[tracker] Switch to decomposed database



commit f67b2e34cbcbd86005855810cd05ecd2bd90c2bd
Author: Jürg Billeter <j bitron ch>
Date:   Wed Apr 15 17:25:18 2009 +0200

    Switch to decomposed database
---
 configure.ac                                       |    5 +-
 data/Makefile.am                                   |    2 +-
 data/db/Makefile.am                                |    8 +-
 data/db/sqlite-email.sql                           |   28 -
 data/db/sqlite-metadata.sql                        |   64 -
 data/db/sqlite-service-triggers.sql                |    9 -
 data/db/sqlite-service-types.sql                   |  127 --
 data/db/sqlite-service.sql                         |  106 --
 data/db/sqlite-stored-procs.sql                    |  117 --
 data/db/sqlite-tracker-triggers.sql                |    4 -
 data/db/sqlite-tracker.sql                         |   71 -
 data/dbus/Makefile.am                              |    1 +
 data/dbus/tracker-daemon.xml                       |   49 +-
 data/dbus/tracker-extract.xml                      |    4 +-
 data/dbus/tracker-indexer.xml                      |   21 +
 data/dbus/tracker-resources.xml                    |   29 +
 data/dbus/tracker-search.xml                       |    3 +-
 data/ontologies/10-xsd.ontology                    |   14 +
 data/ontologies/11-rdf.ontology                    |   82 +
 data/ontologies/12-nrl.ontology                    |   14 +
 data/ontologies/Makefile.am                        |   11 +
 data/services/Makefile.am                          |   11 -
 data/services/default.metadata                     |  116 --
 data/services/default.service                      |   46 -
 data/services/email.metadata                       |   64 -
 data/services/file.metadata                        |   99 -
 .../libtracker-common-sections.txt                 |   48 +-
 .../libtracker-module-sections.txt                 |    1 -
 .../tmpl/tracker-module-metadata.sgml              |   30 +-
 src/libtracker-common/Makefile.am                  |    4 +
 src/libtracker-common/tracker-class.c              |  701 +-------
 src/libtracker-common/tracker-class.h              |   64 +-
 src/libtracker-common/tracker-common.h             |    5 +-
 src/libtracker-common/tracker-file-utils.c         |  167 +--
 src/libtracker-common/tracker-file-utils.h         |    6 +-
 src/libtracker-common/tracker-hal.c                |  100 +-
 src/libtracker-common/tracker-hal.h                |    8 +-
 src/libtracker-common/tracker-namespace.c          |  224 +++
 src/libtracker-common/tracker-namespace.h          |   66 +
 src/libtracker-common/tracker-ontology.c           |  796 ++--------
 src/libtracker-common/tracker-ontology.h           |   78 +-
 src/libtracker-common/tracker-property.c           |  453 +++---
 src/libtracker-common/tracker-property.h           |   69 +-
 src/libtracker-common/tracker-statement-list.c     |  129 ++
 src/libtracker-common/tracker-statement-list.h     |   54 +
 src/libtracker-common/tracker-thumbnailer.c        |    2 -
 src/libtracker-common/tracker-utils.c              |  221 +++-
 src/libtracker-common/tracker-utils.h              |    5 +
 src/libtracker-data/Makefile.am                    |    6 +-
 src/libtracker-data/tracker-data-backup.c          |   10 +-
 src/libtracker-data/tracker-data-manager.c         |  791 ++++++++-
 src/libtracker-data/tracker-data-manager.h         |   19 +-
 src/libtracker-data/tracker-data-metadata.c        |  280 ---
 src/libtracker-data/tracker-data-metadata.h        |   59 -
 src/libtracker-data/tracker-data-query.c           |  700 +++-----
 src/libtracker-data/tracker-data-query.h           |   50 +-
 src/libtracker-data/tracker-data-search.c          |   51 +-
 src/libtracker-data/tracker-data-search.h          |   11 +-
 src/libtracker-data/tracker-data-update.c          | 1873 ++++++++++++++------
 src/libtracker-data/tracker-data-update.h          |   58 +-
 src/libtracker-data/tracker-query-tree.c           |  220 +--
 src/libtracker-data/tracker-query-tree.h           |    8 +-
 src/libtracker-data/tracker-turtle.c               |   36 +-
 src/libtracker-data/tracker-turtle.h               |    9 +-
 src/libtracker-db/tracker-db-dbus.c                |   12 +-
 src/libtracker-db/tracker-db-index-item.c          |   41 +-
 src/libtracker-db/tracker-db-index-item.h          |   11 +-
 src/libtracker-db/tracker-db-index-manager.c       |   97 +-
 src/libtracker-db/tracker-db-index-manager.h       |    4 +-
 src/libtracker-db/tracker-db-index.c               |   18 +-
 src/libtracker-db/tracker-db-index.h               |    2 -
 src/libtracker-db/tracker-db-interface.c           |   23 +-
 src/libtracker-db/tracker-db-manager.c             | 1102 ++----------
 src/libtracker-db/tracker-db-manager.h             |   23 +-
 src/libtracker-gtk/tracker-metadata-tile.c         |    6 +-
 src/libtracker-gtk/tracker-metadata-tile.h         |    2 +
 src/libtracker-gtk/tracker-tag-bar.c               |   17 +-
 src/libtracker-gtk/tracker-tag-bar.h               |    2 +
 src/libtracker/Makefile.am                         |    1 +
 src/libtracker/tracker.c                           |  158 +--
 src/libtracker/tracker.h                           |   61 +-
 src/plugins/evolution/tracker-evolution-indexer.c  |  148 +-
 src/plugins/kmail/tracker-kmail-indexer.c          |  117 +-
 src/plugins/rss/tracker-rss-indexer.c              |   76 +-
 src/tracker-extract/Makefile.am                    |   85 +-
 src/tracker-extract/tracker-escape.c               |   64 -
 src/tracker-extract/tracker-escape.h               |   46 -
 src/tracker-extract/tracker-extract-abw.c          |   64 +-
 .../tracker-extract-gstreamer-helix.c              |  221 ++--
 src/tracker-extract/tracker-extract-gstreamer.c    |  344 +++--
 src/tracker-extract/tracker-extract-html.c         |   86 +-
 src/tracker-extract/tracker-extract-imagemagick.c  |   62 +-
 src/tracker-extract/tracker-extract-jpeg.c         |  127 +-
 src/tracker-extract/tracker-extract-libxine.c      |  107 +-
 src/tracker-extract/tracker-extract-mp3.c          |  437 +++--
 src/tracker-extract/tracker-extract-mplayer.c      |  124 +-
 src/tracker-extract/tracker-extract-msoffice.c     |  129 ++-
 src/tracker-extract/tracker-extract-oasis.c        |  116 +-
 src/tracker-extract/tracker-extract-pdf.c          |   79 +-
 src/tracker-extract/tracker-extract-playlist.c     |  102 +-
 src/tracker-extract/tracker-extract-png.c          |  109 +-
 src/tracker-extract/tracker-extract-ps.c           |   74 +-
 src/tracker-extract/tracker-extract-tiff.c         |  104 +-
 src/tracker-extract/tracker-extract-totem.c        |   79 +-
 src/tracker-extract/tracker-extract-vorbis.c       |  117 +-
 src/tracker-extract/tracker-extract-xmp.c          |   20 +-
 src/tracker-extract/tracker-extract.c              |  135 +-
 src/tracker-extract/tracker-extract.h              |    2 +-
 src/tracker-extract/tracker-iptc.c                 |  115 +-
 src/tracker-extract/tracker-iptc.h                 |    3 +-
 src/tracker-extract/tracker-main.c                 |    8 +-
 src/tracker-extract/tracker-main.h                 |    5 +-
 src/tracker-extract/tracker-xmp.c                  |  269 ++--
 src/tracker-extract/tracker-xmp.h                  |    2 +-
 src/tracker-fts/tracker-fts.c                      |   22 +-
 src/tracker-indexer/modules/applications.c         |  233 ++-
 src/tracker-indexer/modules/evolution-common.c     |   46 +-
 src/tracker-indexer/modules/evolution-common.h     |   19 +-
 src/tracker-indexer/modules/evolution-imap.c       |   77 +-
 src/tracker-indexer/modules/evolution-pop.c        |   69 +-
 src/tracker-indexer/modules/files.c                |   25 -
 src/tracker-indexer/modules/gaim-conversations.c   |   13 +-
 src/tracker-indexer/tracker-indexer.c              | 1475 +++++-----------
 src/tracker-indexer/tracker-indexer.h              |   17 +-
 src/tracker-indexer/tracker-main.c                 |   20 +-
 src/tracker-indexer/tracker-module-file.c          |   50 +-
 src/tracker-indexer/tracker-module-file.h          |    1 -
 .../tracker-module-metadata-private.h              |   20 +-
 .../tracker-module-metadata-utils.c                |  651 ++++----
 src/tracker-indexer/tracker-module-metadata.c      |  224 +--
 src/tracker-indexer/tracker-module-metadata.h      |   24 +-
 src/tracker-indexer/tracker-removable-device.c     |  478 ++---
 src/tracker-indexer/tracker-removable-device.h     |   13 +-
 .../tracker-search-tool-callbacks.c                |    5 +-
 src/tracker-search-tool/tracker-search-tool.c      |   32 +-
 src/tracker-search-tool/tracker-search-tool.h      |    2 +
 src/tracker-utils/.gitignore                       |    3 +
 src/tracker-utils/Makefile.am                      |   12 +-
 src/tracker-utils/tracker-info.c                   |    5 +-
 src/tracker-utils/tracker-search.c                 |    5 +-
 src/tracker-utils/tracker-tag.c                    |   11 +-
 src/trackerd/Makefile.am                           |    3 +
 src/trackerd/tracker-backup.c                      |    3 +
 src/trackerd/tracker-daemon.c                      |  127 +--
 src/trackerd/tracker-dbus.c                        |   25 +-
 src/trackerd/tracker-dbus.h                        |    3 +-
 src/trackerd/tracker-main.c                        |   54 +-
 src/trackerd/tracker-marshal.list                  |    8 +-
 src/trackerd/tracker-processor.c                   |   10 +-
 src/trackerd/tracker-resources.c                   |  183 ++
 src/trackerd/tracker-resources.h                   |   74 +
 src/trackerd/tracker-search.c                      |   68 +-
 src/trackerd/tracker-search.h                      |    4 +-
 src/trackerd/tracker-volume-cleanup.c              |   67 +-
 tests/Makefile.am                                  |    1 -
 tests/libtracker-common/Makefile.am                |   12 -
 tests/libtracker-common/tracker-dbus-test.c        |    6 +-
 tests/libtracker-common/tracker-field-test.c       |    4 +-
 tests/libtracker-common/tracker-file-utils-test.c  |   54 +-
 tests/libtracker-common/tracker-ontology-test.c    |  458 -----
 .../libtracker-db/tracker-db-manager-test-attach.c |    1 -
 .../libtracker-db/tracker-db-manager-test-custom.c |    1 -
 .../tracker-db-manager-test-unattach.c             |    3 +-
 tests/libtracker-db/tracker-index-writer-test.c    |   12 +-
 tests/scripts/.gitignore                           |    2 -
 tests/scripts/Makefile.am                          |    3 -
 tests/scripts/data/common.sql                      |  609 -------
 tests/scripts/data/email-contents.sql              |    1 -
 tests/scripts/data/email-meta.sql                  |   67 -
 tests/scripts/data/file-meta.sql                   |   42 -
 tests/scripts/dummy_data_start.sh.in               |   63 -
 tests/scripts/dummy_data_stop.sh.in                |   11 -
 tests/scripts/testing.txt                          |   19 -
 tests/scripts/xdg_dirs.source                      |    2 -
 tests/scripts/xdg_dirs.unsource                    |    2 -
 tests/tracker-extract/Makefile.am                  |   32 +-
 tests/tracker-extract/tracker-extract-jpeg-test.c  |    3 +-
 tests/tracker-extract/tracker-extract-mp3-test.c   |    4 -
 tests/tracker-extract/tracker-extract-png-test.c   |    8 +-
 tests/tracker-extract/tracker-extract-test-utils.c |  134 +-
 utils/qdbm/print-words.c                           |    3 +-
 utils/qdbm/search-word.c                           |    5 +-
 182 files changed, 8156 insertions(+), 11260 deletions(-)

diff --git a/configure.ac b/configure.ac
index 5667d30..4e4cdb7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1350,7 +1350,7 @@ AC_CONFIG_FILES([
 	data/libtracker-gtk.pc
 	data/Makefile
 	data/modules/Makefile
-	data/services/Makefile
+	data/ontologies/Makefile
 	data/tracker.pc
 	data/tracker-module-1.0.pc
 	docs/Makefile
@@ -1397,9 +1397,6 @@ AC_CONFIG_FILES([
 	tests/libtracker-common/Makefile
 	tests/libtracker-db/Makefile
 	tests/Makefile
-	tests/scripts/dummy_data_start.sh
-	tests/scripts/dummy_data_stop.sh
-	tests/scripts/Makefile
 	tests/tracker-indexer/Makefile
 	tests/tracker-extract/Makefile
 	utils/Makefile
diff --git a/data/Makefile.am b/data/Makefile.am
index 8c5ae43..f4ba015 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,6 +1,6 @@
 include $(top_srcdir)/Makefile.decl
 
-SUBDIRS = db dbus modules languages icons services
+SUBDIRS = db dbus modules languages icons ontologies
 
 trackerd.desktop.in: trackerd.desktop.in.in
 	@sed -e "s|@libexecdir[ ]|${libexecdir}|" \
diff --git a/data/db/Makefile.am b/data/db/Makefile.am
index 6cf05db..0b2a9f0 100644
--- a/data/db/Makefile.am
+++ b/data/db/Makefile.am
@@ -4,14 +4,8 @@ configdir = $(datadir)/tracker
 
 config_DATA =				\
 	sqlite-contents.sql		\
-	sqlite-email.sql		\
-	sqlite-metadata.sql 		\
 	sqlite-fulltext.sql 		\
-	sqlite-service.sql		\
-	sqlite-service-triggers.sql 	\
-	sqlite-service-types.sql 	\
 	sqlite-stored-procs.sql 	\
-	sqlite-tracker.sql 		\
-	sqlite-tracker-triggers.sql
+	sqlite-tracker.sql
 
 EXTRA_DIST = $(config_DATA)
diff --git a/data/db/sqlite-email.sql b/data/db/sqlite-email.sql
deleted file mode 100644
index fa4e1fe..0000000
--- a/data/db/sqlite-email.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-
-CREATE TABLE MailSummary
-(
-	ID		Integer primary key AUTOINCREMENT not null,
-	MailApp		Integer not null,
-	MailType	Integer not null,
-	FileName	Text not null,
-	Path		Text not null,
-	UriPrefix	Text,
-	NeedsChecking	Integer default 0,
-	MailCount	Integer,
-	JunkCount	Integer,
-	DeleteCount	Integer,
-	Offset		Integer,
-	LastOffset	Integer,
-	MTime		integer,
-
-	unique (Path)
-);
-
-
-CREATE TABLE JunkMail
-(
-	UID			integer not null,
-	SummaryID		Integer not null,
-
-	primary key (UID, SummaryID)
-);
diff --git a/data/db/sqlite-metadata.sql b/data/db/sqlite-metadata.sql
deleted file mode 100644
index c5faa91..0000000
--- a/data/db/sqlite-metadata.sql
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/* describes the types of metadata */
-CREATE TABLE  MetaDataTypes 
-(
-	ID	 		Integer primary key AUTOINCREMENT not null,
-	MetaName		Text not null  COLLATE NOCASE, 
-	DataTypeID		Integer default 1,    /* 0=Keyword, 1=indexable, 2=Clob (compressed indexable text),  3=String, 4=Integer, 5=Double,  6=DateTime, 7=Blob, 8=Struct, 9=ServiceLink */
-	DisplayName		text,
-	Description		text default ' ',
-	Enabled			integer default 1, /* used to prevent use of this metadata type */
-	UIVisible		integer default 0, /* should this metadata type be visible in a search criteria UI  */
-	WriteExec		text default ' ', /* used to specify an external program that can write an *embedded* metadata to a file */
-	Alias			text default ' ', /* alternate name for this type (XESAM specs?) */
-	FieldName		text default ' ', /* filedname if present in the services table */
-	Weight			Integer default 1, /* weight of metdata type in ranking */
-	Embedded		Integer default 1, /* 1 if metadata extracted from the file by the indexer and is not updateable by the user. 0 - this metadata can be updated by the user and is external to the file */
-	MultipleValues		Integer default 0, /* 0= type cannot have multiple values per entity, 1= type can have more than 1 value per entity */
-	Delimited		Integer default 0, /* if 1, extra delimiters (hyphen and underscore) are used to break word */
-	Filtered		Integer default 1, /* if 1, words are filtered for numerics (if numeric indexing is disabled), stopwords and min length */
-	Abstract		Integer default 0, /* if 0, can be used for storing metadata - Abstract type classes cannot store metadata and can only be used for searching its decendants */
-	StemMetadata		Integer default 1, /* 1 if metadata should be stemmed */
-	SideCar			Integer default 0, /* should this metadata be backed up in an xmp sidecar file */
-	FileName		Text default ' ',
-
-	Unique (MetaName)
-);
-
-insert into MetaDataTypes (MetaName) values ('default');
-
-CREATE INDEX  MetaDataTypesIndex1 ON MetaDataTypes (Alias);
-
-
-/* flattened table to store metadata inter-relationships */
-CREATE TABLE  MetaDataChildren
-(
-	MetaDataID		integer not null,
-	ChildID			integer not null,
-
-	primary key (MetaDataID, ChildID)
-
-);
-
-
-/* for specifying fixed non-extensible metadata group/structs */
-CREATE TABLE  MetaDataGroup
-(
-	MetaDataGroupID		integer not null,
-	ChildID			integer not null,
-
-	primary key (MetaDataGroupID, ChildID)
-
-);
-
-
-/* future-proof table for future addional options specific to a certain metadata type  */
-CREATE TABLE MetadataOptions
-(
-	MetaDataID		Integer not null,
-	OptionName		Text not null,
-	OptionValue		Text default ' ',
-
-	primary key (MetaDataID, OptionName)
-);
-
diff --git a/data/db/sqlite-service-triggers.sql b/data/db/sqlite-service-triggers.sql
deleted file mode 100644
index 51277de..0000000
--- a/data/db/sqlite-service-triggers.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-CREATE TRIGGER delete_service BEFORE DELETE ON Services 
-BEGIN  
-	DELETE FROM ServiceMetaData WHERE ServiceID = old.ID;
-	DELETE FROM ServiceKeywordMetaData WHERE ServiceID = old.ID;
-	DELETE FROM ServiceNumericMetaData WHERE ServiceID = old.ID;
-	DELETE FROM ChildServices WHERE (ParentID = old.ID);
-	DELETE FROM ChildServices WHERE (ChildID = old.ID);
-	
-END;!
diff --git a/data/db/sqlite-service-types.sql b/data/db/sqlite-service-types.sql
deleted file mode 100644
index 89d4f7b..0000000
--- a/data/db/sqlite-service-types.sql
+++ /dev/null
@@ -1,127 +0,0 @@
-
-CREATE TABLE  ServiceTypes
-(
-	TypeID 			Integer primary key AUTOINCREMENT not null,
-	TypeName		Text COLLATE NOCASE not null,
-
-	TypeCount		Integer default 0,
-
-	DisplayName		Text default ' ',
-	ParentID		Integer default 0,
-	Parent			Text default ' ',
-	PropertyPrefix		Text default ' ',
-	Enabled			Integer default 1, 
-	Embedded		Integer default 1, /* service is created by the indexer if embedded. User or app defined services are not embedded */
-	ChildResource		Integer default 0, /* service is a child service */
-	
-	CreateDesktopFile	Integer default 0, /* used by a UI to indicate whether it should create a desktop file for the service if its copied (using the ViewerExec field + uri) */
-
-	/* useful for a UI when determining what actions a hit can have */
-	CanCopy			Integer default 1, 
-	CanDelete		Integer default 1,
-
-	ShowServiceFiles	Integer default 0,
-	ShowServiceDirectories  Integer default 0,
-
-	HasMetadata		Integer default 1,
-	HasFullText		Integer default 1,
-	HasThumbs		Integer default 1,
-	
-	ContentMetadata		Text default ' ', /* the content field is the one most likely to be used for showing a search snippet */ 
-
-	KeyMetadata1		Text default ' ', /* the most commonly requested metadata (especially for tables/grid views) is cached int he services table for extra fast retrieval */
-	KeyMetadata2		Text default ' ',
-	KeyMetadata3		Text default ' ',
-	KeyMetadata4		Text default ' ',
-	KeyMetadata5		Text default ' ',
-	KeyMetadata6		Text default ' ',
-	KeyMetadata7		Text default ' ',
-	KeyMetadata8		Text default ' ',
-	KeyMetadata9		Text default ' ',
-	KeyMetadata10		Text default ' ',
-	KeyMetadata11		Text default ' ',
-
-	UIVisible		Integer default 0,	/* should service appear in a search GUI? */
-	UITitle			Text default ' ',	/* title format as displayed in the metadata tile */
-	UIMetadata1		Text default ' ',	/*UI fields to show in GUI for a hit - if not set then Name,Path,Mime are used */
-	UIMetadata2		Text default ' ',
-	UIMetadata3		Text default ' ',
-	UIView			Text default 'default',
-
-	Description		Text default ' ',
-	Database		integer default 0, /* 0 = DB_FILES, 1 = DB_EMAILS, 2 = DB_MISC, 3 = DB_USER */
-	Icon			Text default ' ',
-
-	IndexerExec		Text default ' ',
-	IndexerOutput		Text default 'stdout',
-	ThumbExec		Text default ' ',
-	ViewerExec		Text default ' ',
-
-	WatchFolders		Text default ' ',
-	IncludeGlob		Text default ' ',
-	ExcludeGlob		Text default ' ',
-
-	FileName		Text default ' ',
-
-	unique (TypeName)
-);
-
-CREATE INDEX ServiceTypesStats ON ServiceTypes (TypeName, TypeID);
-CREATE INDEX ServiceTypesParentStats ON ServiceTypes (Parent, TypeID, ParentID);
-
-insert into ServiceTypes (TypeName) values ('default');
-
-/* metadata that should appear in a tabular view and/or metadata tile for the service */
-CREATE TABLE ServiceTileMetadata
-(
-	ServiceTypeID		Integer not null,
-	MetaName		Text not null,
-
-	primary key (ServiceTypeID, MetaName)
-);
-
-
-CREATE TABLE ServiceTabularMetadata
-(
-	ServiceTypeID		Integer not null,
-	MetaName		Text not null,
-
-	primary key (ServiceTypeID, MetaName)
-);
-
-
-/* option sspecific to a certain service type go here */
-CREATE TABLE ServiceTypeOptions
-(
-	ServiceTypeID		Integer not null,
-	OptionName		Text not null,
-	OptionValue		Text default ' ',
-
-	primary key (ServiceTypeID, OptionName)
-);
-
-
-
-
-/* these two only apply to file based services */
-CREATE TABLE  FileMimes
-(
-	Mime			Text primary key not null,
-	ServiceTypeID		Integer default 0,
-	ThumbExec		Text default ' ',
-	MetadataExec		Text default ' ',
-	FullTextExec		Text default ' '
-
-);
-
-CREATE TABLE  FileMimePrefixes
-(
-	MimePrefix		Text primary key not null,
-	ServiceTypeID		Integer default 0,
-	ThumbExec		Text default ' ',
-	MetadataExec		Text default ' ',
-	FullTextExec		Text default ' '
-
-);
-
-
diff --git a/data/db/sqlite-service.sql b/data/db/sqlite-service.sql
deleted file mode 100644
index 7bc9ffa..0000000
--- a/data/db/sqlite-service.sql
+++ /dev/null
@@ -1,106 +0,0 @@
-/* basic info for a file or service object */
-CREATE TABLE  Services
-(
-	ID            		Integer primary key not null,
-	ServiceTypeID		Integer  default 0, /* see ServiceTypes table above for ID values. A value of 0 indicates a group resource rather than a service */
-	Path 			Text not null,      /* non-file objects should use service name here */
-	Name	 		Text default ' ',   /* name of file or object - the combination path and name must be unique for all objects */
-	Enabled			Integer default 1,
-	Mime			Text default ' ',
-	Size			Integer default 0,
-	Rank			Integer default 5,
-	ParentID		Integer,
-
-	KeyMetadata1		Text,
-	KeyMetadata2		Text,
-	KeyMetadata3		Text,
-	KeyMetadata4		Text,
-	KeyMetadata5		Text,
-	KeyMetadata6		Integer,
-	KeyMetadata7		Integer,
-	KeyMetadata8		Integer,
-	KeyMetadata9		Text,
-	KeyMetadata10		Text,
-	KeyMetadata11		Text,
-
-	KeyMetadataCollation1   Text,
-	KeyMetadataCollation2   Text,
-	KeyMetadataCollation3   Text,
-	KeyMetadataCollation4   Text,
-	KeyMetadataCollation5   Text,
-
-	Icon			Text,
-	CanWrite		Integer default 1,
-	CanExecute		Integer default 1,
-
-	LanguageId		Integer default 0,
-	IsDirectory   		Integer default 0,
-    	IsLink        		Integer default 0,
-	AuxilaryID		Integer default 0, /* link to Volumes table for files, link to MailSummary table for emails*/
-	IndexTime  		Integer default 0, /* should equal st_mtime for file if up-to-date */
-	Accessed  		Integer default 0, /* last accessed */
-	Offset			Integer default 0, /* last used disk offset for indexable files that always grow (like chat logs) or email offset */
-	MD5			Text,
-
-    	unique (Path, Name)
-);
-
-CREATE INDEX ServiceTypeIDIndex ON Services (ServiceTypeID);
-
-/* It would seem that sqlite is unable to use split indices for GROUP or ORDER, thus we end up
-   with this scheme where AuxilaryID is dropped from the index and ServiceType requires additional logic */
-CREATE INDEX ServicesCompoundIndex1 ON Services (ServiceTypeID, KeyMetadataCollation1, KeyMetadataCollation2);
-CREATE INDEX ServicesCompoundIndex2 ON Services (ServiceTypeID, KeyMetadataCollation2);
-CREATE INDEX ServicesCompoundIndex3 ON Services (ServiceTypeID, KeyMetadataCollation3);
-CREATE INDEX ServicesCompoundIndex4 ON Services (ServiceTypeID, KeyMetadataCollation4);
-CREATE INDEX ServicesCompoundIndex5 ON Services (ServiceTypeID, KeyMetadataCollation5);
-CREATE INDEX ServicesCompoundIndex6 ON Services (ServiceTypeID, KeyMetadata6);
-CREATE INDEX ServicesCompoundIndex7 ON Services (ServiceTypeID, KeyMetadata7);
-CREATE INDEX ServicesCompoundIndex8 ON Services (ServiceTypeID, KeyMetadata8);
-CREATE INDEX ServicesCompoundIndexAux ON Services (ServiceTypeID, AuxilaryID);
-
-/* child service relationships for a specific group/struct metadata */
-CREATE TABLE ChildServices
-(
-	ParentID            		Integer not null,
-	ChildID				Integer not null,
-	MetaDataID			Integer not null,
-
-	primary key (ParentID, ChildID, MetaDataID)
-);
-
-/* utf-8 based literal metadata. */
-CREATE TABLE  ServiceMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer not null,
-	MetaDataValue     	Text,
-	MetaDataDisplay		Text,
-	MetaDataCollation	Text
-);
-
-CREATE INDEX ServiceMetaDataCompoundIndex ON ServiceMetaData (ServiceID, MetaDataID, MetaDataDisplay, MetaDataCollation);
-
-/* metadata for all keyword types - keywords are db indexed for fast searching - they are also not processed like other metadata. */
-CREATE TABLE  ServiceKeywordMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer not null,
-	MetaDataValue		Text COLLATE NOCASE
-);
-
-CREATE INDEX ServiceKeywordMetaDataCompoundIndex ON ServiceKeywordMetaData (ServiceID, MetaDataID, MetaDataValue);
-
-/* metadata for all integer/date types */
-CREATE TABLE  ServiceNumericMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer not null,
-	MetaDataValue		Integer not null
-);
-
-CREATE INDEX ServiceNumericMetaDataCompoundIndex ON ServiceNumericMetaData (ServiceID, MetaDataID, MetaDataValue);
-
diff --git a/data/db/sqlite-stored-procs.sql b/data/db/sqlite-stored-procs.sql
index bdd3a46..ce6e61a 100644
--- a/data/db/sqlite-stored-procs.sql
+++ b/data/db/sqlite-stored-procs.sql
@@ -2,120 +2,3 @@
  * This file is dedicated to stored procedures 
  */
 
-
-/*
- * Metadata queries
- */
-GetApplicationByID             SELECT (S.Path || '/' || S.Name) AS uri, 'Applications', 'Application', S.KeyMetadata1, S.KeyMetadata2, S.KeyMetadata3 FROM Services AS S WHERE S.ID = ?;
-GetAllServices                 SELECT TypeID, TypeName, Parent, PropertyPrefix, Enabled, Embedded, HasMetadata, HasFullText, HasThumbs, ContentMetadata, Database, ShowServiceFiles, ShowServiceDirectories, KeyMetadata1, KeyMetadata2, KeyMetadata3, KeyMetadata4, KeyMetadata5, KeyMetadata6, KeyMetadata7, KeyMetadata8, KeyMetadata9, KeyMetadata10, KeyMetadata11 FROM ServiceTypes;
-GetEmailByID                   SELECT (S.Path || '/' || S.Name) AS uri, 'Emails', S.Mime, S.KeyMetadata1, S.KeyMetadata2, S.KeyMetadata3 FROM Services AS S WHERE S.ID = ?;
-GetFileByID                    SELECT S.Path, S.Name, S.Mime, S.ServiceTypeID FROM Services AS S WHERE S.ID = ? AND S.Enabled = 1 AND (S.AuxilaryID = 0 OR S.AuxilaryID IN (SELECT VolumeID FROM Volumes WHERE Enabled = 1));
-GetFileByID2                   SELECT (S.Path || '/' || S.Name) AS uri, GetServiceName (ServiceTypeID), S.Mime FROM Services AS S WHERE S.ID = ? AND S.Enabled = 1 AND (S.AuxilaryID = 0 OR S.AuxilaryID IN (SELECT VolumeID FROM Volumes WHERE Enabled = 1));
-GetFileMTime                   SELECT M.MetaDataValue FROM Services AS S INNER JOIN ServiceNumericMetaData M ON S.ID = M.ServiceID WHERE S.Path = ? AND S.Name = ? AND M.MetaDataID = (SELECT ID FROM MetaDataTypes WHERE MetaName ='File:Modified');
-GetServices                    SELECT TypeName, Description, Parent FROM ServiceTypes ORDER BY TypeID;
-GetFileChildren                SELECT ID, Path, Name, IsDirectory FROM Services WHERE Path = ?;
-
-
-
-/*
- * Option queries
- */
-GetOption                      SELECT OptionValue FROM Options WHERE OptionKey = ?;
-SetOption                      REPLACE INTO Options (OptionKey, OptionValue) VALUES (?,?);
-
-GetCollationLocale             SELECT OptionValue FROM Options WHERE OptionKey = 'CollationLocale';
-SetCollationLocale             UPDATE Options SET OptionValue = ? WHERE OptionKey = 'CollationLocale';
-
-/*
- * File queries
- */
-CreateService                  INSERT INTO Services (ID, Path, Name, ServiceTypeID, Mime, Size, IsDirectory, IsLink, Offset, IndexTime, AuxilaryID) VALUES (?,?,?,?,?,?,?,?,?,?,?); 
-
-MoveService                    UPDATE Services SET Path = ?, Name = ? WHERE Path = ? AND Name = ?;
-MoveServiceChildren            UPDATE Services SET Path = replace (Path, ?, ?) WHERE Path = ? OR Path LIKE (? || '/%');
-
-DeleteContent                  DELETE FROM ServiceContents WHERE ServiceID = ? AND MetadataId = ?;
-DeleteService1                 DELETE FROM Services WHERE ID = ?;
-DeleteServiceRecursively       DELETE FROM Services WHERE Path = ? OR Path LIKE (? || '/%');
-DeleteServiceMetadata          DELETE FROM ServiceMetaData WHERE ServiceID = ?;
-DeleteServiceKeywordMetadata   DELETE FROM ServiceMetaData WHERE ServiceID = ?;
-DeleteServiceNumericMetadata   DELETE FROM ServiceMetaData WHERE ServiceID = ?;
-
-GetServiceID                   SELECT ID, IndexTime, IsDirectory, ServiceTypeID FROM Services WHERE Path = ? AND Name = ?;
-GetByServiceType               SELECT DISTINCT S.Path || '/' || S.Name AS uri FROM Services AS S WHERE S.Enabled = 1 AND (S.AuxilaryID = 0 OR S.AuxilaryID IN (SELECT VolumeID FROM Volumes WHERE Enabled = 1)) AND S.ServiceTypeID IN (SELECT TypeId FROM ServiceTypes WHERE TypeName = ? OR Parent = ?) LIMIT ?,?;
-GetContents                    SELECT uncompress (Content) FROM ServiceContents WHERE ServiceID = ? AND MetadataID = ? AND Content is not null;
-GetFileContents                SELECT substr(uncompress (Content), ?, ?) FROM ServiceContents WHERE ServiceID = ?;
-GetAllContents                 SELECT uncompress (Content) FROM ServiceContents WHERE ServiceID = ? AND Content is not null;
-GetKeywordList                 SELECT DISTINCT K.MetaDataValue, count(*) AS totalcount FROM Services AS S, ServiceKeywordMetaData K WHERE K.ServiceID = S.ID AND (S.ServiceTypeID IN (SELECT TypeId FROM ServiceTypes WHERE TypeName = ? OR Parent = ?)) AND K.MetaDataId = 19 GROUP BY K.MetaDataValue ORDER BY totalcount desc, K.MetaDataValue ASC;
-
-SaveServiceContents            REPLACE INTO ServiceContents (ServiceID, MetadataID, Content) VALUES (?,?,compress (?));
-
-/*
- * Metadata/MIME queries
- */
-GetUserMetadataBackup          SELECT S.Path || '/' || S.Name, T.TypeName, M.MetadataID, M.MetadataDisplay FROM Services S, ServiceMetadata M, ServiceTypes T WHERE (S.ID == M.ServiceID) AND (S.ServiceTypeID == T.TypeID) AND (M.MetadataID IN (SELECT ID From MetadataTypes WHERE Embedded = 0)) UNION SELECT S.Path || '/' || S.Name, T.TypeName, M.MetadataID, upper(M.MetadataValue) FROM Services S, ServiceNumericMetadata M, ServiceTypes T WHERE (S.ID == M.ServiceID) AND (S.ServiceTypeID == T.TypeID) AND (M.MetadataID IN (SELECT ID From MetadataTypes WHERE Embedded = 0)) UNION SELECT S.Path || '/' || S.Name, T.Typename, M.MetadataID, M.MetadataValue FROM Services S, ServiceKeywordMetadata M, ServiceTypes T WHERE (S.ID == M.ServiceID) AND (S.ServiceTypeID == T.TypeID) AND (M.MetadataID IN (SELECT ID From MetadataTypes WHERE Embedded = 0));
-GetAllMetadata                 SELECT MetadataID, MetadataDisplay FROM ServiceMetadata WHERE ServiceID = ? UNION SELECT MetadataID, MetadataValue FROM ServiceKeywordMetadata WHERE ServiceID = ? UNION SELECT MetadataID, upper(MetadataValue) FROM ServiceNumericMetadata WHERE ServiceID = ?;
-GetMetadata                    SELECT MetaDataDisplay FROM ServiceMetaData WHERE ServiceID = ? AND MetaDataID = ?;
-GetMetadataAliases             SELECT DISTINCT M.MetaName, M.ID FROM MetaDataTypes AS M, MetaDataChildren AS C WHERE M.ID = C.ChildID AND C.MetaDataID = ?; 
-GetMetadataAliasesForName      SELECT DISTINCT M.MetaName, M.ID FROM MetaDataTypes AS M, MetaDataChildren AS C WHERE M.ID = C.ChildID AND C.MetaDataID = (SELECT ID FROM MetaDataTypes WHERE MetaName = ?) UNION SELECT M.MetaName, M.ID FROM MetaDataTypes AS M WHERE M.MetaName = ?; 
-GetMetadataKeyword             SELECT MetaDataValue FROM ServiceKeywordMetaData WHERE ServiceID = ? AND MetaDataID = ?;
-GetMetadataNumeric             SELECT MetaDataValue FROM ServiceNumericMetaData WHERE ServiceID = ? AND MetaDataID = ?;
-GetMetadataTypes               SELECT ID, MetaName, DataTypeID, FieldName, Weight, Embedded, MultipleValues, Delimited, Filtered, Abstract FROM MetaDataTypes;
-
-SetMetadata                    INSERT INTO ServiceMetaData (ServiceID, MetaDataID, MetaDataValue, MetaDataDisplay, MetaDataCollation) VALUES (?,?,?,?,CollateKey(?));
-SetMetadataKeyword             INSERT INTO ServiceKeywordMetaData (ServiceID, MetaDataID, MetaDataValue) VALUES (?,?,?);
-SetMetadataNumeric             INSERT INTO ServiceNumericMetaData (ServiceID, MetaDataID, MetaDataValue) VALUES (?,?,?);
-
-DeleteMetadata                 DELETE FROM ServiceMetaData WHERE ServiceID = ? AND MetaDataID = ?;
-DeleteMetadataKeyword          DELETE FROM ServiceKeywordMetaData WHERE ServiceID = ? AND MetaDataID = ?;
-DeleteMetadataKeywordValue     DELETE FROM ServiceKeywordMetaData WHERE ServiceID = ? AND MetaDataID = ? AND MetaDataValue = ?;
-DeleteMetadataValue            DELETE FROM ServiceMetaData WHERE ServiceID = ? AND MetaDataID = ? AND MetaDataDisplay = ?;
-DeleteMetadataNumeric          DELETE FROM ServiceNumericMetaData WHERE ServiceID = ? AND MetaDataID = ?;
-
-UpdateMetadataCollation        UPDATE ServiceMetadata SET MetadataCollation=CollateKey(MetadataDisplay);
-
-InsertMetaDataChildren         INSERT INTO MetaDataChildren (ChildID,MetadataID) VALUES (?,(SELECT ID FROM MetaDataTypes WHERE MetaName = ?));
-InsertMetadataType             INSERT INTO MetaDataTypes (MetaName) VALUES (?);
-InsertMimePrefixes             REPLACE INTO FileMimePrefixes (MimePrefix) VALUES (?);
-InsertMimes                    REPLACE INTO FileMimes (Mime) VALUES (?);
-InsertServiceTabularMetadata   REPLACE INTO ServiceTabularMetadata (ServiceTypeID, MetaName) VALUES (?, ?);
-InsertServiceTileMetadata      REPLACE INTO ServiceTileMetadata (ServiceTypeID, MetaName) VALUES (?, ?);
-InsertServiceType              REPLACE INTO ServiceTypes (TypeName) VALUES (?);
-
-GetMimeForServiceId            SELECT Mime FROM FileMimes WHERE ServiceTypeId = ?;
-GetMimePrefixForServiceId      SELECT MimePrefix FROM FileMimePrefixes WHERE ServiceTypeId = ?;
-
-/*
- * Statistics queries
- */
-GetStats                       SELECT T.TypeName, COUNT(1) FROM Services S, ServiceTypes T WHERE S.AuxilaryID IN (SELECT VolumeID FROM Volumes WHERE Enabled = 1) AND S.Enabled = 1 AND T.TypeID=S.ServiceTypeID GROUP BY ServiceTypeID ORDER BY T.TypeName;
-GetStatsForParents	       SELECT T.Parent, COUNT(1) FROM ServiceTypes AS T JOIN Services AS S ON S.ServiceTypeID=T.TypeID WHERE S.AuxilaryID IN (SELECT VolumeID FROM Volumes WHERE Enabled = 1) AND S.Enabled = 1 AND S.ServiceTypeID IN (SELECT TypeID FROM ServiceTypes WHERE ParentID > 0) GROUP BY T.ParentID ORDER BY T.Parent;
-
-GetHitDetails                  SELECT ROWID, HitCount, HitArraySize FROM HitIndex WHERE word = ?;
-
-/*
- * Volume handling
- */
-
-GetVolumeID                    SELECT VolumeID FROM Volumes WHERE UDI = ?;
-GetVolumeByPath                SELECT VolumeID FROM Volumes WHERE Enabled = 1 AND (? = MountPath OR ? LIKE (MountPath || '/%'));
-GetVolumesToClean              SELECT MountPath, VolumeID FROM Volumes WHERE DisabledDate < date('now', '-3 day');
-InsertVolume                   INSERT INTO Volumes (MountPath, UDI, Enabled, DisabledDate) VALUES (?, ?, 1, date('now'));
-EnableVolume                   UPDATE Volumes SET MountPath = ?, Enabled = 1 WHERE UDI = ?;
-DisableVolume                  UPDATE Volumes SET Enabled = 0, DisabledDate = date ('now') WHERE UDI = ?;
-DisableAllVolumes              UPDATE Volumes SET Enabled = 0 WHERE VolumeID > 1;
-UpdateVolumeDisabledDate       UPDATE Volumes SET DisabledDate = date ('now') WHERE VolumeID = ?;
-
-/*
- * Turtle importing
- */
-DeleteServiceAll               DELETE FROM Services WHERE ServiceTypeID = ?;
-
-/*
- * Deprecated
- */
-GetNewID                       SELECT OptionValue FROM Options WHERE OptionKey = 'Sequence';
-UpdateNewID                    UPDATE Options SET OptionValue = ? WHERE OptionKey = 'Sequence';
-
-GetNewEventID                  SELECT OptionValue FROM Options WHERE OptionKey = 'EventSequence';
-UpdateNewEventID               UPDATE Options SET OptionValue = ? WHERE OptionKey = 'EventSequence';
diff --git a/data/db/sqlite-tracker-triggers.sql b/data/db/sqlite-tracker-triggers.sql
deleted file mode 100644
index e887af0..0000000
--- a/data/db/sqlite-tracker-triggers.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-CREATE TRIGGER delete_backup_service BEFORE DELETE ON BackupServices 
-BEGIN  
-	DELETE FROM BackupMetaData WHERE ServiceID = old.ID;
-END;!
diff --git a/data/db/sqlite-tracker.sql b/data/db/sqlite-tracker.sql
index e41ba4a..907fc03 100644
--- a/data/db/sqlite-tracker.sql
+++ b/data/db/sqlite-tracker.sql
@@ -13,75 +13,4 @@ insert Into Options (OptionKey, OptionValue) values ('KMailLastModseq', '0');
 insert Into Options (OptionKey, OptionValue) values ('RssLastModseq', '0');
 insert Into Options (OptionKey, OptionValue) values ('CollationLocale', '');
 
-/* store volume and HAL info here for files */
-CREATE TABLE  Volumes
-(
-	VolumeID 	Integer primary key AUTOINCREMENT,
-	UDI		Text,
-	VolumeName	Text,
-	MountPath	Text,
-	Enabled		Integer default 0,
-	DisabledDate	Text
-);
-
-INSERT INTO Volumes (Enabled) VALUES ('1');
-
-/* provides links from one service entity to another (entities can be in different databases) */
-CREATE TABLE  ServiceLinks
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	MetadataID		Integer not null,
-	SourcePath		Text,
-	SourceName		Text,
-	DestPath		Text,
-	DestName		Text
-);
-
-
-
-/* following two tables are used to backup any user/app defined metadata for indexed/embedded services only */ 
-CREATE TABLE  BackupServices
-(
-	ID            		Integer primary key AUTOINCREMENT not null,
-	Path 			Text  not null, 
-	Name	 		Text,
-
-	unique (Path, Name)
-
-);
-
 
-CREATE TABLE  BackupMetaData
-(
-	ID			Integer primary key  AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer  not null,
-	UserValue		Text
-	
-	 
-);
-
-CREATE INDEX  BackupMetaDataIndex1 ON BackupMetaData (ServiceID, MetaDataID);
-
-
-
-CREATE TABLE KeywordImages
-(
-	Keyword 	Text primary key,
-	Image		Text
-);
-
-
-/* allow aliasing of VFolders with nice names */
-CREATE TABLE  VFolders
-(
-	Path			Text  not null,
-	Name			Text  not null,
-	Query			text not null,
-	RDF			text,
-	Type			Integer default 0,
-	active			Integer,
-
-	primary key (Path, Name)
-
-);
diff --git a/data/db/sqlite-triggers.sql b/data/db/sqlite-triggers.sql
deleted file mode 100644
index e69de29..0000000
diff --git a/data/dbus/Makefile.am b/data/dbus/Makefile.am
index 218f067..ae6ae5f 100644
--- a/data/dbus/Makefile.am
+++ b/data/dbus/Makefile.am
@@ -5,6 +5,7 @@ configdir = $(datadir)/tracker
 config_DATA =						\
 	tracker-backup.xml				\
 	tracker-daemon.xml				\
+	tracker-resources.xml				\
 	tracker-search.xml				\
 	tracker-indexer.xml				\
 	tracker-extract.xml
diff --git a/data/dbus/tracker-daemon.xml b/data/dbus/tracker-daemon.xml
index a7c82da..49f6343 100644
--- a/data/dbus/tracker-daemon.xml
+++ b/data/dbus/tracker-daemon.xml
@@ -1,53 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <!-- 
-   The "service" input parameters are a string representing the
-   service type. A list of service types can be obtained by calling
-   method GetServices and will *potentially* include the following:
-
-   "Files" 
-   "Folders" *
-   "Documents" *
-   "Images" *
-   "Music" *
-   "Videos" *
-   "Text Files" *
-   "Development Files" *
-   "Other Files" *
-   "VFS Files"
-   "VFS Folders" **
-   "VFS Documents" **
-   "VFS Images" **
-   "VFS Music" **
-   "VFS Videos" **
-   "VFS Text Files" **
-   "VFS Development Files" **
-   "VFS Other Files" **
-   "Conversations"
-   "Playlists"
-   "Applications"	
-   "Contacts"
-   "Emails"	
-   "EmailAttachments"
-   "Notes"
-   "Appointments"
-   "Tasks"
-   "Bookmarks"
-   "History"
-   "Projects"
-   
-   
-   (*) - these services are a subset of "Files" service.
-   (**) - these services are a subset of "VFSFiles" service.
-   
-   Services may also have a corresponding metadata class associated
-   with them (EG Files has "File" class, Documents "Doc" etc see the
-   spec at:
-   
-   http://freedesktop.org/wiki/Standards/shared-filemetadata-spec 
-
-   for more details on metadata classes).
-   
    The "id" input parameters can represent, in the case of a file, the
    full path and name of the file. In other cases, "id" can also be a
    unique name or URI for the specified service. 
@@ -90,6 +43,8 @@
       --> 
     <method name="GetStats">
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" 
+		  value="QVector&lt;QStringList&gt;"/>
       <arg type="aas" name="service_stats" direction="out" />
     </method>
         
diff --git a/data/dbus/tracker-extract.xml b/data/dbus/tracker-extract.xml
index 4d9de37..7e6db82 100644
--- a/data/dbus/tracker-extract.xml
+++ b/data/dbus/tracker-extract.xml
@@ -17,9 +17,9 @@
     </method>
     <method name="GetMetadata">
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
-      <arg type="s" name="path" direction="in" />
+      <arg type="s" name="uri" direction="in" />
       <arg type="s" name="mime" direction="in" />
-      <arg type="a{ss}" name="values" direction="out" />
+      <arg type="a(sss)" name="statements" direction="out" />
     </method>
   </interface>
 </node>
diff --git a/data/dbus/tracker-indexer.xml b/data/dbus/tracker-indexer.xml
index 2e85b8c..a42f963 100644
--- a/data/dbus/tracker-indexer.xml
+++ b/data/dbus/tracker-indexer.xml
@@ -11,6 +11,11 @@
 
 <node name="/">
   <interface name="org.freedesktop.Tracker.Indexer">  
+    <method name="TurtleAdd">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="s" name="file" direction="in" />
+    </method>
+
     <method name="FilesCheck">
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
       <arg type="s" name="module" direction="in" />
@@ -44,6 +49,22 @@
       <arg type="b" name="enabled" direction="in" />
     </method>
 
+    <!-- Insert single statement -->
+    <method name="InsertStatement">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> 
+      <arg type="s" name="subject" direction="in" />
+      <arg type="s" name="predicate" direction="in" />
+      <arg type="s" name="object" direction="in" />
+    </method>
+
+    <!-- Delete single statement -->
+    <method name="DeleteStatement">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> 
+      <arg type="s" name="subject" direction="in" />
+      <arg type="s" name="predicate" direction="in" />
+      <arg type="s" name="object" direction="in" />
+    </method>
+
     <method name="Pause">
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
     </method>
diff --git a/data/dbus/tracker-resources.xml b/data/dbus/tracker-resources.xml
new file mode 100644
index 0000000..74f8e25
--- /dev/null
+++ b/data/dbus/tracker-resources.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<node name="/org/freedesktop/Tracker">
+  <interface name="org.freedesktop.Tracker.Resources">
+
+    <!-- Insert single statement -->
+    <method name="Insert">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> 
+      <arg type="s" name="subject" direction="in" />
+      <arg type="s" name="predicate" direction="in" />
+      <arg type="s" name="object" direction="in" />
+    </method>
+
+    <!-- Delete single statement -->
+    <method name="Delete">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> 
+      <arg type="s" name="subject" direction="in" />
+      <arg type="s" name="predicate" direction="in" />
+      <arg type="s" name="object" direction="in" />
+    </method>
+
+    <!-- Load statements from Turtle file -->
+    <method name="Load">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> 
+      <arg type="s" name="uri" direction="in" />
+    </method>
+
+  </interface>
+</node>
diff --git a/data/dbus/tracker-search.xml b/data/dbus/tracker-search.xml
index 31c00bb..a58bf6b 100644
--- a/data/dbus/tracker-search.xml
+++ b/data/dbus/tracker-search.xml
@@ -10,8 +10,7 @@
       -->
     <method name="GetSnippet">
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
-      <arg type="s" name="service" direction="in" />
-      <arg type="s" name="id" direction="in" />
+      <arg type="s" name="uri" direction="in" />
       <arg type="s" name="search_text" direction="in" />
       <arg type="s" name="result" direction="out" />
     </method>
diff --git a/data/ontologies/10-xsd.ontology b/data/ontologies/10-xsd.ontology
new file mode 100644
index 0000000..d9ba87d
--- /dev/null
+++ b/data/ontologies/10-xsd.ontology
@@ -0,0 +1,14 @@
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+xsd: a tracker:Namespace ;
+	tracker:prefix "xsd" .
+
+xsd:string a rdfs:Class .
+xsd:boolean a rdfs:Class .
+xsd:integer a rdfs:Class .
+xsd:double a rdfs:Class .
+xsd:date a rdfs:Class .
+xsd:dateTime a rdfs:Class .
+
diff --git a/data/ontologies/11-rdf.ontology b/data/ontologies/11-rdf.ontology
new file mode 100644
index 0000000..ae3069c
--- /dev/null
+++ b/data/ontologies/11-rdf.ontology
@@ -0,0 +1,82 @@
+ prefix nrl: <http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+rdf: a tracker:Namespace ;
+	tracker:prefix "rdf" .
+
+rdfs: a tracker:Namespace ;
+	tracker:prefix "rdfs" .
+
+rdfs:Resource a rdfs:Class ;
+	rdfs:label "All Resources" ;
+	rdfs:comment "All resources" .
+
+rdfs:Class a rdfs:Class ;
+	rdfs:label "Class" ;
+	rdfs:subClassOf rdfs:Resource .
+
+rdf:Property a rdfs:Class ;
+	rdfs:label "Property" ;
+	rdfs:subClassOf rdfs:Resource .
+
+rdfs:Literal a rdfs:Class ;
+	rdfs:label "Literal" ;
+	rdfs:subClassOf rdfs:Resource .
+
+rdf:type a rdf:Property ;
+	rdfs:domain rdfs:Resource ;
+	rdfs:range rdfs:Class .
+
+rdfs:subClassOf a rdf:Property ;
+	rdfs:domain rdfs:Class ;
+	rdfs:range rdfs:Class .
+
+rdfs:subPropertyOf a rdf:Property ;
+	rdfs:domain rdf:Property ;
+	rdfs:range rdf:Property .
+
+rdfs:comment a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdfs:Resource ;
+	rdfs:range xsd:string .
+
+rdfs:label a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdfs:Resource ;
+	rdfs:range xsd:string .
+
+rdfs:domain a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdf:Property ;
+	rdfs:range rdfs:Resource .
+
+rdfs:range a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdf:Property ;
+	rdfs:range rdfs:Class .
+
+tracker: a tracker:Namespace ;
+	tracker:prefix "tracker" .
+
+tracker:Namespace a rdfs:Class ;
+	rdfs:label "Namespace" ;
+	rdfs:subClassOf rdfs:Resource .
+
+tracker:prefix a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain tracker:Namespace ;
+	rdfs:range xsd:string .
+
+tracker:indexed a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdf:Property ;
+	rdfs:range xsd:boolean .
+
+tracker:fulltextIndexed a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdf:Property ;
+	rdfs:range xsd:boolean .
+
diff --git a/data/ontologies/12-nrl.ontology b/data/ontologies/12-nrl.ontology
new file mode 100644
index 0000000..b8a5954
--- /dev/null
+++ b/data/ontologies/12-nrl.ontology
@@ -0,0 +1,14 @@
+ prefix nrl: <http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+nrl: a tracker:Namespace ;
+	tracker:prefix "nrl" .
+
+nrl:maxCardinality a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdf:Property ;
+	rdfs:range xsd:integer .
+
diff --git a/data/ontologies/Makefile.am b/data/ontologies/Makefile.am
new file mode 100644
index 0000000..c929809
--- /dev/null
+++ b/data/ontologies/Makefile.am
@@ -0,0 +1,11 @@
+include $(top_srcdir)/Makefile.decl
+
+configdir = $(datadir)/tracker/ontologies
+
+config_DATA =			\
+	10-xsd.ontology		\
+	11-rdf.ontology		\
+	12-nrl.ontology
+
+EXTRA_DIST = $(config_DATA)
+
diff --git a/data/services/Makefile.am b/data/services/Makefile.am
deleted file mode 100644
index 3d96098..0000000
--- a/data/services/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-include $(top_srcdir)/Makefile.decl
-
-configdir = $(datadir)/tracker/services
-
-config_DATA = 				\
-	default.metadata 		\
-	default.service 		\
-	email.metadata 			\
-	file.metadata
-
-EXTRA_DIST = $(config_DATA)
diff --git a/data/services/default.metadata b/data/services/default.metadata
deleted file mode 100644
index 3fd39fe..0000000
--- a/data/services/default.metadata
+++ /dev/null
@@ -1,116 +0,0 @@
-[DC:Contributor]
-Abstract=true
-DisplayName=Contributor
-Description=Contributors to the resource (other than the authors)
-DataType=index
-
-[DC:Coverage]
-Abstract=true
-DisplayName=Coverage
-Description=The extent or scope of the resource
-DataType=index
-
-[DC:Creator]
-Abstract=true
-DisplayName=Author
-Description=The authors of the resource
-DataType=index
-
-[DC:Date]
-Abstract=true
-DisplayName=Date
-Description=Date that something interesting happened to the resource
-DataType=date
-
-[DC:Description]
-Abstract=true
-DisplayName=Description
-Description=A textual description of the content of the resource
-DataType=index
-
-[DC:Format]
-Abstract=true
-DisplayName=Format
-Description=The file format(mime) or type used when saving the resource
-DataType=keyword
-
-[DC:Identifier]
-Abstract=true
-DisplayName=Identifier
-Description=Unique identifier of the resource
-DataType=index
-
-[DC:Language]
-Abstract=true
-DisplayName=Langauge
-Description=Language used in the resource
-DataType=index
-
-[DC:Publishers]
-Abstract=true
-DisplayName=Publishers
-Description=Publishers of the resource
-DataType=index
-
-[DC:Relation]
-Abstract=true
-DisplayName=Relationship
-Description=Relationships to other resources
-DataType=index
-
-[DC:Rights]
-Abstract=true
-DisplayName=Rights
-Description=Informal rights statement of the resource
-DataType=index
-
-[DC:Source]
-Abstract=true
-DisplayName=Source
-Description=Unique identifier of the work from which this resource was derived
-DataType=index
-
-[DC:Subject]
-Abstract=true
-DisplayName=Subject
-Description=specifies the topic of the content of the resource
-DataType=index
-MultipleValues=true
-
-[DC:Keywords]
-Abstract=true
-DisplayName=Keywords
-Description=Keywords that are used to tag a resource
-DataType=keyword
-MultipleValues=true
-
-[DC:Title]
-Abstract=true
-DisplayName=Title
-Description=specifies the topic of the content of the resource
-DataType=index
-
-[DC:Type]
-Abstract=true
-DisplayName=Type
-Description=specifies the type of the content of the resource
-DataType=index
-
-[User:Rank]
-DisplayName=Rank
-Description=User settable rank or score of the resource
-FieldName=Rank
-DataType=integer
-Embedded=false
-
-[User:Keywords]
-DisplayName=Keywords
-Description=User settable keywords which are used to tag a resource
-Parent=DC:Keywords
-DataType=keyword
-Weight=50
-Embedded=false
-MultipleValues=true
-Filtered=false
-
-
diff --git a/data/services/default.service b/data/services/default.service
deleted file mode 100644
index 847d747..0000000
--- a/data/services/default.service
+++ /dev/null
@@ -1,46 +0,0 @@
-[Files]
-DisplayName=All Files
-Description=All files in the filesystem
-PropertyPrefix=File
-UIVisible=true
-Icon=system-file-manager
-UIView=icon
-ShowServiceFiles=true
-ShowServiceDirectories=true
-
-[Folders]
-DisplayName=Folders
-Description=Folders in the filesystem
-Parent=Files
-UIVisible=true
-UIView=icon
-MimePrefixes=x-directory/;inode/;
-Icon=folder
-ShowServiceFiles=true
-ShowServiceDirectories=true
-HasFullText=false
-HasMetadata=false
-HasThumbs=false
-
-[Other]
-DisplayName=Other Files
-Description=All other files that do not belong in any other category
-Parent=Files
-ShowServiceFiles=true
-ShowServiceDirectories=true
-HasMetadata=true
-HasFullText=true
-HasThumbs=true
-
-[Emails]
-DisplayName=Emails
-Description=All Emails
-PropertyPrefix=Email
-UIVisible=true
-UIMetadata1=Email:Subject
-UIMetadata2=Email:Sender
-Icon=stock_mail-open
-TabularMetadata=Email:Sender;Email:Subject;Email:Date;
-TileMetadata=Email:Sender;Email:Subject;Email:Date;Email:SentTo;Email:CC;Email:Attachments
-ContentMetadata=Email:Body
-
diff --git a/data/services/email.metadata b/data/services/email.metadata
deleted file mode 100644
index ba4001c..0000000
--- a/data/services/email.metadata
+++ /dev/null
@@ -1,64 +0,0 @@
-[Email:Recipient]
-Abstract=true
-DisplayName=Recipient
-Description=The recepient of an email
-DataType=index
-
-[Email:Body]
-DisplayName=Body
-Description=The body contents of the email
-DataType=blob
-Weight=1
-
-[Email:Date]
-DisplayName=Date
-Description=Date email was sent
-DataType=date
-Parent=DC:Date
-
-[Email:Sender]
-DisplayName=Sender
-Description=The sender of the email
-DataType=index
-Parent=DC:Creator
-Weight=10
-
-[Email:Subject]
-DisplayName=Subject
-Description=The subject of the email
-DataType=index
-Parent=DC:Subject
-Weight=20
-
-[Email:SentTo]
-DisplayName=Sent to
-Description=The group of people the email was sent to
-DataType=index
-MultipleValues=true
-Parent=Email:Recipient
-Weight=10
-
-[Email:CC]
-DisplayName=CC
-Description=The CC recipients of the email
-DataType=index
-MultipleValues=true
-Parent=Email:Recipient
-Weight=5
-
-[Email:Attachments]
-DisplayName=Attachments
-Description=The names of the attachments
-DataType=index
-Weight=5
-
-[Email:AttachmentsDelimited]
-DisplayName=AttachmentsDelimited
-Description=The names of the attachments with extra delimiting
-DataType=index
-Weight=5
-
-
-
-
-
diff --git a/data/services/file.metadata b/data/services/file.metadata
deleted file mode 100644
index 440d90e..0000000
--- a/data/services/file.metadata
+++ /dev/null
@@ -1,99 +0,0 @@
-[File:Name]
-DisplayName=Filename
-Description=Name of File
-DataType=index
-FieldName=Name
-Parent=DC:Identifier
-Weight=10
-Filtered=false
-
-[File:Ext]
-DisplayName=Extension
-Description=File extension
-DataType=index
-Weight=15
-Filtered=false
-
-[File:Path]
-DisplayName=Path
-Description=File Path
-DataType=index
-FieldName=Path
-Parent=DC:Identifier
-Weight=1
-Filtered=false
-
-[File:NameDelimited]
-DisplayName=Keywords
-Description=Name of File
-DataType=index
-Weight=5
-Filtered=false
-Delimited=true
-
-[File:Contents]
-DisplayName=Contents
-Description=File Contents
-DataType=fulltext
-Weight=1
-
-[File:Link]
-DisplayName=Link
-Description=File Link
-DataType=index
-Parent=DC:Relation
-Weight=1
-
-[File:Mime]
-DisplayName=Mime Type
-Description=File Mime Type
-DataType=keyword
-FieldName=Mime
-Parent=DC:Format
-Weight=10
-
-[File:Size]
-DisplayName=Size
-Description=File size in bytes
-DataType=integer
-FieldName=Size
-
-[File:License]
-DisplayName=License
-Description=File License Type
-DataType=index
-Parent=DC:Rights
-Weight=1
-
-[File:Copyright]
-DisplayName=Copyright
-Description=Copyright owners of the file
-DataType=index
-Parent=DC:Rights
-Weight=1
-
-[File:Modified]
-DisplayName=Modified
-Description=Last modified date
-DataType=date
-Parent=DC:Date
-FieldName=IndexTime
-
-[File:Accessed]
-DisplayName=Accessed
-Description=Last acessed date
-DataType=date
-Parent=DC:Date
-FieldName=Accessed
-
-[File:Other]
-DisplayName=Other
-Description=Other details about a file
-DataType=index
-Weight=1
-
-[File:Language]
-DisplayName=Language
-Description=File language
-DataType=index
-Weight=1
diff --git a/docs/reference/libtracker-common/libtracker-common-sections.txt b/docs/reference/libtracker-common/libtracker-common-sections.txt
index ef35a8c..87e8f77 100644
--- a/docs/reference/libtracker-common/libtracker-common-sections.txt
+++ b/docs/reference/libtracker-common/libtracker-common-sections.txt
@@ -109,11 +109,7 @@ tracker_env_check_xdg_dirs
 tracker_file_close
 tracker_file_get_mime_type
 tracker_file_get_mtime
-tracker_file_get_path_and_name
 tracker_file_get_size
-tracker_file_is_directory
-tracker_file_is_indexable
-tracker_file_is_valid
 tracker_file_open
 tracker_path_evaluate_name
 tracker_path_hash_table_filter_duplicates
@@ -141,23 +137,16 @@ tracker_throttle
 <TITLE>Properties</TITLE>
 TrackerProperty
 tracker_property_new
-tracker_property_append_child_id
-tracker_property_get_child_ids
 tracker_property_get_data_type
-tracker_property_get_delimited
 tracker_property_get_embedded
-tracker_property_get_field_name
 tracker_property_get_filtered
 tracker_property_get_id
 tracker_property_get_multiple_values
 tracker_property_get_name
 tracker_property_get_store_metadata
 tracker_property_get_weight
-tracker_property_set_child_ids
 tracker_property_set_data_type
-tracker_property_set_delimited
 tracker_property_set_embedded
-tracker_property_set_field_name
 tracker_property_set_filtered
 tracker_property_set_id
 tracker_property_set_multiple_values
@@ -292,32 +281,17 @@ tracker_nfs_lock_shutdown
 <TITLE>Ontology</TITLE>
 tracker_ontology_init
 tracker_ontology_shutdown
-tracker_ontology_get_field_by_id
-tracker_ontology_get_field_by_name
-tracker_ontology_get_field_name_by_service_name
-tracker_ontology_get_field_names_registered
-tracker_ontology_get_service_by_id
-tracker_ontology_get_service_by_mime
-tracker_ontology_get_service_by_name
-tracker_ontology_get_service_db_by_name
-tracker_ontology_get_service_id_by_name
-tracker_ontology_get_service_names_registered
-tracker_ontology_get_service_parent
-tracker_ontology_get_service_parent_by_id
-tracker_ontology_get_service_parent_id_by_id
-tracker_ontology_service_add
-tracker_ontology_service_get_key_metadata
-tracker_ontology_service_get_show_directories
-tracker_ontology_service_get_show_files
-tracker_ontology_service_has_embedded
-tracker_ontology_service_has_metadata
-tracker_ontology_service_has_text
-tracker_ontology_service_has_thumbnails
-tracker_ontology_service_is_valid
-tracker_ontology_field_add
-tracker_ontology_field_get_display_name
-tracker_ontology_field_get_id
-tracker_ontology_field_is_child_of
+tracker_ontology_get_property_by_id
+tracker_ontology_get_property_by_name
+tracker_ontology_get_class_by_id
+tracker_ontology_get_class_by_mime
+tracker_ontology_get_class_by_name
+tracker_ontology_get_class_db_by_name
+tracker_ontology_get_class_id_by_name
+tracker_ontology_add_class
+tracker_ontology_class_get_key_metadata
+tracker_ontology_class_is_valid
+tracker_ontology_add_property
 </SECTION>
 
 <INCLUDE>libtracker-common/tracker-parser.h</INCLUDE>
diff --git a/docs/reference/libtracker-module/libtracker-module-sections.txt b/docs/reference/libtracker-module/libtracker-module-sections.txt
index d3d9d4e..6836ff8 100644
--- a/docs/reference/libtracker-module/libtracker-module-sections.txt
+++ b/docs/reference/libtracker-module/libtracker-module-sections.txt
@@ -25,7 +25,6 @@ tracker_module_iteratable_get_count
 <TITLE>Metadata Object</TITLE>
 TrackerModuleMetadata
 tracker_module_metadata_new
-tracker_module_metadata_clear_field
 tracker_module_metadata_add_take_string
 tracker_module_metadata_add_string
 tracker_module_metadata_add_int
diff --git a/docs/reference/libtracker-module/tmpl/tracker-module-metadata.sgml b/docs/reference/libtracker-module/tmpl/tracker-module-metadata.sgml
index 3d99b07..4722a77 100644
--- a/docs/reference/libtracker-module/tmpl/tracker-module-metadata.sgml
+++ b/docs/reference/libtracker-module/tmpl/tracker-module-metadata.sgml
@@ -35,22 +35,14 @@ Metadata object
 @Returns: 
 
 
-<!-- ##### FUNCTION tracker_module_metadata_clear_field ##### -->
-<para>
-
-</para>
-
- metadata: 
- field_name: 
-
-
 <!-- ##### FUNCTION tracker_module_metadata_add_take_string ##### -->
 <para>
 
 </para>
 
 @metadata: 
- field_name: 
+ subject: 
+ predicate: 
 @value: 
 @Returns: 
 
@@ -61,7 +53,8 @@ Metadata object
 </para>
 
 @metadata: 
- field_name: 
+ subject: 
+ predicate: 
 @value: 
 
 
@@ -71,7 +64,8 @@ Metadata object
 </para>
 
 @metadata: 
- field_name: 
+ subject: 
+ predicate: 
 @value: 
 
 
@@ -81,7 +75,8 @@ Metadata object
 </para>
 
 @metadata: 
- field_name: 
+ subject: 
+ predicate: 
 @value: 
 
 
@@ -91,7 +86,8 @@ Metadata object
 </para>
 
 @metadata: 
- field_name: 
+ subject: 
+ predicate: 
 @value: 
 
 
@@ -101,7 +97,8 @@ Metadata object
 </para>
 
 @metadata: 
- field_name: 
+ subject: 
+ predicate: 
 @value: 
 
 
@@ -111,7 +108,8 @@ Metadata object
 </para>
 
 @metadata: 
- field_name: 
+ subject: 
+ predicate: 
 @value: 
 
 
diff --git a/src/libtracker-common/Makefile.am b/src/libtracker-common/Makefile.am
index a5169c3..a267173 100644
--- a/src/libtracker-common/Makefile.am
+++ b/src/libtracker-common/Makefile.am
@@ -44,10 +44,12 @@ libtracker_common_la_SOURCES =	 			\
 	tracker-log.c	 				\
 	tracker-marshal-main.c				\
 	tracker-module-config.c				\
+	tracker-namespace.c				\
 	tracker-nfs-lock.c				\
 	tracker-ontology.c				\
 	tracker-parser.c				\
 	tracker-property.c				\
+	tracker-statement-list.c			\
 	tracker-type-utils.c				\
 	tracker-utils.c					\
 	tracker-thumbnailer.c				\
@@ -70,9 +72,11 @@ libtracker_commoninclude_HEADERS =			\
 	tracker-file-utils.h				\
 	tracker-language.h				\
 	tracker-module-config.h				\
+	tracker-namespace.h				\
 	tracker-ontology.h				\
 	tracker-parser.h				\
 	tracker-property.h				\
+	tracker-statement-list.h			\
 	tracker-type-utils.h				\
 	tracker-utils.h
 
diff --git a/src/libtracker-common/tracker-class.c b/src/libtracker-common/tracker-class.c
index c9bcd9e..cd11721 100644
--- a/src/libtracker-common/tracker-class.c
+++ b/src/libtracker-common/tracker-class.c
@@ -25,32 +25,18 @@
 #include <glib.h>
 
 #include "tracker-class.h"
+#include "tracker-namespace.h"
+#include "tracker-ontology.h"
 
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_CLASS, TrackerClassPriv))
 
 typedef struct _TrackerClassPriv TrackerClassPriv;
 
 struct _TrackerClassPriv {
-	gint	       id;
-
+	gchar	      *uri;
 	gchar	      *name;
-	gchar	      *parent;
-
-	gchar	      *property_prefix;
-	gchar	      *content_metadata;
-	GSList	      *key_metadata;
-
-	TrackerDBType  db_type;
-
-	gboolean       enabled;
-	gboolean       embedded;
-
-	gboolean       has_metadata;
-	gboolean       has_full_text;
-	gboolean       has_thumbs;
 
-	gboolean       show_service_files;
-	gboolean       show_service_directories;
+	GArray        *super_classes;
 };
 
 static void class_finalize	 (GObject      *object);
@@ -65,65 +51,10 @@ static void class_set_property (GObject      *object,
 
 enum {
 	PROP_0,
-	PROP_ID,
-	PROP_NAME,
-	PROP_PARENT,
-	PROP_PROPERTY_PREFIX,
-	PROP_CONTENT_METADATA,
-	PROP_KEY_METADATA,
-	PROP_DB_TYPE,
-	PROP_ENABLED,
-	PROP_EMBEDDED,
-	PROP_HAS_METADATA,
-	PROP_HAS_FULL_TEXT,
-	PROP_HAS_THUMBS,
-	PROP_SHOW_SERVICE_FILES,
-	PROP_SHOW_SERVICE_DIRECTORIES
+	PROP_URI,
+	PROP_NAME
 };
 
-GType
-tracker_db_type_get_type (void)
-{
-	static GType etype = 0;
-
-	if (etype == 0) {
-		static const GEnumValue values[] = {
-			{ TRACKER_DB_TYPE_UNKNOWN,
-			  "TRACKER_DB_TYPE_UNKNOWN",
-			  "unknown" },
-			{ TRACKER_DB_TYPE_DATA,
-			  "TRACKER_DB_TYPE_DATA",
-			  "data" },
-			{ TRACKER_DB_TYPE_INDEX,
-			  "TRACKER_DB_TYPE_INDEX",
-			  "index" },
-			{ TRACKER_DB_TYPE_COMMON,
-			  "TRACKER_DB_TYPE_COMMON",
-			  "common" },
-			{ TRACKER_DB_TYPE_CONTENT,
-			  "TRACKER_DB_TYPE_CONTENT",
-			  "content" },
-			{ TRACKER_DB_TYPE_EMAIL,
-			  "TRACKER_DB_TYPE_EMAIL",
-			  "email" },
-			{ TRACKER_DB_TYPE_FILES,
-			  "TRACKER_DB_TYPE_FILES",
-			  "files" },
-			{ TRACKER_DB_TYPE_CACHE,
-			  "TRACKER_DB_TYPE_CACHE",
-			  "cache" },
-			{ TRACKER_DB_TYPE_USER,
-			  "TRACKER_DB_TYPE_USER",
-			  "user" },
-			{ 0, NULL, NULL }
-		};
-
-		etype = g_enum_register_static ("TrackerDBType", values);
-	}
-
-	return etype;
-}
-
 G_DEFINE_TYPE (TrackerClass, tracker_class, G_TYPE_OBJECT);
 
 static void
@@ -136,105 +67,19 @@ tracker_class_class_init (TrackerClassClass *klass)
 	object_class->set_property = class_set_property;
 
 	g_object_class_install_property (object_class,
-					 PROP_ID,
-					 g_param_spec_int ("id",
-							   "id",
-							   "Unique identifier for this service",
-							   0,
-							   G_MAXINT,
-							   0,
-							   G_PARAM_READWRITE));
+					 PROP_URI,
+					 g_param_spec_string ("uri",
+							      "uri",
+							      "URI",
+							      NULL,
+							      G_PARAM_READWRITE));
 	g_object_class_install_property (object_class,
 					 PROP_NAME,
 					 g_param_spec_string ("name",
 							      "name",
 							      "Service name",
 							      NULL,
-							      G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_PARENT,
-					 g_param_spec_string ("parent",
-							      "parent",
-							      "Service name of parent",
-							      NULL,
-							      G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_PROPERTY_PREFIX,
-					 g_param_spec_string ("property-prefix",
-							      "property-prefix",
-							      "The properties of this category are prefix:name",
-							      NULL,
-							      G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_CONTENT_METADATA,
-					 g_param_spec_string ("content-metadata",
-							      "content-metadata",
-							      "Content metadata",
-							      NULL,
-							      G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_KEY_METADATA,
-					 g_param_spec_pointer ("key-metadata",
-							       "key-metadata",
-							       "Key metadata",
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_DB_TYPE,
-					 g_param_spec_enum ("db-type",
-							    "db-type",
-							    "Database type",
-							    tracker_db_type_get_type (),
-							    TRACKER_DB_TYPE_DATA,
-							    G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_ENABLED,
-					 g_param_spec_boolean ("enabled",
-							       "enabled",
-							       "Enabled",
-							       TRUE,
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_EMBEDDED,
-					 g_param_spec_boolean ("embedded",
-							       "embedded",
-							       "Embedded",
-							       FALSE,
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_HAS_METADATA,
-					 g_param_spec_boolean ("has-metadata",
-							       "has-metadata",
-							       "Has metadata",
-							       FALSE,
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_HAS_FULL_TEXT,
-					 g_param_spec_boolean ("has-full-text",
-							       "has-full-text",
-							       "Has full text",
-							       FALSE,
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_HAS_THUMBS,
-					 g_param_spec_boolean ("has-thumbs",
-							       "has-thumbs",
-							       "Has thumbnails",
-							       FALSE,
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_SHOW_SERVICE_FILES,
-					 g_param_spec_boolean ("show-service-files",
-							       "show-service-files",
-							       "Show service files",
-							       FALSE,
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_SHOW_SERVICE_DIRECTORIES,
-					 g_param_spec_boolean ("show-service-directories",
-							       "show-service-directories",
-							       "Show service directories",
-							       FALSE,
-							       G_PARAM_READWRITE));
+							      G_PARAM_READABLE));
 
 	g_type_class_add_private (object_class, sizeof (TrackerClassPriv));
 }
@@ -242,6 +87,11 @@ tracker_class_class_init (TrackerClassClass *klass)
 static void
 tracker_class_init (TrackerClass *service)
 {
+	TrackerClassPriv *priv;
+
+	priv = GET_PRIV (service);
+
+	priv->super_classes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
 }
 
 static void
@@ -251,13 +101,10 @@ class_finalize (GObject *object)
 
 	priv = GET_PRIV (object);
 
+	g_free (priv->uri);
 	g_free (priv->name);
-	g_free (priv->parent);
-	g_free (priv->content_metadata);
-	g_free (priv->property_prefix);
 
-	g_slist_foreach (priv->key_metadata, (GFunc) g_free, NULL);
-	g_slist_free (priv->key_metadata);
+	g_array_free (priv->super_classes, TRUE);
 
 	(G_OBJECT_CLASS (tracker_class_parent_class)->finalize) (object);
 }
@@ -273,48 +120,12 @@ class_get_property (GObject	 *object,
 	priv = GET_PRIV (object);
 
 	switch (param_id) {
-	case PROP_ID:
-		g_value_set_int (value, priv->id);
+	case PROP_URI:
+		g_value_set_string (value, priv->uri);
 		break;
 	case PROP_NAME:
 		g_value_set_string (value, priv->name);
 		break;
-	case PROP_PARENT:
-		g_value_set_string (value, priv->parent);
-		break;
-	case PROP_PROPERTY_PREFIX:
-		g_value_set_string (value, priv->property_prefix);
-		break;
-	case PROP_CONTENT_METADATA:
-		g_value_set_string (value, priv->content_metadata);
-		break;
-	case PROP_KEY_METADATA:
-		g_value_set_pointer (value, priv->key_metadata);
-		break;
-	case PROP_DB_TYPE:
-		g_value_set_enum (value, priv->db_type);
-		break;
-	case PROP_ENABLED:
-		g_value_set_boolean (value, priv->enabled);
-		break;
-	case PROP_EMBEDDED:
-		g_value_set_boolean (value, priv->embedded);
-		break;
-	case PROP_HAS_METADATA:
-		g_value_set_boolean (value, priv->has_metadata);
-		break;
-	case PROP_HAS_FULL_TEXT:
-		g_value_set_boolean (value, priv->has_full_text);
-		break;
-	case PROP_HAS_THUMBS:
-		g_value_set_boolean (value, priv->has_thumbs);
-		break;
-	case PROP_SHOW_SERVICE_FILES:
-		g_value_set_boolean (value, priv->show_service_files);
-		break;
-	case PROP_SHOW_SERVICE_DIRECTORIES:
-		g_value_set_boolean (value, priv->show_service_directories);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -332,92 +143,16 @@ class_set_property (GObject	   *object,
 	priv = GET_PRIV (object);
 
 	switch (param_id) {
-	case PROP_ID:
-		tracker_class_set_id (TRACKER_CLASS (object),
-					g_value_get_int (value));
-		break;
-	case PROP_NAME:
-		tracker_class_set_name (TRACKER_CLASS (object),
+	case PROP_URI:
+		tracker_class_set_uri (TRACKER_CLASS (object),
 					  g_value_get_string (value));
 		break;
-	case PROP_PROPERTY_PREFIX:
-		tracker_class_set_property_prefix (TRACKER_CLASS (object),
-						     g_value_get_string (value));
-		break;
-	case PROP_PARENT:
-		tracker_class_set_parent (TRACKER_CLASS (object),
-					    g_value_get_string (value));
-		break;
-	case PROP_CONTENT_METADATA:
-		tracker_class_set_content_metadata (TRACKER_CLASS (object),
-						      g_value_get_string (value));
-		break;
-	case PROP_KEY_METADATA:
-		tracker_class_set_key_metadata (TRACKER_CLASS (object),
-						  g_value_get_pointer (value));
-		break;
-	case PROP_DB_TYPE:
-		tracker_class_set_db_type (TRACKER_CLASS (object),
-					     g_value_get_enum (value));
-		break;
-	case PROP_ENABLED:
-		tracker_class_set_enabled (TRACKER_CLASS (object),
-					     g_value_get_boolean (value));
-		break;
-	case PROP_EMBEDDED:
-		tracker_class_set_embedded (TRACKER_CLASS (object),
-					      g_value_get_boolean (value));
-		break;
-	case PROP_HAS_METADATA:
-		tracker_class_set_has_metadata (TRACKER_CLASS (object),
-						  g_value_get_boolean (value));
-		break;
-	case PROP_HAS_FULL_TEXT:
-		tracker_class_set_has_full_text (TRACKER_CLASS (object),
-						   g_value_get_boolean (value));
-		break;
-	case PROP_HAS_THUMBS:
-		tracker_class_set_has_thumbs (TRACKER_CLASS (object),
-						g_value_get_boolean (value));
-		break;
-	case PROP_SHOW_SERVICE_FILES:
-		tracker_class_set_show_service_files (TRACKER_CLASS (object),
-							g_value_get_boolean (value));
-		break;
-	case PROP_SHOW_SERVICE_DIRECTORIES:
-		tracker_class_set_show_service_directories (TRACKER_CLASS (object),
-							      g_value_get_boolean (value));
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
 	};
 }
 
-static gboolean
-class_int_validate (TrackerClass *service,
-		      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 (service), 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;
-}
-
 TrackerClass *
 tracker_class_new (void)
 {
@@ -428,20 +163,8 @@ tracker_class_new (void)
 	return service;
 }
 
-gint
-tracker_class_get_id (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), -1);
-
-	priv = GET_PRIV (service);
-
-	return priv->id;
-}
-
 const gchar *
-tracker_class_get_name (TrackerClass *service)
+tracker_class_get_uri (TrackerClass *service)
 {
 	TrackerClassPriv *priv;
 
@@ -449,35 +172,11 @@ tracker_class_get_name (TrackerClass *service)
 
 	priv = GET_PRIV (service);
 
-	return priv->name;
+	return priv->uri;
 }
 
 const gchar *
-tracker_class_get_parent (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), NULL);
-
-	priv = GET_PRIV (service);
-
-	return priv->parent;
-}
-
-const gchar *
-tracker_class_get_property_prefix (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), NULL);
-
-	priv = GET_PRIV (service);
-
-	return priv->property_prefix;
-}
-
-const gchar *
-tracker_class_get_content_metadata (TrackerClass *service)
+tracker_class_get_name (TrackerClass *service)
 {
 	TrackerClassPriv *priv;
 
@@ -485,11 +184,11 @@ tracker_class_get_content_metadata (TrackerClass *service)
 
 	priv = GET_PRIV (service);
 
-	return priv->content_metadata;
+	return priv->name;
 }
 
-const GSList *
-tracker_class_get_key_metadata (TrackerClass *service)
+TrackerClass **
+tracker_class_get_super_classes (TrackerClass *service)
 {
 	TrackerClassPriv *priv;
 
@@ -497,125 +196,11 @@ tracker_class_get_key_metadata (TrackerClass *service)
 
 	priv = GET_PRIV (service);
 
-	return priv->key_metadata;
-}
-
-TrackerDBType
-tracker_class_get_db_type (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), TRACKER_DB_TYPE_DATA);
-
-	priv = GET_PRIV (service);
-
-	return priv->db_type;
-}
-
-gboolean
-tracker_class_get_enabled (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
-
-	priv = GET_PRIV (service);
-
-	return priv->enabled;
-}
-
-gboolean
-tracker_class_get_embedded (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
-
-	priv = GET_PRIV (service);
-
-	return priv->embedded;
-}
-
-gboolean
-tracker_class_get_has_metadata (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
-
-	priv = GET_PRIV (service);
-
-	return priv->has_metadata;
-}
-
-gboolean
-tracker_class_get_has_full_text (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
-
-	priv = GET_PRIV (service);
-
-	return priv->has_full_text;
-}
-
-gboolean
-tracker_class_get_has_thumbs (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
-
-	priv = GET_PRIV (service);
-
-	return priv->has_thumbs;
-}
-
-gboolean
-tracker_class_get_show_service_files (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
-
-	priv = GET_PRIV (service);
-
-	return priv->show_service_files;
-}
-
-gboolean
-tracker_class_get_show_service_directories (TrackerClass *service)
-{
-	TrackerClassPriv *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
-
-	priv = GET_PRIV (service);
-
-	return priv->show_service_directories;
+	return (TrackerClass **) priv->super_classes->data;
 }
 
 void
-tracker_class_set_id (TrackerClass *service,
-			gint		value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	if (!class_int_validate (service, "id", value)) {
-		return;
-	}
-
-	priv = GET_PRIV (service);
-
-	priv->id = value;
-	g_object_notify (G_OBJECT (service), "id");
-}
-
-void
-tracker_class_set_name (TrackerClass *service,
+tracker_class_set_uri (TrackerClass *service,
 			  const gchar	 *value)
 {
 	TrackerClassPriv *priv;
@@ -624,221 +209,69 @@ tracker_class_set_name (TrackerClass *service,
 
 	priv = GET_PRIV (service);
 
+	g_free (priv->uri);
 	g_free (priv->name);
+	priv->uri = NULL;
+	priv->name = NULL;
 
 	if (value) {
-		priv->name = g_strdup (value);
-	} else {
-		priv->name = NULL;
-	}
-
-	g_object_notify (G_OBJECT (service), "name");
-}
-
-void
-tracker_class_set_parent (TrackerClass *service,
-			    const gchar    *value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	g_free (priv->parent);
-
-	if (value) {
-		priv->parent = g_strdup (value);
-	} else {
-		priv->parent = NULL;
-	}
+		gchar *namespace_uri, *hash;
+		TrackerNamespace *namespace;
 
-	g_object_notify (G_OBJECT (service), "parent");
-}
+		priv->uri = g_strdup (value);
 
-void
-tracker_class_set_property_prefix (TrackerClass *service,
-				     const gchar    *value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	g_free (priv->property_prefix);
-
-	if (value) {
-		priv->property_prefix = g_strdup (value);
-	} else {
-		priv->property_prefix = NULL;
-	}
-
-	g_object_notify (G_OBJECT (service), "property-prefix");
-}
-
-void
-tracker_class_set_content_metadata (TrackerClass *service,
-				      const gchar    *value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	g_free (priv->content_metadata);
-
-	if (value) {
-		priv->content_metadata = g_strdup (value);
-	} else {
-		priv->content_metadata = NULL;
-	}
-
-	g_object_notify (G_OBJECT (service), "content-metadata");
-}
-
-void
-tracker_class_set_key_metadata (TrackerClass *service,
-				  const GSList	 *value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	g_slist_foreach (priv->key_metadata, (GFunc) g_free, NULL);
-	g_slist_free (priv->key_metadata);
-
-	if (value) {
-		GSList	     *new_list;
-		const GSList *l;
-
-		new_list = NULL;
-
-		for (l = value; l; l = l->next) {
-			new_list = g_slist_prepend (new_list, g_strdup (l->data));
+		hash = strrchr (priv->uri, '#');
+		if (hash == NULL) {
+			/* support ontologies whose namespace uri does not end in a hash, e.g. dc */
+			hash = strrchr (priv->uri, '/');
+		}
+		if (hash == NULL) {
+			g_critical ("Unknown namespace of class %s", priv->uri);
+		} else {
+			namespace_uri = g_strndup (priv->uri, hash - priv->uri + 1);
+			namespace = tracker_ontology_get_namespace_by_uri (namespace_uri);
+			if (namespace == NULL) {
+				g_critical ("Unknown namespace %s of class %s", namespace_uri, priv->uri);
+			} else {
+				priv->name = g_strdup_printf ("%s:%s", tracker_namespace_get_prefix (namespace), hash + 1);
+			}
+			g_free (namespace_uri);
 		}
-
-		new_list = g_slist_reverse (new_list);
-		priv->key_metadata = new_list;
-	} else {
-		priv->key_metadata = NULL;
 	}
 
-	g_object_notify (G_OBJECT (service), "key-metadata");
+	g_object_notify (G_OBJECT (service), "uri");
 }
 
 void
-tracker_class_set_db_type (TrackerClass *service,
-			     TrackerDBType   value)
+tracker_class_set_super_classes (TrackerClass  *service,
+			         TrackerClass **value)
 {
 	TrackerClassPriv *priv;
+	TrackerClass     **super_class;
 
 	g_return_if_fail (TRACKER_IS_CLASS (service));
 
 	priv = GET_PRIV (service);
 
-	priv->db_type = value;
-	g_object_notify (G_OBJECT (service), "db-type");
-}
+	g_array_free (priv->super_classes, TRUE);
 
-void
-tracker_class_set_enabled (TrackerClass *service,
-			     gboolean	     value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	priv->enabled = value;
-	g_object_notify (G_OBJECT (service), "enabled");
-}
-
-void
-tracker_class_set_embedded (TrackerClass *service,
-			      gboolean	      value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	priv->embedded = value;
-	g_object_notify (G_OBJECT (service), "embedded");
-}
-
-void
-tracker_class_set_has_metadata (TrackerClass *service,
-				  gboolean	  value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	priv->has_metadata = value;
-	g_object_notify (G_OBJECT (service), "has-metadata");
-}
-
-void
-tracker_class_set_has_full_text (TrackerClass *service,
-				   gboolean	   value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	priv->has_full_text = value;
-	g_object_notify (G_OBJECT (service), "has-full-text");
-}
-
-void
-tracker_class_set_has_thumbs (TrackerClass *service,
-				gboolean	value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	priv->has_thumbs = value;
-	g_object_notify (G_OBJECT (service), "has-thumbs");
-}
-
-void
-tracker_class_set_show_service_files (TrackerClass *service,
-					gboolean	value)
-{
-	TrackerClassPriv *priv;
-
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-
-	priv = GET_PRIV (service);
-
-	priv->show_service_files = value;
-	g_object_notify (G_OBJECT (service), "show-service-files");
+	priv->super_classes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
+	for (super_class = value; *super_class; super_class++) {
+		g_array_append_val (priv->super_classes, *super_class);
+	}
 }
 
 void
-tracker_class_set_show_service_directories (TrackerClass *service,
-					      gboolean	      value)
+tracker_class_add_super_class (TrackerClass  *service,
+			         TrackerClass *value)
 {
 	TrackerClassPriv *priv;
 
 	g_return_if_fail (TRACKER_IS_CLASS (service));
+	g_return_if_fail (TRACKER_IS_CLASS (value));
 
 	priv = GET_PRIV (service);
 
-	priv->show_service_directories = value;
-	g_object_notify (G_OBJECT (service), "show-service-directories");
+	g_array_append_val (priv->super_classes, value);
 }
 
diff --git a/src/libtracker-common/tracker-class.h b/src/libtracker-common/tracker-class.h
index 8de96e6..3e0414b 100644
--- a/src/libtracker-common/tracker-class.h
+++ b/src/libtracker-common/tracker-class.h
@@ -30,23 +30,6 @@ G_BEGIN_DECLS
 #error "only <libtracker-common/tracker-common.h> must be included directly."
 #endif
 
-#define TRACKER_TYPE_DB_TYPE (tracker_db_type_get_type ())
-
-typedef enum {
-	TRACKER_DB_TYPE_UNKNOWN,
-	TRACKER_DB_TYPE_DATA,
-	TRACKER_DB_TYPE_INDEX,
-	TRACKER_DB_TYPE_COMMON,
-	TRACKER_DB_TYPE_CONTENT,
-	TRACKER_DB_TYPE_EMAIL,
-	TRACKER_DB_TYPE_FILES,
-	TRACKER_DB_TYPE_CACHE,
-	TRACKER_DB_TYPE_USER
-} TrackerDBType;
-
-GType tracker_db_type_get_type (void) G_GNUC_CONST;
-
-
 #define TRACKER_TYPE_CLASS	     (tracker_class_get_type ())
 #define TRACKER_CLASS(o)	     (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_CLASS, TrackerClass))
 #define TRACKER_CLASS_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), TRACKER_TYPE_CLASS, TrackerClassClass))
@@ -69,49 +52,16 @@ GType		tracker_class_get_type		     (void) G_GNUC_CONST;
 
 TrackerClass *tracker_class_new			     (void);
 
-gint		tracker_class_get_id			     (TrackerClass *service);
+const gchar *	tracker_class_get_uri			     (TrackerClass *service);
 const gchar *	tracker_class_get_name		     (TrackerClass *service);
-const gchar *	tracker_class_get_parent		     (TrackerClass *service);
-const gchar *	tracker_class_get_property_prefix	     (TrackerClass *service);
-const gchar *	tracker_class_get_content_metadata	     (TrackerClass *service);
-const GSList *	tracker_class_get_key_metadata	     (TrackerClass *service);
-TrackerDBType	tracker_class_get_db_type		     (TrackerClass *service);
-gboolean	tracker_class_get_enabled		     (TrackerClass *service);
-gboolean	tracker_class_get_embedded		     (TrackerClass *service);
-gboolean	tracker_class_get_has_metadata	     (TrackerClass *service);
-gboolean	tracker_class_get_has_full_text	     (TrackerClass *service);
-gboolean	tracker_class_get_has_thumbs		     (TrackerClass *service);
-gboolean	tracker_class_get_show_service_files	     (TrackerClass *service);
-gboolean	tracker_class_get_show_service_directories (TrackerClass *service);
+TrackerClass  **tracker_class_get_super_classes		     (TrackerClass *service);
 
-void		tracker_class_set_id			     (TrackerClass *service,
-							      gint	      value);
-void		tracker_class_set_name		     (TrackerClass *service,
-							      const gchar    *value);
-void		tracker_class_set_parent		     (TrackerClass *service,
-							      const gchar    *value);
-void		tracker_class_set_property_prefix	     (TrackerClass *service,
-							      const gchar    *value);
-void		tracker_class_set_content_metadata	     (TrackerClass *service,
+void		tracker_class_set_uri			     (TrackerClass *service,
 							      const gchar    *value);
-void		tracker_class_set_key_metadata	     (TrackerClass *service,
-							      const GSList   *value);
-void		tracker_class_set_db_type		     (TrackerClass *service,
-							      TrackerDBType   value);
-void		tracker_class_set_enabled		     (TrackerClass *service,
-							      gboolean	      value);
-void		tracker_class_set_embedded		     (TrackerClass *service,
-							      gboolean	      value);
-void		tracker_class_set_has_metadata	     (TrackerClass *service,
-							      gboolean	      value);
-void		tracker_class_set_has_full_text	     (TrackerClass *service,
-							      gboolean	      value);
-void		tracker_class_set_has_thumbs		     (TrackerClass *service,
-							      gboolean	      value);
-void		tracker_class_set_show_service_files	     (TrackerClass *service,
-							      gboolean	      value);
-void		tracker_class_set_show_service_directories (TrackerClass *service,
-							      gboolean	      value);
+void		tracker_class_set_super_classes		     (TrackerClass  *self,
+							      TrackerClass **super_classes);
+void		tracker_class_add_super_class		     (TrackerClass  *self,
+							      TrackerClass  *value);
 
 G_END_DECLS
 
diff --git a/src/libtracker-common/tracker-common.h b/src/libtracker-common/tracker-common.h
index 4fb22d3..53711b9 100644
--- a/src/libtracker-common/tracker-common.h
+++ b/src/libtracker-common/tracker-common.h
@@ -32,15 +32,16 @@ G_BEGIN_DECLS
 
 #define __LIBTRACKER_COMMON_INSIDE__
 
+#include "tracker-class.h"
 #include "tracker-config.h"
-#include "tracker-property.h"
 #include "tracker-file-utils.h"
 #include "tracker-hal.h"
 #include "tracker-language.h"
 #include "tracker-module-config.h"
+#include "tracker-namespace.h"
 #include "tracker-ontology.h"
 #include "tracker-parser.h"
-#include "tracker-class.h"
+#include "tracker-property.h"
 #include "tracker-type-utils.h"
 #include "tracker-utils.h"
 
diff --git a/src/libtracker-common/tracker-file-utils.c b/src/libtracker-common/tracker-file-utils.c
index 569a201..fa8b202 100644
--- a/src/libtracker-common/tracker-file-utils.c
+++ b/src/libtracker-common/tracker-file-utils.c
@@ -85,19 +85,16 @@ tracker_file_close (FILE     *file,
 }
 
 goffset
-tracker_file_get_size (const gchar *uri)
+tracker_file_get_size (const gchar *path)
 {
 	GFileInfo *info;
 	GFile	  *file;
 	GError	  *error = NULL;
 	goffset    size;
 
-	g_return_val_if_fail (uri != NULL, 0);
+	g_return_val_if_fail (path != NULL, 0);
 
-	/* NOTE: We will need to fix this in Jurg's branch and call
-	 * the _for_uri() variant.
-	 */
-	file = g_file_new_for_path (uri);
+	file = g_file_new_for_path (path);
 	info = g_file_query_info (file,
 				  G_FILE_ATTRIBUTE_STANDARD_SIZE,
 				  G_FILE_QUERY_INFO_NONE,
@@ -106,7 +103,7 @@ tracker_file_get_size (const gchar *uri)
 
 	if (G_UNLIKELY (error)) {
 		g_message ("Could not get size for '%s', %s",
-			   uri,
+			   path,
 			   error->message);
 		g_error_free (error);
 		size = 0;
@@ -121,19 +118,16 @@ tracker_file_get_size (const gchar *uri)
 }
 
 guint64
-tracker_file_get_mtime (const gchar *uri)
+tracker_file_get_mtime (const gchar *path)
 {
 	GFileInfo *info;
 	GFile	  *file;
 	GError	  *error = NULL;
 	guint64    mtime;
 
-	g_return_val_if_fail (uri != NULL, 0);
+	g_return_val_if_fail (path != NULL, 0);
 
-	/* NOTE: We will need to fix this in Jurg's branch and call
-	 * the _for_uri() variant.
-	 */
-	file = g_file_new_for_path (uri);
+	file = g_file_new_for_path (path);
 	info = g_file_query_info (file,
 				  G_FILE_ATTRIBUTE_TIME_MODIFIED,
 				  G_FILE_QUERY_INFO_NONE,
@@ -142,7 +136,7 @@ tracker_file_get_mtime (const gchar *uri)
 
 	if (G_UNLIKELY (error)) {
 		g_message ("Could not get mtime for '%s', %s",
-			   uri,
+			   path,
 			   error->message);
 		g_error_free (error);
 		mtime = 0;
@@ -157,17 +151,14 @@ tracker_file_get_mtime (const gchar *uri)
 }
 
 gchar *
-tracker_file_get_mime_type (const gchar *uri)
+tracker_file_get_mime_type (GFile *file)
 {
 	GFileInfo *info;
-	GFile	  *file;
 	GError	  *error = NULL;
 	gchar	  *content_type;
 
-	/* NOTE: We will need to fix this in Jurg's branch and call
-	 * the _for_uri() variant.
-	 */
-	file = g_file_new_for_path (uri);
+	g_return_val_if_fail (G_IS_FILE (file), NULL);
+
 	info = g_file_query_info (file,
 				  G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
 				  G_FILE_QUERY_INFO_NONE,
@@ -184,138 +175,20 @@ tracker_file_get_mime_type (const gchar *uri)
 		g_object_unref (info);
 	}
 
-	g_object_unref (file);
-
 	return content_type ? content_type : g_strdup ("unknown");
 }
 
-static gchar *
-tracker_file_get_vfs_path (const gchar *uri)
-{
-	gchar *p;
-
-	if (!uri || !strchr (uri, G_DIR_SEPARATOR)) {
-		return NULL;
-	}
-
-	p = (gchar*) uri + strlen (uri) - 1;
-
-	/* Skip trailing slash */
-	if (p != uri && *p == G_DIR_SEPARATOR) {
-		p--;
-	}
-
-	/* Search backwards to the next slash. */
-	while (p != uri && *p != G_DIR_SEPARATOR) {
-		p--;
-	}
-
-	if (p[0] != '\0') {
-		gchar *new_uri_text;
-		gint   length;
-
-		length = p - uri;
-
-		if (length == 0) {
-			new_uri_text = g_strdup (G_DIR_SEPARATOR_S);
-		} else {
-			new_uri_text = g_malloc (length + 1);
-			memcpy (new_uri_text, uri, length);
-			new_uri_text[length] = '\0';
-		}
-
-		return new_uri_text;
-	} else {
-		return g_strdup (G_DIR_SEPARATOR_S);
-	}
-}
-
-static gchar *
-tracker_file_get_vfs_name (const gchar *uri)
-{
-	gchar *p, *res, *tmp, *result;
-
-	if (!uri || !strchr (uri, G_DIR_SEPARATOR)) {
-		return g_strdup (" ");
-	}
-
-	tmp = g_strdup (uri);
-	p = tmp + strlen (uri) - 1;
-
-	/* Skip trailing slash */
-	if (p != tmp && *p == G_DIR_SEPARATOR) {
-		*p = '\0';
-	}
-
-	/* Search backwards to the next slash.	*/
-	while (p != tmp && *p != G_DIR_SEPARATOR) {
-		p--;
-	}
-
-	res = p + 1;
-
-	if (res && res[0] != '\0') {
-		result = g_strdup (res);
-		g_free (tmp);
-
-		return result;
-	}
-
-	g_free (tmp);
-
-	return g_strdup (" ");
-}
-
-
-static gchar *
-normalize_uri (const gchar *uri) {
-
-	GFile  *f;
-	gchar *normalized;
-
-	f = g_file_new_for_path (uri);
-	normalized =  g_file_get_path (f);
-	g_object_unref (f);
-
-	return normalized;
-}
-
-void
-tracker_file_get_path_and_name (const gchar *uri,
-				gchar **path,
-				gchar **name)
-{
-
-	g_return_if_fail (uri);
-	g_return_if_fail (path);
-	g_return_if_fail (name);
-
-	if (uri[0] == G_DIR_SEPARATOR) {
-		gchar *checked_uri;
-
-		checked_uri = normalize_uri (uri);
-		*name = g_path_get_basename (checked_uri);
-		*path = g_path_get_dirname (checked_uri);
-
-		g_free (checked_uri);
-	} else {
-		*name = tracker_file_get_vfs_name (uri);
-		*path = tracker_file_get_vfs_path (uri);
-	}
-
-}
-
 void
-tracker_path_remove (const gchar *uri)
+tracker_path_remove (const gchar *path)
 {
 	GQueue *dirs;
 	GSList *dirs_to_remove = NULL;
 
-	g_return_if_fail (uri != NULL);
+	g_return_if_fail (path != NULL);
 
 	dirs = g_queue_new ();
 
-	g_queue_push_tail (dirs, g_strdup (uri));
+	g_queue_push_tail (dirs, g_strdup (path));
 
 	while (!g_queue_is_empty (dirs)) {
 		GDir  *p;
@@ -568,7 +441,7 @@ tracker_path_list_filter_duplicates (GSList      *roots,
 }
 
 gchar *
-tracker_path_evaluate_name (const gchar *uri)
+tracker_path_evaluate_name (const gchar *path)
 {
 	gchar	     *final_path;
 	gchar	    **tokens;
@@ -578,12 +451,12 @@ tracker_path_evaluate_name (const gchar *uri)
 	const gchar  *env;
 	gchar	     *expanded;
 
-	if (!uri || uri[0] == '\0') {
+	if (!path || path[0] == '\0') {
 		return NULL;
 	}
 
 	/* First check the simple case of using tilder */
-	if (uri[0] == '~') {
+	if (path[0] == '~') {
 		const char *home = g_get_home_dir ();
 
 		if (!home || home[0] == '\0') {
@@ -592,14 +465,14 @@ tracker_path_evaluate_name (const gchar *uri)
 
 		return g_build_path (G_DIR_SEPARATOR_S,
 				     home,
-				     uri + 1,
+				     path + 1,
 				     NULL);
 	}
 
 	/* Second try to find any environment variables and expand
 	 * them, like $HOME or ${FOO}
 	 */
-	tokens = g_strsplit (uri, G_DIR_SEPARATOR_S, -1);
+	tokens = g_strsplit (path, G_DIR_SEPARATOR_S, -1);
 
 	for (token = tokens; *token; token++) {
 		if (**token != '$') {
@@ -631,7 +504,7 @@ tracker_path_evaluate_name (const gchar *uri)
 		expanded = g_strjoinv (G_DIR_SEPARATOR_S, tokens);
 		g_strfreev (tokens);
 	} else {
-		expanded = g_strdup (uri);
+		expanded = g_strdup (path);
 	}
 
 	/* Only resolve relative paths if there is a directory
diff --git a/src/libtracker-common/tracker-file-utils.h b/src/libtracker-common/tracker-file-utils.h
index ea1dd4e..8edcc02 100644
--- a/src/libtracker-common/tracker-file-utils.h
+++ b/src/libtracker-common/tracker-file-utils.h
@@ -28,6 +28,7 @@
 
 #include <stdio.h>
 #include <glib.h>
+#include <gio/gio.h>
 
 FILE*    tracker_file_open                         (const gchar  *uri,
 						    const gchar  *how,
@@ -36,10 +37,7 @@ void     tracker_file_close                        (FILE         *file,
 						    gboolean      need_again_soon);
 goffset  tracker_file_get_size                     (const gchar  *uri);
 guint64  tracker_file_get_mtime                    (const gchar  *uri);
-gchar *  tracker_file_get_mime_type                (const gchar  *uri);
-void     tracker_file_get_path_and_name            (const gchar  *uri,
-						    gchar       **path,
-						    gchar       **name);
+gchar *  tracker_file_get_mime_type                (GFile        *file);
 void     tracker_path_remove                       (const gchar  *uri);
 gboolean tracker_path_is_in_path                   (const gchar  *path,
 						    const gchar  *in_path);
diff --git a/src/libtracker-common/tracker-hal.c b/src/libtracker-common/tracker-hal.c
index 7d9d713..1c551dd 100644
--- a/src/libtracker-common/tracker-hal.c
+++ b/src/libtracker-common/tracker-hal.c
@@ -25,6 +25,7 @@
 
 #include <string.h>
 
+#include <gio/gio.h>
 #include <libhal.h>
 #include <libhal-storage.h>
 
@@ -1150,31 +1151,38 @@ tracker_hal_get_removable_device_roots (TrackerHal *hal)
 /**
  * tracker_hal_path_is_on_removable_device:
  * @hal: A #TrackerHal
- * @path: a path
- * @mount_mount: if @path is on a removable device, the mount point will
+ * @uri: a uri
+ * @mount_mount: if @uri is on a removable device, the mount point will
  * be filled in here. You must free the returned result
- * @available: if @path is on a removable device, this will be set to 
+ * @available: if @uri is on a removable device, this will be set to 
  * TRUE in case the file is available right now
  *
- * Returns Whether or not @path is on a known removable device
+ * Returns Whether or not @uri is on a known removable device
  *
- * Returns: TRUE if @path on a known removable device, FALSE otherwise
+ * Returns: TRUE if @uri on a known removable device, FALSE otherwise
  **/
 gboolean
-tracker_hal_path_is_on_removable_device (TrackerHal  *hal,
-					 const gchar *path,
-					 gchar      **mount_point,
-					 gboolean    *available)
+tracker_hal_uri_is_on_removable_device (TrackerHal  *hal,
+				        const gchar *uri,
+				        gchar      **mount_point,
+				        gboolean    *available)
 {
 	TrackerHalPriv *priv;
 	GHashTableIter  iter;
 	gboolean        found = FALSE;
 	gpointer        key, value;
+	gchar          *path;
+	GFile          *file;
 
 	g_return_val_if_fail (TRACKER_IS_HAL (hal), FALSE);
 
-	if (!path)
+	file = g_file_new_for_uri (uri);
+	path = g_file_get_path (file);
+
+	if (!path) {
+		g_object_unref (file);
 		return FALSE;
+	}
 
 	priv = GET_PRIV (hal);
 
@@ -1216,6 +1224,9 @@ tracker_hal_path_is_on_removable_device (TrackerHal  *hal,
 		libhal_volume_free (volume);
 	}
 
+	g_free (path);
+	g_object_unref (file);
+
 	return found;
 }
 
@@ -1301,4 +1312,73 @@ tracker_hal_udi_get_is_mounted (TrackerHal  *hal,
 
 }
 
+
+
+/**
+ * tracker_hal_get_volume_udi_for_file:
+ * @hal: A #TrackerHal
+ * @file: a file
+ *
+ * Returns the UDI of the removable device for @file
+ *
+ * Returns: Returns the UDI of the removable device for @file
+ **/
+const gchar *
+tracker_hal_get_volume_udi_for_file (TrackerHal  *hal,
+				     GFile       *file)
+{
+	TrackerHalPriv *priv;
+	GHashTableIter  iter;
+	gboolean        found = FALSE;
+	gpointer        key, value;
+	gchar          *path;
+	const gchar    *udi;
+
+	g_return_val_if_fail (TRACKER_IS_HAL (hal), FALSE);
+
+	path = g_file_get_path (file);
+
+	if (!path) {
+		return NULL;
+	}
+
+	priv = GET_PRIV (hal);
+
+	g_hash_table_iter_init (&iter, priv->removable_devices);
+
+	while (g_hash_table_iter_next (&iter, &key, &value)) {
+		LibHalVolume  *volume;
+		const gchar   *mp;
+
+		udi = key;
+
+		volume = libhal_volume_from_udi (priv->context, udi);
+
+		if (!volume) {
+			g_message ("HAL device with udi:'%s' has no volume, "
+				   "should we delete?",
+				   udi);
+			continue;
+		}
+
+		mp = libhal_volume_get_mount_point (volume);
+
+		if (g_strcmp0 (mp, path) != 0) {
+			if (g_strrstr (path, mp)) {
+				found = TRUE;
+				libhal_volume_free (volume);
+				break;
+			}
+		}
+
+		libhal_volume_free (volume);
+	}
+
+	g_free (path);
+
+	if (!found)
+		udi = NULL;
+
+	return udi;
+}
 #endif /* HAVE_HAL */
diff --git a/src/libtracker-common/tracker-hal.h b/src/libtracker-common/tracker-hal.h
index d88aecc..21ea607 100644
--- a/src/libtracker-common/tracker-hal.h
+++ b/src/libtracker-common/tracker-hal.h
@@ -23,6 +23,7 @@
 #define __LIBTRACKER_HAL_H__
 
 #include <glib-object.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -66,11 +67,14 @@ const gchar *tracker_hal_udi_get_mount_point         (TrackerHal  *hal,
 						      const gchar *udi);
 gboolean     tracker_hal_udi_get_is_mounted          (TrackerHal  *hal,
 						      const gchar *udi);
-gboolean     tracker_hal_path_is_on_removable_device (TrackerHal  *hal,
-						      const gchar *path,
+gboolean     tracker_hal_uri_is_on_removable_device  (TrackerHal  *hal,
+						      const gchar *uri,
 						      gchar      **mount_point,
 						      gboolean    *available);
 
+const gchar* tracker_hal_get_volume_udi_for_file     (TrackerHal  *hal, 
+						      GFile        *file);
+
 #endif /* HAVE_HAL */
 
 G_END_DECLS
diff --git a/src/libtracker-common/tracker-namespace.c b/src/libtracker-common/tracker-namespace.c
new file mode 100644
index 0000000..3e82368
--- /dev/null
+++ b/src/libtracker-common/tracker-namespace.c
@@ -0,0 +1,224 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
+ * 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 <string.h>
+#include <stdlib.h>
+
+#include <glib.h>
+
+#include "tracker-namespace.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_NAMESPACE, TrackerNamespacePriv))
+
+typedef struct _TrackerNamespacePriv TrackerNamespacePriv;
+
+struct _TrackerNamespacePriv {
+	gchar	      *uri;
+	gchar	      *prefix;
+};
+
+static void namespace_finalize	 (GObject      *object);
+static void namespace_get_property (GObject      *object,
+				  guint		param_id,
+				  GValue       *value,
+				  GParamSpec   *pspec);
+static void namespace_set_property (GObject      *object,
+				  guint		param_id,
+				  const GValue *value,
+				  GParamSpec   *pspec);
+
+enum {
+	PROP_0,
+	PROP_URI,
+	PROP_PREFIX
+};
+
+G_DEFINE_TYPE (TrackerNamespace, tracker_namespace, G_TYPE_OBJECT);
+
+static void
+tracker_namespace_class_init (TrackerNamespaceClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize	   = namespace_finalize;
+	object_class->get_property = namespace_get_property;
+	object_class->set_property = namespace_set_property;
+
+	g_object_class_install_property (object_class,
+					 PROP_URI,
+					 g_param_spec_string ("uri",
+							      "uri",
+							      "URI",
+							      NULL,
+							      G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_PREFIX,
+					 g_param_spec_string ("prefix",
+							      "prefix",
+							      "Prefix",
+							      NULL,
+							      G_PARAM_READWRITE));
+
+	g_type_class_add_private (object_class, sizeof (TrackerNamespacePriv));
+}
+
+static void
+tracker_namespace_init (TrackerNamespace *service)
+{
+}
+
+static void
+namespace_finalize (GObject *object)
+{
+	TrackerNamespacePriv *priv;
+
+	priv = GET_PRIV (object);
+
+	g_free (priv->uri);
+	g_free (priv->prefix);
+
+	(G_OBJECT_CLASS (tracker_namespace_parent_class)->finalize) (object);
+}
+
+static void
+namespace_get_property (GObject	 *object,
+		      guint	  param_id,
+		      GValue	 *value,
+		      GParamSpec *pspec)
+{
+	TrackerNamespacePriv *priv;
+
+	priv = GET_PRIV (object);
+
+	switch (param_id) {
+	case PROP_URI:
+		g_value_set_string (value, priv->uri);
+		break;
+	case PROP_PREFIX:
+		g_value_set_string (value, priv->prefix);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+static void
+namespace_set_property (GObject	   *object,
+		      guint	    param_id,
+		      const GValue *value,
+		      GParamSpec   *pspec)
+{
+	TrackerNamespacePriv *priv;
+
+	priv = GET_PRIV (object);
+
+	switch (param_id) {
+	case PROP_URI:
+		tracker_namespace_set_uri (TRACKER_NAMESPACE (object),
+					  g_value_get_string (value));
+		break;
+	case PROP_PREFIX:
+		tracker_namespace_set_prefix (TRACKER_NAMESPACE (object),
+					  g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+TrackerNamespace *
+tracker_namespace_new (void)
+{
+	TrackerNamespace *namespace;
+
+	namespace = g_object_new (TRACKER_TYPE_NAMESPACE, NULL);
+
+	return namespace;
+}
+
+const gchar *
+tracker_namespace_get_uri (TrackerNamespace *namespace)
+{
+	TrackerNamespacePriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_NAMESPACE (namespace), NULL);
+
+	priv = GET_PRIV (namespace);
+
+	return priv->uri;
+}
+
+const gchar *
+tracker_namespace_get_prefix (TrackerNamespace *namespace)
+{
+	TrackerNamespacePriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_NAMESPACE (namespace), NULL);
+
+	priv = GET_PRIV (namespace);
+
+	return priv->prefix;
+}
+
+void
+tracker_namespace_set_uri (TrackerNamespace *namespace,
+			  const gchar	 *value)
+{
+	TrackerNamespacePriv *priv;
+
+	g_return_if_fail (TRACKER_IS_NAMESPACE (namespace));
+
+	priv = GET_PRIV (namespace);
+
+	g_free (priv->uri);
+
+	if (value) {
+		priv->uri = g_strdup (value);
+	} else {
+		priv->uri = NULL;
+	}
+
+	g_object_notify (G_OBJECT (namespace), "uri");
+}
+
+void
+tracker_namespace_set_prefix (TrackerNamespace *namespace,
+			  const gchar	 *value)
+{
+	TrackerNamespacePriv *priv;
+
+	g_return_if_fail (TRACKER_IS_NAMESPACE (namespace));
+
+	priv = GET_PRIV (namespace);
+
+	g_free (priv->prefix);
+
+	if (value) {
+		priv->prefix = g_strdup (value);
+	} else {
+		priv->prefix = NULL;
+	}
+
+	g_object_notify (G_OBJECT (namespace), "prefix");
+}
+
diff --git a/src/libtracker-common/tracker-namespace.h b/src/libtracker-common/tracker-namespace.h
new file mode 100644
index 0000000..f8b87ab
--- /dev/null
+++ b/src/libtracker-common/tracker-namespace.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
+ * 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 __LIBTRACKER_COMMON_NAMESPACE_H__
+#define __LIBTRACKER_COMMON_NAMESPACE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#if !defined (__LIBTRACKER_COMMON_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "only <libtracker-common/tracker-common.h> must be included directly."
+#endif
+
+#define TRACKER_TYPE_NAMESPACE	     (tracker_namespace_get_type ())
+#define TRACKER_NAMESPACE(o)	     (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_NAMESPACE, TrackerNamespace))
+#define TRACKER_NAMESPACE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), TRACKER_TYPE_NAMESPACE, TrackerNamespaceClass))
+#define TRACKER_IS_NAMESPACE(o)	     (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_NAMESPACE))
+#define TRACKER_IS_NAMESPACE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_NAMESPACE))
+#define TRACKER_NAMESPACE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_NAMESPACE, TrackerNamespaceClass))
+
+typedef struct _TrackerNamespace	    TrackerNamespace;
+typedef struct _TrackerNamespaceClass TrackerNamespaceClass;
+
+struct _TrackerNamespace {
+	GObject      parent;
+};
+
+struct _TrackerNamespaceClass {
+	GObjectClass parent_class;
+};
+
+GType		tracker_namespace_get_type		     (void) G_GNUC_CONST;
+
+TrackerNamespace *tracker_namespace_new			     (void);
+
+const gchar *	tracker_namespace_get_uri		     (TrackerNamespace *namespace_);
+const gchar *	tracker_namespace_get_prefix		     (TrackerNamespace *namespace_);
+
+void		tracker_namespace_set_uri		     (TrackerNamespace *namespace_,
+							      const gchar    *value);
+void		tracker_namespace_set_prefix		     (TrackerNamespace *namespace_,
+							      const gchar    *value);
+
+G_END_DECLS
+
+#endif /* __LIBTRACKER_COMMON_NAMESPACE_H__ */
+
diff --git a/src/libtracker-common/tracker-ontology.c b/src/libtracker-common/tracker-ontology.c
index 0d69e26..af28a95 100644
--- a/src/libtracker-common/tracker-ontology.c
+++ b/src/libtracker-common/tracker-ontology.c
@@ -29,104 +29,32 @@
 #include "tracker-ontology.h"
 
 typedef struct {
-	gchar *prefix;
-	gint   service;
-} ServiceMimePrefixes;
-
-typedef struct {
 	gchar  *name;
 	GArray *subcategories;
 } CalculateSubcategoriesForEach;
 
 static gboolean    initialized;
 
-/* Hash (gint service_type_id, TrackerClass *service) */
-static GHashTable *service_ids;
-
-/* Hash (gchar *service_name, TrackerClass *service) */
-static GHashTable *service_names;
-
-/* Hash (gchar *mime, gint service_type_id) */
-static GHashTable *mimes_to_service_ids;
-
-/* List of ServiceMimePrefixes */
-static GSList	  *service_mime_prefixes;
-
-/* Field descriptions */
-static GHashTable *field_names;
-
-/* FieldType enum class */
-static gpointer    field_type_enum_class;
-
-/* Category - subcategory ids cache */
-static GHashTable *subcategories_cache;
-
-static void
-ontology_mime_prefix_foreach (gpointer data,
-			      gpointer user_data)
-{
-	ServiceMimePrefixes *mime_prefix;
-
-	mime_prefix = data;
-
-	g_free (mime_prefix->prefix);
-	g_free (mime_prefix);
-}
-
-#if 0
-
-/* NOTE: This function *USED* to be for the service_names and
- * field_names hash tables so they could collate strings before
- * comparing them. But we have stopped using this because all service
- * names and field names are quite specific and defined in code so
- * they shouldn't ever need to be collated or case insensitively
- * compared.
- *
- * If this breaks things, we can reinstate it.
- */
-static gpointer
-ontology_hash_lookup_by_collated_str (GHashTable  *hash_table,
-				      const gchar *str)
-{
-	gpointer  data;
-	gchar	 *str_lower;
-
-	str_lower = g_utf8_collate_key (str, -1);
-	if (!str_lower) {
-		return NULL;
-	}
-
-	data = g_hash_table_lookup (hash_table, str_lower);
-	g_free (str_lower);
-
-	return data;
-}
+/* List of TrackerNamespace objects */
+static GArray     *namespaces;
 
-#endif
+/* Namespace uris */
+static GHashTable *namespace_uris;
 
-static gpointer
-ontology_hash_lookup_by_id (GHashTable	*hash_table,
-			    gint	 id)
-{
-	gpointer  data;
-	gchar	 *str;
+/* List of TrackerClass objects */
+static GArray     *classes;
 
-	str = g_strdup_printf ("%d", id);
-	if (!str) {
-		return NULL;
-	}
+/* Hash (gchar *class_uri, TrackerClass *service) */
+static GHashTable *class_uris;
 
-	data = g_hash_table_lookup (hash_table, str);
-	g_free (str);
+/* List of TrackerProperty objects */
+static GArray     *properties;
 
-	return data;
-}
+/* Field uris */
+static GHashTable *property_uris;
 
-static void
-free_int_array (gpointer data) 
-{
-	g_array_free ((GArray *)data, TRUE);
-}
+/* FieldType enum class */
+static gpointer    property_type_enum_class;
 
 void
 tracker_ontology_init (void)
@@ -135,36 +63,32 @@ tracker_ontology_init (void)
 		return;
 	}
 
-	service_ids = g_hash_table_new_full (g_str_hash,
-					     g_str_equal,
-					     g_free,
-					     g_object_unref);
+	namespaces = g_array_new (TRUE, TRUE, sizeof (TrackerNamespace *));
 
-	service_names = g_hash_table_new_full (g_str_hash,
-					       g_str_equal,
-					       g_free,
-					       g_object_unref);
+	namespace_uris = g_hash_table_new_full (g_str_hash,
+					      g_str_equal,
+					      g_free,
+					      g_object_unref);
 
-	mimes_to_service_ids = g_hash_table_new_full (g_str_hash,
-						      g_str_equal,
-						      g_free,
-						      NULL);
+	classes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
 
-	field_names = g_hash_table_new_full (g_str_hash,
-					     g_str_equal,
-					     g_free,
-					     g_object_unref);
+	class_uris = g_hash_table_new_full (g_str_hash,
+					      g_str_equal,
+					      g_free,
+					      g_object_unref);
 
-	subcategories_cache = g_hash_table_new_full (g_str_hash,
-						     g_str_equal,
-						     g_free,
-						     free_int_array);
+	properties = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
+
+	property_uris = g_hash_table_new_full (g_str_hash,
+					    g_str_equal,
+					    g_free,
+					    g_object_unref);
 
 	/* We will need the class later in order to match strings to enum values
 	 * when inserting metadata types in the DB, so the enum class needs to be
 	 * created beforehand.
 	 */
-	field_type_enum_class = g_type_class_ref (TRACKER_TYPE_PROPERTY_TYPE);
+	property_type_enum_class = g_type_class_ref (TRACKER_TYPE_PROPERTY_TYPE);
 
 	initialized = TRUE;
 }
@@ -172,658 +96,142 @@ tracker_ontology_init (void)
 void
 tracker_ontology_shutdown (void)
 {
+	gint i;
+
 	if (!initialized) {
 		return;
 	}
 
-	g_hash_table_unref (service_ids);
-	service_ids = NULL;
-
-	g_hash_table_unref (service_names);
-	service_names = NULL;
+	for (i = 0; i < namespaces->len; i++) {
+		g_object_unref (g_array_index (namespaces, TrackerNamespace *, i));
+	}
+	g_array_free (namespaces, TRUE);
 
-	g_hash_table_unref (mimes_to_service_ids);
-	mimes_to_service_ids = NULL;
+	g_hash_table_unref (namespace_uris);
+	namespace_uris = NULL;
 
-	g_hash_table_unref (field_names);
-	field_names = NULL;
+	for (i = 0; i < classes->len; i++) {
+		g_object_unref (g_array_index (classes, TrackerClass *, i));
+	}
+	g_array_free (classes, TRUE);
 
-	g_hash_table_unref (subcategories_cache);
-	subcategories_cache = NULL;
+	g_hash_table_unref (class_uris);
+	class_uris = NULL;
 
-	if (service_mime_prefixes) {
-		g_slist_foreach (service_mime_prefixes,
-				 ontology_mime_prefix_foreach,
-				 NULL);
-		g_slist_free (service_mime_prefixes);
-		service_mime_prefixes = NULL;
+	for (i = 0; i < properties->len; i++) {
+		g_object_unref (g_array_index (properties, TrackerProperty *, i));
 	}
+	g_array_free (properties, TRUE);
+
+	g_hash_table_unref (property_uris);
+	property_uris = NULL;
 
-	g_type_class_unref (field_type_enum_class);
-	field_type_enum_class = NULL;
+	g_type_class_unref (property_type_enum_class);
+	property_type_enum_class = NULL;
 
 	initialized = FALSE;
 }
 
 void
-tracker_ontology_service_add (TrackerClass *service,
-			      GSList	     *mimes,
-			      GSList	     *mime_prefixes)
+tracker_ontology_add_class (TrackerClass *service)
 {
 
-	GSList		    *l;
-	ServiceMimePrefixes *service_mime_prefix;
-	gint		     id;
-	const gchar	    *name;
+	const gchar	    *uri, *name;
 
 	g_return_if_fail (TRACKER_IS_CLASS (service));
 
-	id = tracker_class_get_id (service);
+	uri = tracker_class_get_uri (service);
 	name = tracker_class_get_name (service);
 
-	g_hash_table_insert (service_names,
-			     g_strdup (name),
-			     g_object_ref (service));
-	g_hash_table_insert (service_ids,
-			     g_strdup_printf ("%d", id),
-			     g_object_ref (service));
-
-	for (l = mimes; l && l->data; l = l->next) {
-		g_hash_table_insert (mimes_to_service_ids,
-				     l->data,
-				     GINT_TO_POINTER (id));
-	}
-
-	for (l = mime_prefixes; l; l = l->next) {
-		service_mime_prefix = g_new0 (ServiceMimePrefixes, 1);
-		service_mime_prefix->prefix = l->data;
-		service_mime_prefix->service = id;
+	g_object_ref (service);
+	g_array_append_val (classes, service);
 
-		service_mime_prefixes = g_slist_prepend (service_mime_prefixes,
-						       service_mime_prefix);
+	if (uri) {
+		g_hash_table_insert (class_uris,
+				     g_strdup (uri),
+				     g_object_ref (service));
 	}
 }
 
 TrackerClass *
-tracker_ontology_get_service_by_name (const gchar *service_str)
+tracker_ontology_get_class_by_uri (const gchar *class_uri)
 {
-	g_return_val_if_fail (service_str != NULL, NULL);
+	g_return_val_if_fail (class_uri != NULL, NULL);
 
-	return g_hash_table_lookup (service_names, service_str);
+	return g_hash_table_lookup (class_uris, class_uri);
 }
 
-G_CONST_RETURN gchar *
-tracker_ontology_get_service_by_id (gint id)
+TrackerNamespace **
+tracker_ontology_get_namespaces (void)
 {
-	TrackerClass *service;
-
-	service = ontology_hash_lookup_by_id (service_ids, id);
-
-	if (!service) {
-		return NULL;
-	}
-
-	return tracker_class_get_name (service);
+	/* copy len + 1 elements to include NULL terminator */
+	return g_memdup (namespaces->data, sizeof (TrackerNamespace *) * (namespaces->len + 1));
 }
 
-G_CONST_RETURN gchar *
-tracker_ontology_get_service_by_mime (const gchar *mime)
+TrackerClass **
+tracker_ontology_get_classes (void)
 {
-	gpointer	     id;
-	ServiceMimePrefixes *item;
-	GSList		    *prefix_service;
-
-	g_return_val_if_fail (mime != NULL, "Other");
-
-	/* Try a complete mime */
-	id = g_hash_table_lookup (mimes_to_service_ids, mime);
-	if (id) {
-		return tracker_ontology_get_service_by_id (GPOINTER_TO_INT (id));
-	}
-
-	/* Try in prefixes */
-	for (prefix_service = service_mime_prefixes;
-	     prefix_service != NULL;
-	     prefix_service = prefix_service->next) {
-		item = prefix_service->data;
-		if (g_str_has_prefix (mime, item->prefix)) {
-			return tracker_ontology_get_service_by_id (item->service);
-		}
-	}
-
-	/* Default option */
-	return "Other";
+	/* copy len + 1 elements to include NULL terminator */
+	return g_memdup (classes->data, sizeof (TrackerClass *) * (classes->len + 1));
 }
 
-gint
-tracker_ontology_get_service_id_by_name (const char *service_str)
+TrackerProperty **
+tracker_ontology_get_properties (void)
 {
-	TrackerClass *service;
-
-	g_return_val_if_fail (service_str != NULL, -1);
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (!service) {
-		return -1;
-	}
-
-	return tracker_class_get_id (service);
-}
-
-gchar *
-tracker_ontology_get_service_parent (const gchar *service_str)
-{
-	TrackerClass *service;
-	const gchar    *parent = NULL;
-
-	g_return_val_if_fail (service_str != NULL, NULL);
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (service) {
-		parent = tracker_class_get_parent (service);
-	}
-
-	return g_strdup (parent);
-}
-
-gchar *
-tracker_ontology_get_service_parent_by_id (gint id)
-{
-	TrackerClass *service;
-
-	service = ontology_hash_lookup_by_id (service_ids, id);
-
-	if (!service) {
-		return NULL;
-	}
-
-	return g_strdup (tracker_class_get_parent (service));
-}
-
-gint
-tracker_ontology_get_service_parent_id_by_id (gint id)
-{
-	TrackerClass *service;
-	const gchar    *parent = NULL;
-
-	service = ontology_hash_lookup_by_id (service_ids, id);
-
-	if (service) {
-		parent = tracker_class_get_parent (service);
-	}
-
-	if (!parent) {
-		return -1;
-	}
-
-	service = g_hash_table_lookup (service_names, parent);
-
-	if (!service) {
-		return -1;
-	}
-
-	return tracker_class_get_id (service);
-}
-
-TrackerDBType
-tracker_ontology_get_service_db_by_name (const gchar *service_str)
-{
-	TrackerDBType  type;
-	gchar	      *str;
-
-	g_return_val_if_fail (service_str != NULL, TRACKER_DB_TYPE_FILES);
-
-	str = g_utf8_strdown (service_str, -1);
-
-	if (g_str_has_suffix (str, "emails") ||
-	    g_str_has_suffix (str, "attachments")) {
-		type = TRACKER_DB_TYPE_EMAIL;
-	} else if (g_str_has_prefix (str, "files")) {
-		type = TRACKER_DB_TYPE_FILES;
-	} else {
-		type = TRACKER_DB_TYPE_FILES;
-	}
-
-	g_free (str);
-
-	return type;
-}
-
-GSList *
-tracker_ontology_get_service_names_registered (void)
-{
-	TrackerClass *service;
-	GList	       *services, *l;
-	GSList	       *names = NULL;
-
-	services = g_hash_table_get_values (service_names);
-
-	for (l = services; l; l = l->next) {
-		service = l->data;
-		names = g_slist_prepend (names, g_strdup (tracker_class_get_name (service)));
-	}
-
-	return names;
-}
-
-GSList *
-tracker_ontology_get_field_names_registered (const gchar *service_str)
-{
-	GList	    *fields;
-	GList	    *l;
-	GSList	    *names;
-	const gchar *prefix = NULL;
-	const gchar *parent_prefix;
-
-	parent_prefix = NULL;
-
-	if (service_str) {
-		TrackerClass *service;
-		TrackerClass *parent;
-		const gchar    *parent_name;
-
-		service = tracker_ontology_get_service_by_name (service_str);
-		if (!service) {
-			return NULL;
-		}
-
-		/* Prefix for properties of the category */
-		prefix = tracker_class_get_property_prefix (service);
-
-		if (!prefix || g_strcmp0 (prefix, " ") == 0) {
-			prefix = service_str;
-		}
-
-		/* Prefix for properties of the parent */
-		parent_name = tracker_ontology_get_service_parent (service_str);
-
-		if (parent_name && g_strcmp0 (parent_name, " ") != 0) {
-			parent = tracker_ontology_get_service_by_name (parent_name);
-
-			if (parent) {
-				parent_prefix = tracker_class_get_property_prefix (parent);
-
-				if (!parent_prefix || g_strcmp0 (parent_prefix, " ") == 0) {
-					parent_prefix = parent_name;
-				}
-			}
-		}
-	}
-
-	names = NULL;
-	fields = g_hash_table_get_values (field_names);
-
-	for (l = fields; l; l = l->next) {
-		TrackerProperty *field;
-		const gchar  *name;
-
-		field = l->data;
-		name = tracker_property_get_name (field);
-
-		if (service_str == NULL ||
-		    (prefix && g_str_has_prefix (name, prefix)) ||
-		    (parent_prefix && g_str_has_prefix (name, parent_prefix))) {
-			names = g_slist_prepend (names, g_strdup (name));
-		}
-	}
-
-	g_list_free (fields);
-
-	return names;
-}
-
-static void
-calculate_subcategories_foreach (gpointer key, 
-				 gpointer value,
-				 gpointer user_data) 
-{
-	TrackerClass                *service;
-	CalculateSubcategoriesForEach *data;
-
-	service = value;
-	data = user_data;
-
-	if (!g_strcmp0 (tracker_class_get_name (service), data->name) ||
-	    !g_strcmp0 (tracker_class_get_parent (service), data->name) ||
-	    !g_strcmp0 ("*", data->name)) {
-		gint id = tracker_class_get_id (service);
-		g_array_append_val (data->subcategories, id);
-	}
-}
-
-GArray *
-tracker_ontology_get_subcategory_ids (const gchar *service_str)
-{
-	GArray *subcategories;
-
-	subcategories = g_hash_table_lookup (subcategories_cache, service_str);
-
-	if (!subcategories) {
-		CalculateSubcategoriesForEach data;
-
-		data.name = g_strdup (service_str);
-		data.subcategories = g_array_new (TRUE, TRUE, sizeof (int));
-
-		g_hash_table_foreach (service_names, calculate_subcategories_foreach, &data);
-		g_hash_table_insert (subcategories_cache, data.name, data.subcategories);
-
-		subcategories = data.subcategories;
-	}
-
-	return subcategories;
-}
-
-/*
- * Service data
- */
-gboolean
-tracker_ontology_service_is_valid (const gchar *service_str)
-{
-	g_return_val_if_fail (service_str != NULL, FALSE);
-
-	return tracker_ontology_get_service_id_by_name (service_str) != -1;
-}
-
-gboolean
-tracker_ontology_service_has_embedded (const gchar *service_str)
-{
-	TrackerClass *service;
-
-	g_return_val_if_fail (service_str != NULL, FALSE);
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (!service) {
-		return FALSE;
-	}
-
-	return tracker_class_get_embedded (service);
-}
-
-gboolean
-tracker_ontology_service_has_metadata (const gchar *service_str)
-{
-	TrackerClass *service;
-
-	g_return_val_if_fail (service_str != NULL, FALSE);
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (!service) {
-		return FALSE;
-	}
-
-	return tracker_class_get_has_metadata (service);
-}
-
-gboolean
-tracker_ontology_service_has_thumbnails (const gchar *service_str)
-{
-	TrackerClass *service;
-
-	g_return_val_if_fail (service_str != NULL, FALSE);
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (!service) {
-		return FALSE;
-	}
-
-	return tracker_class_get_has_thumbs (service);
-}
-
-gboolean
-tracker_ontology_service_has_text (const char *service_str)
-{
-	TrackerClass *service;
-
-	g_return_val_if_fail (service_str != NULL, FALSE);
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (!service) {
-		return FALSE;
-	}
-
-	return tracker_class_get_has_full_text (service);
-}
-
-gint
-tracker_ontology_service_get_key_metadata (const gchar *service_str,
-					   const gchar *meta_name)
-{
-	TrackerClass *service;
-	gint		i;
-	const GSList   *l;
-
-	g_return_val_if_fail (service_str != NULL, 0);
-	g_return_val_if_fail (meta_name != NULL, 0);
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (!service) {
-		return 0;
-	}
-
-	for (l = tracker_class_get_key_metadata (service), i = 1;
-	     l;
-	     l = l->next, i++) {
-		if (!l->data) {
-			continue;
-		}
-
-		if (strcasecmp (l->data, meta_name) == 0) {
-			return i;
-		}
-	}
-
-	return 0;
-}
-
-gint
-tracker_ontology_service_get_key_collate (const gchar *service_str,
-					  const gchar *meta_name)
-{
-	gint		i;
-
-	g_return_val_if_fail (service_str != NULL, 0);
-	g_return_val_if_fail (meta_name != NULL, 0);
-
-	i = tracker_ontology_service_get_key_metadata (service_str, meta_name);
-
-	return ((i < 6) ? i : 0);
-}
-
-gboolean
-tracker_ontology_service_get_show_directories (const gchar *service_str)
-{
-	TrackerClass *service;
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (!service) {
-		return FALSE;
-	}
-
-	return tracker_class_get_show_service_directories (service);
-}
-
-gboolean
-tracker_ontology_service_get_show_files (const gchar *service_str)
-{
-	TrackerClass *service;
-
-	service = g_hash_table_lookup (service_names, service_str);
-
-	if (!service) {
-		return FALSE;
-	}
-
-	return tracker_class_get_show_service_files (service);
+	/* copy len + 1 elements to include NULL terminator */
+	return g_memdup (properties->data, sizeof (TrackerProperty *) * (properties->len + 1));
 }
 
 /* Field mechanics */
 void
-tracker_ontology_field_add (TrackerProperty *field)
+tracker_ontology_add_property (TrackerProperty *field)
 {
-	const gchar *name;
+	const gchar *uri;
 
 	g_return_if_fail (TRACKER_IS_PROPERTY (field));
 
-	name = tracker_property_get_name (field);
-	g_return_if_fail (name != NULL);
+	uri = tracker_property_get_uri (field);
 
-	g_hash_table_insert (field_names,
-			     /* g_utf8_collate_key (tracker_property_get_name (field), -1), */
-			     g_strdup (name),
-			     g_object_ref (field));
-}
-
-TrackerProperty *
-tracker_ontology_get_field_by_name (const gchar *name)
-{
-	g_return_val_if_fail (name != NULL, NULL);
+	g_object_ref (field);
+	g_array_append_val (properties, field);
 
-	return g_hash_table_lookup (field_names, name);
+	g_hash_table_insert (property_uris,
+			     g_strdup (uri),
+			     g_object_ref (field));
 }
 
 TrackerProperty *
-tracker_ontology_get_field_by_id (gint id)
-{
-	TrackerProperty *field = NULL;
-	GList	     *values;
-	GList	     *l;
-
-	/* TODO Create a hashtable with id -> field def. More efficient */
-
-	values = g_hash_table_get_values (field_names);
-
-	for (l = values; l && !field; l = l->next) {
-		if (atoi (tracker_property_get_id (l->data)) == id) {
-			field = l->data;
-		}
-	}
-
-	g_list_free (values);
-
-	return field;
-}
-
-gchar *
-tracker_ontology_get_field_name_by_service_name (TrackerProperty *field,
-						 const gchar  *service_str)
-{
-	const gchar *field_name;
-	const gchar *meta_name;
-	gint	     key_field;
-
-	g_return_val_if_fail (TRACKER_IS_PROPERTY (field), NULL);
-	g_return_val_if_fail (service_str != NULL, NULL);
-
-	meta_name = tracker_property_get_name (field);
-	key_field = tracker_ontology_service_get_key_metadata (service_str,
-							       meta_name);
-
-	if (key_field > 0) {
-		return g_strdup_printf ("KeyMetadata%d", key_field);
-
-	}
-
-	/* TODO do it using field_name in TrackerProperty! */
-	field_name = tracker_property_get_field_name (field);
-	if (field_name) {
-		return g_strdup (field_name);
-	} else {
-		return NULL;
-	}
-}
-
-/*
- * Field data
- */
-gchar *
-tracker_ontology_field_get_display_name (TrackerProperty *field)
+tracker_ontology_get_property_by_uri (const gchar *uri)
 {
-	TrackerPropertyType type;
-
-	g_return_val_if_fail (TRACKER_IS_PROPERTY (field), NULL);
+	g_return_val_if_fail (uri != NULL, NULL);
 
-	type = tracker_property_get_data_type (field);
-
-	if (type == TRACKER_PROPERTY_TYPE_INDEX ||
-	    type == TRACKER_PROPERTY_TYPE_STRING ||
-	    type == TRACKER_PROPERTY_TYPE_DOUBLE) {
-		return g_strdup ("MetaDataDisplay");
-	}
-
-	return g_strdup ("MetaDataValue");
+	return g_hash_table_lookup (property_uris, uri);
 }
 
-const gchar *
-tracker_ontology_field_get_id (const gchar *name)
+void
+tracker_ontology_add_namespace (TrackerNamespace *namespace)
 {
-	TrackerProperty *field;
+	const gchar *uri;
 
-	g_return_val_if_fail (name != NULL, NULL);
+	g_return_if_fail (TRACKER_IS_NAMESPACE (namespace));
 
-	field = tracker_ontology_get_field_by_name (name);
+	uri = tracker_namespace_get_uri (namespace);
 
-	if (field) {
-		return tracker_property_get_id (field);
-	}
+	g_object_ref (namespace);
+	g_array_append_val (namespaces, namespace);
 
-	return NULL;
+	g_hash_table_insert (namespace_uris,
+			     g_strdup (uri),
+			     g_object_ref (namespace));
 }
 
-gboolean
-tracker_ontology_field_is_child_of (const gchar *field_str_child,
-				    const gchar *field_str_parent)
+TrackerNamespace *
+tracker_ontology_get_namespace_by_uri (const gchar *uri)
 {
-	TrackerProperty *field_child;
-	TrackerProperty *field_parent;
-	const GSList *l;
-
-	g_return_val_if_fail (field_str_child != NULL, FALSE);
-	g_return_val_if_fail (field_str_parent != NULL, FALSE);
-
-	field_child = tracker_ontology_get_field_by_name (field_str_child);
-
-	if (!field_child) {
-		return FALSE;
-	}
-
-	field_parent = tracker_ontology_get_field_by_name (field_str_parent);
-
-	if (!field_parent) {
-		return FALSE;
-	}
+	g_return_val_if_fail (uri != NULL, NULL);
 
-	for (l = tracker_property_get_child_ids (field_parent); l; l = l->next) {
-		if (!l->data) {
-			return FALSE;
-		}
-
-		if (strcmp (tracker_property_get_id (field_child), l->data) == 0) {
-			return TRUE;
-		}
-	}
-
-	return FALSE;
+	return g_hash_table_lookup (namespace_uris, uri);
 }
 
-const gchar *
-tracker_ontology_get_field_name_by_id (gint id)
-{
-	TrackerProperty *field;
 
-	field = tracker_ontology_get_field_by_id (id);
-
-	if (field) {
-		return tracker_property_get_name (field);
-	}
-	
-	return NULL;
-}
 
diff --git a/src/libtracker-common/tracker-ontology.h b/src/libtracker-common/tracker-ontology.h
index 17aece6..d62cb86 100644
--- a/src/libtracker-common/tracker-ontology.h
+++ b/src/libtracker-common/tracker-ontology.h
@@ -24,8 +24,9 @@
 
 #include <glib-object.h>
 
-#include "tracker-property.h"
 #include "tracker-class.h"
+#include "tracker-namespace.h"
+#include "tracker-property.h"
 
 G_BEGIN_DECLS
 
@@ -33,53 +34,46 @@ G_BEGIN_DECLS
 #error "only <libtracker-common/tracker-common.h> must be included directly."
 #endif
 
+/* Core ontologies */
+#define TRACKER_RDF_PREFIX	"http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+#define TRACKER_RDFS_PREFIX	"http://www.w3.org/2000/01/rdf-schema#";
+#define TRACKER_XSD_PREFIX      "http://www.w3.org/2001/XMLSchema#";
+#define TRACKER_TRACKER_PREFIX	"http://www.tracker-project.org/ontologies/tracker#";
+#define TRACKER_DC_PREFIX	"http://dublincore.org/2008/01/14/dcterms.rdf#";
+#define TRACKER_MAEMO_PREFIX	"http://maemo.org/ontologies/tracker#";
+
+/* Our Nepomuk selection */
+#define TRACKER_NRL_PREFIX	"http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#";
+#define TRACKER_NMO_PREFIX	"http://www.semanticdesktop.org/ontologies/2007/03/22/nmo#";
+#define TRACKER_NIE_PREFIX	"http://www.semanticdesktop.org/ontologies/2007/01/19/nie#";
+#define TRACKER_NCO_PREFIX	"http://www.semanticdesktop.org/ontologies/2007/03/22/nco#";
+#define TRACKER_NAO_PREFIX	"http://www.semanticdesktop.org/ontologies/2007/08/15/nao#";
+#define TRACKER_NID3_PREFIX	"http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#";
+#define TRACKER_NFO_PREFIX	"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#";
+
+/* Temporary */
+#define TRACKER_NMM_PREFIX	"http://www.tracker-project.org/temp/nmm#";
+
+#define TRACKER_DATASOURCE_URN_PREFIX "urn:nepomuk:datasource:"
+#define TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN TRACKER_DATASOURCE_URN_PREFIX "9291a450-1d49-11de-8c30-0800200c9a66"
+
 void		tracker_ontology_init				(void);
 void		tracker_ontology_shutdown			(void);
 
 /* Service mechanics */
-void		tracker_ontology_service_add			(TrackerClass *service,
-								 GSList		*mimes,
-								 GSList		*mime_prefixes);
-TrackerClass *tracker_ontology_get_service_by_name		(const gchar	*service_str);
-G_CONST_RETURN gchar *
-                tracker_ontology_get_service_by_id		(gint		 id);
-G_CONST_RETURN gchar *
-                tracker_ontology_get_service_by_mime		(const gchar	*mime);
-gint		tracker_ontology_get_service_id_by_name		(const gchar	*service_str);
-TrackerDBType	tracker_ontology_get_service_db_by_name		(const gchar	*service_str);
-gchar *		tracker_ontology_get_service_parent		(const gchar	*service_str);
-gchar *		tracker_ontology_get_service_parent_by_id	(gint		 id);
-gint		tracker_ontology_get_service_parent_id_by_id	(gint		 id);
-GSList *	tracker_ontology_get_service_names_registered	(void);
-GSList *	tracker_ontology_get_field_names_registered	(const gchar	*service_str);
-GArray *        tracker_ontology_get_subcategory_ids            (const gchar    *service_str);
-
-/* Service data */
-gboolean	tracker_ontology_service_is_valid		(const gchar	*service_str);
-gboolean	tracker_ontology_service_has_embedded		(const gchar	*service_str);
-gboolean	tracker_ontology_service_has_metadata		(const gchar	*service_str);
-gboolean	tracker_ontology_service_has_thumbnails		(const gchar	*service_str);
-gboolean	tracker_ontology_service_has_text		(const gchar	*service_str);
-gint		tracker_ontology_service_get_key_metadata	(const gchar	*service_str,
-								 const gchar	*meta_name);
-gint		tracker_ontology_service_get_key_collate	(const gchar	*service_str,
-								 const gchar	*meta_name);
-gboolean	tracker_ontology_service_get_show_directories	(const gchar	*service_str);
-gboolean	tracker_ontology_service_get_show_files		(const gchar	*service_str);
-const gchar *	tracker_ontology_get_field_name_by_id 	        (gint id);
+void		tracker_ontology_add_class			(TrackerClass *service);
+TrackerClass *tracker_ontology_get_class_by_uri		(const gchar	*service_uri);
+
+TrackerNamespace **tracker_ontology_get_namespaces               (void);
+TrackerClass  **tracker_ontology_get_classes                    (void);
+TrackerProperty **tracker_ontology_get_properties               (void);
 
 /* Field mechanics */
-void		tracker_ontology_field_add			(TrackerProperty	*field);
-TrackerProperty *	tracker_ontology_get_field_by_name		(const gchar	*name);
-TrackerProperty *	tracker_ontology_get_field_by_id		(gint		 id);
-gchar *		tracker_ontology_get_field_name_by_service_name (TrackerProperty	*field,
-								 const gchar	*service_str);
-
-/* Field data */
-gchar *		tracker_ontology_field_get_display_name		(TrackerProperty	*field);
-const gchar *	tracker_ontology_field_get_id			(const gchar	*name);
-gboolean	tracker_ontology_field_is_child_of		(const gchar	*child,
-								 const gchar	*parent);
+void		tracker_ontology_add_property			(TrackerProperty	*field);
+TrackerProperty *	tracker_ontology_get_property_by_uri		(const gchar	*uri);
+
+void		tracker_ontology_add_namespace			(TrackerNamespace	*namespace_);
+TrackerNamespace *tracker_ontology_get_namespace_by_uri		(const gchar	*namespace_uri);
 
 G_END_DECLS
 
diff --git a/src/libtracker-common/tracker-property.c b/src/libtracker-common/tracker-property.c
index caec7f5..83f6b69 100644
--- a/src/libtracker-common/tracker-property.c
+++ b/src/libtracker-common/tracker-property.c
@@ -24,26 +24,36 @@
 
 #include <glib.h>
 
+#include "tracker-namespace.h"
+#include "tracker-ontology.h"
 #include "tracker-property.h"
 
+#define XSD_BOOLEAN TRACKER_XSD_PREFIX "boolean"
+#define XSD_DATE TRACKER_XSD_PREFIX "date"
+#define XSD_DATETIME TRACKER_XSD_PREFIX "dateTime"
+#define XSD_DOUBLE TRACKER_XSD_PREFIX "double"
+#define XSD_INTEGER TRACKER_XSD_PREFIX "integer"
+#define XSD_STRING TRACKER_XSD_PREFIX "string"
+
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_PROPERTY, TrackerPropertyPriv))
 
 typedef struct _TrackerPropertyPriv TrackerPropertyPriv;
 
 struct _TrackerPropertyPriv {
-	gchar	      *id;
+	gchar	      *uri;
 	gchar	      *name;
 
 	TrackerPropertyType  data_type;
-	gchar	      *field_name;
+	TrackerClass   *domain;
+	TrackerClass   *range;
 	gint	       weight;
+	gboolean       indexed;
+	gboolean       fulltext_indexed;
 	gboolean       embedded;
 	gboolean       multiple_values;
-	gboolean       delimited;
 	gboolean       filtered;
-	gboolean       store_metadata;
 
-	GSList	      *child_ids;
+	GArray        *super_properties;
 };
 
 static void property_finalize     (GObject      *object);
@@ -58,17 +68,17 @@ static void property_set_property (GObject      *object,
 
 enum {
 	PROP_0,
-	PROP_ID,
+	PROP_URI,
 	PROP_NAME,
 	PROP_DATA_TYPE,
-	PROP_FIELD_NAME,
+	PROP_DOMAIN,
+	PROP_RANGE,
 	PROP_WEIGHT,
+	PROP_INDEXED,
+	PROP_FULLTEXT_INDEXED,
 	PROP_EMBEDDED,
 	PROP_MULTIPLE_VALUES,
-	PROP_DELIMITED,
-	PROP_FILTERED,
-	PROP_STORE_METADATA,
-	PROP_CHILD_IDS
+	PROP_FILTERED
 };
 
 GType
@@ -78,18 +88,12 @@ tracker_property_type_get_type (void)
 
 	if (etype == 0) {
 		static const GEnumValue values[] = {
-			{ TRACKER_PROPERTY_TYPE_KEYWORD,
-			  "TRACKER_PROPERTY_TYPE_KEYWORD",
-			  "keyword" },
-			{ TRACKER_PROPERTY_TYPE_INDEX,
-			  "TRACKER_PROPERTY_TYPE_INDEX",
-			  "index" },
-			{ TRACKER_PROPERTY_TYPE_FULLTEXT,
-			  "TRACKER_PROPERTY_TYPE_FULLTEXT",
-			  "fulltext" },
 			{ TRACKER_PROPERTY_TYPE_STRING,
 			  "TRACKER_PROPERTY_TYPE_STRING",
 			  "string" },
+			{ TRACKER_PROPERTY_TYPE_BOOLEAN,
+			  "TRACKER_PROPERTY_TYPE_BOOLEAN",
+			  "boolean" },
 			{ TRACKER_PROPERTY_TYPE_INTEGER,
 			  "TRACKER_PROPERTY_TYPE_INTEGER",
 			  "integer" },
@@ -99,15 +103,21 @@ tracker_property_type_get_type (void)
 			{ TRACKER_PROPERTY_TYPE_DATE,
 			  "TRACKER_PROPERTY_TYPE_DATE",
 			  "date" },
+			{ TRACKER_PROPERTY_TYPE_DATETIME,
+			  "TRACKER_PROPERTY_TYPE_DATETIME",
+			  "datetime" },
 			{ TRACKER_PROPERTY_TYPE_BLOB,
 			  "TRACKER_PROPERTY_TYPE_BLOB",
 			  "blob" },
 			{ TRACKER_PROPERTY_TYPE_STRUCT,
 			  "TRACKER_PROPERTY_TYPE_STRUCT",
 			  "struct" },
-			{ TRACKER_PROPERTY_TYPE_LINK,
-			  "TRACKER_PROPERTY_TYPE_LINK",
-			  "link" },
+			{ TRACKER_PROPERTY_TYPE_RESOURCE,
+			  "TRACKER_PROPERTY_TYPE_RESOURCE",
+			  "resource" },
+			{ TRACKER_PROPERTY_TYPE_FULLTEXT,
+			  "TRACKER_PROPERTY_TYPE_FULLTEXT",
+			  "fulltext" },
 			{ 0, NULL, NULL }
 		};
 
@@ -147,10 +157,10 @@ tracker_property_class_init (TrackerPropertyClass *klass)
 	object_class->set_property = property_set_property;
 
 	g_object_class_install_property (object_class,
-					 PROP_ID,
-					 g_param_spec_string ("id",
-							      "id",
-							      "Unique identifier for this field",
+					 PROP_URI,
+					 g_param_spec_string ("uri",
+							      "uri",
+							      "URI",
 							      NULL,
 							      G_PARAM_READWRITE));
 	g_object_class_install_property (object_class,
@@ -159,21 +169,28 @@ tracker_property_class_init (TrackerPropertyClass *klass)
 							      "name",
 							      "Field name",
 							      NULL,
-							      G_PARAM_READWRITE));
+							      G_PARAM_READABLE));
 	g_object_class_install_property (object_class,
 					 PROP_DATA_TYPE,
 					 g_param_spec_enum ("data-type",
 							    "data-type",
 							    "Field data type",
 							    tracker_property_type_get_type (),
-							    TRACKER_PROPERTY_TYPE_INDEX,
+							    TRACKER_PROPERTY_TYPE_STRING,
 							    G_PARAM_READWRITE));
 	g_object_class_install_property (object_class,
-					 PROP_FIELD_NAME,
-					 g_param_spec_string ("field-name",
-							      "field-name",
-							      "Column in services table with the contents of this metadata",
-							      NULL,
+					 PROP_DOMAIN,
+					 g_param_spec_object ("domain",
+							      "domain",
+							      "Domain of this property",
+							      TRACKER_TYPE_CLASS,
+							      G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_RANGE,
+					 g_param_spec_object ("range",
+							      "range",
+							      "Range of this property",
+							      TRACKER_TYPE_CLASS,
 							      G_PARAM_READWRITE));
 	g_object_class_install_property (object_class,
 					 PROP_WEIGHT,
@@ -182,9 +199,23 @@ tracker_property_class_init (TrackerPropertyClass *klass)
 							   "Boost to the score",
 							   0,
 							   G_MAXINT,
-							   0,
+							   1,
 							   G_PARAM_READWRITE));
 	g_object_class_install_property (object_class,
+					 PROP_INDEXED,
+					 g_param_spec_boolean ("indexed",
+							       "indexed",
+							       "Indexed",
+							       TRUE,
+							       G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_FULLTEXT_INDEXED,
+					 g_param_spec_boolean ("fulltext-indexed",
+							       "fulltext-indexed",
+							       "Full-text indexed",
+							       TRUE,
+							       G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
 					 PROP_EMBEDDED,
 					 g_param_spec_boolean ("embedded",
 							       "embedded",
@@ -199,32 +230,11 @@ tracker_property_class_init (TrackerPropertyClass *klass)
 							       TRUE,
 							       G_PARAM_READWRITE));
 	g_object_class_install_property (object_class,
-					 PROP_DELIMITED,
-					 g_param_spec_boolean ("delimited",
-							       "delimited",
-							       "Delimited",
-							       FALSE,
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
 					 PROP_FILTERED,
 					 g_param_spec_boolean ("filtered",
 							       "filtered",
 							       "Filtered",
-							       FALSE,
-							       G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_STORE_METADATA,
-					 g_param_spec_boolean ("store-metadata",
-							       "store-metadata",
-							       "Store metadata",
-							       FALSE,
-							       G_PARAM_READWRITE));
-
-	g_object_class_install_property (object_class,
-					 PROP_CHILD_IDS,
-					 g_param_spec_pointer ("child-ids",
-							       "child-ids",
-							       "Child ids",
+							       TRUE,
 							       G_PARAM_READWRITE));
 
 	g_type_class_add_private (object_class, sizeof (TrackerPropertyPriv));
@@ -233,6 +243,15 @@ tracker_property_class_init (TrackerPropertyClass *klass)
 static void
 tracker_property_init (TrackerProperty *field)
 {
+	TrackerPropertyPriv *priv;
+
+	priv = GET_PRIV (field);
+
+	priv->weight = 1;
+	priv->embedded = TRUE;
+	priv->filtered = TRUE;
+	priv->multiple_values = TRUE;
+	priv->super_properties = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
 }
 
 static void
@@ -242,15 +261,10 @@ property_finalize (GObject *object)
 
 	priv = GET_PRIV (object);
 
-	g_free (priv->id);
+	g_free (priv->uri);
 	g_free (priv->name);
 
-	if (priv->field_name) {
-		g_free (priv->field_name);
-	}
-
-	g_slist_foreach (priv->child_ids, (GFunc) g_free, NULL);
-	g_slist_free (priv->child_ids);
+	g_array_free (priv->super_properties, TRUE);
 
 	(G_OBJECT_CLASS (tracker_property_parent_class)->finalize) (object);
 }
@@ -266,8 +280,8 @@ property_get_property (GObject    *object,
 	priv = GET_PRIV (object);
 
 	switch (param_id) {
-	case PROP_ID:
-		g_value_set_string (value, priv->id);
+	case PROP_URI:
+		g_value_set_string (value, priv->uri);
 		break;
 	case PROP_NAME:
 		g_value_set_string (value, priv->name);
@@ -275,30 +289,30 @@ property_get_property (GObject    *object,
 	case PROP_DATA_TYPE:
 		g_value_set_enum (value, priv->data_type);
 		break;
-	case PROP_FIELD_NAME:
-		g_value_set_string (value, priv->field_name);
+	case PROP_DOMAIN:
+		g_value_set_object (value, priv->domain);
+		break;
+	case PROP_RANGE:
+		g_value_set_object (value, priv->range);
 		break;
 	case PROP_WEIGHT:
 		g_value_set_int (value, priv->weight);
 		break;
+	case PROP_INDEXED:
+		g_value_set_boolean (value, priv->indexed);
+		break;
+	case PROP_FULLTEXT_INDEXED:
+		g_value_set_boolean (value, priv->fulltext_indexed);
+		break;
 	case PROP_EMBEDDED:
 		g_value_set_boolean (value, priv->embedded);
 		break;
 	case PROP_MULTIPLE_VALUES:
 		g_value_set_boolean (value, priv->multiple_values);
 		break;
-	case PROP_DELIMITED:
-		g_value_set_boolean (value, priv->delimited);
-		break;
 	case PROP_FILTERED:
 		g_value_set_boolean (value, priv->filtered);
 		break;
-	case PROP_STORE_METADATA:
-		g_value_set_boolean (value, priv->store_metadata);
-		break;
-	case PROP_CHILD_IDS:
-		g_value_set_pointer (value, priv->child_ids);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -312,26 +326,34 @@ property_set_property (GObject	 *object,
 		    GParamSpec	 *pspec)
 {
 	switch (param_id) {
-	case PROP_ID:
-		tracker_property_set_id (TRACKER_PROPERTY (object),
-				      g_value_get_string (value));
-		break;
-	case PROP_NAME:
-		tracker_property_set_name (TRACKER_PROPERTY (object),
-					g_value_get_string (value));
+	case PROP_URI:
+		tracker_property_set_uri (TRACKER_PROPERTY (object),
+				       g_value_get_string (value));
 		break;
 	case PROP_DATA_TYPE:
 		tracker_property_set_data_type (TRACKER_PROPERTY (object),
 					     g_value_get_enum (value));
 		break;
-	case PROP_FIELD_NAME:
-		tracker_property_set_field_name (TRACKER_PROPERTY (object),
-					      g_value_get_string (value));
+	case PROP_DOMAIN:
+		tracker_property_set_domain (TRACKER_PROPERTY (object),
+					   g_value_get_object (value));
+		break;
+	case PROP_RANGE:
+		tracker_property_set_range (TRACKER_PROPERTY (object),
+					   g_value_get_object (value));
 		break;
 	case PROP_WEIGHT:
 		tracker_property_set_weight (TRACKER_PROPERTY (object),
 					  g_value_get_int (value));
 		break;
+	case PROP_INDEXED:
+		tracker_property_set_indexed (TRACKER_PROPERTY (object),
+					   g_value_get_boolean (value));
+		break;
+	case PROP_FULLTEXT_INDEXED:
+		tracker_property_set_fulltext_indexed (TRACKER_PROPERTY (object),
+						    g_value_get_boolean (value));
+		break;
 	case PROP_EMBEDDED:
 		tracker_property_set_embedded (TRACKER_PROPERTY (object),
 					    g_value_get_boolean (value));
@@ -340,22 +362,10 @@ property_set_property (GObject	 *object,
 		tracker_property_set_multiple_values (TRACKER_PROPERTY (object),
 						   g_value_get_boolean (value));
 		break;
-	case PROP_DELIMITED:
-		tracker_property_set_delimited (TRACKER_PROPERTY (object),
-					     g_value_get_boolean (value));
-		break;
 	case PROP_FILTERED:
 		tracker_property_set_filtered (TRACKER_PROPERTY (object),
 					    g_value_get_boolean (value));
 		break;
-	case PROP_STORE_METADATA:
-		tracker_property_set_store_metadata (TRACKER_PROPERTY (object),
-						  g_value_get_boolean (value));
-		break;
-	case PROP_CHILD_IDS:
-		tracker_property_set_child_ids (TRACKER_PROPERTY (object),
-					     g_value_get_pointer (value));
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -404,7 +414,7 @@ tracker_property_new (void)
 }
 
 const gchar *
-tracker_property_get_id (TrackerProperty *field)
+tracker_property_get_uri (TrackerProperty *field)
 {
 	TrackerPropertyPriv *priv;
 
@@ -412,7 +422,7 @@ tracker_property_get_id (TrackerProperty *field)
 
 	priv = GET_PRIV (field);
 
-	return priv->id;
+	return priv->uri;
 }
 
 const gchar *
@@ -439,8 +449,8 @@ tracker_property_get_data_type (TrackerProperty *field)
 	return priv->data_type;
 }
 
-const gchar *
-tracker_property_get_field_name (TrackerProperty *field)
+TrackerClass *
+tracker_property_get_domain (TrackerProperty *field)
 {
 	TrackerPropertyPriv *priv;
 
@@ -448,7 +458,19 @@ tracker_property_get_field_name (TrackerProperty *field)
 
 	priv = GET_PRIV (field);
 
-	return priv->field_name;
+	return priv->domain;
+}
+
+TrackerClass *
+tracker_property_get_range (TrackerProperty *field)
+{
+	TrackerPropertyPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_PROPERTY (field), NULL);
+
+	priv = GET_PRIV (field);
+
+	return priv->range;
 }
 
 gint
@@ -465,7 +487,7 @@ tracker_property_get_weight (TrackerProperty *field)
 
 
 gboolean
-tracker_property_get_embedded (TrackerProperty *field)
+tracker_property_get_indexed (TrackerProperty *field)
 {
 	TrackerPropertyPriv *priv;
 
@@ -473,12 +495,12 @@ tracker_property_get_embedded (TrackerProperty *field)
 
 	priv = GET_PRIV (field);
 
-	return priv->embedded;
+	return priv->indexed;
 }
 
 
 gboolean
-tracker_property_get_multiple_values (TrackerProperty *field)
+tracker_property_get_fulltext_indexed (TrackerProperty *field)
 {
 	TrackerPropertyPriv *priv;
 
@@ -486,11 +508,12 @@ tracker_property_get_multiple_values (TrackerProperty *field)
 
 	priv = GET_PRIV (field);
 
-	return priv->multiple_values;
+	return priv->fulltext_indexed;
 }
 
+
 gboolean
-tracker_property_get_delimited (TrackerProperty *field)
+tracker_property_get_embedded (TrackerProperty *field)
 {
 	TrackerPropertyPriv *priv;
 
@@ -498,11 +521,12 @@ tracker_property_get_delimited (TrackerProperty *field)
 
 	priv = GET_PRIV (field);
 
-	return priv->delimited;
+	return priv->embedded;
 }
 
+
 gboolean
-tracker_property_get_filtered (TrackerProperty *field)
+tracker_property_get_multiple_values (TrackerProperty *field)
 {
 	TrackerPropertyPriv *priv;
 
@@ -510,11 +534,11 @@ tracker_property_get_filtered (TrackerProperty *field)
 
 	priv = GET_PRIV (field);
 
-	return priv->filtered;
+	return priv->multiple_values;
 }
 
 gboolean
-tracker_property_get_store_metadata (TrackerProperty *field)
+tracker_property_get_filtered (TrackerProperty *field)
 {
 	TrackerPropertyPriv *priv;
 
@@ -522,26 +546,24 @@ tracker_property_get_store_metadata (TrackerProperty *field)
 
 	priv = GET_PRIV (field);
 
-	return priv->store_metadata;
+	return priv->filtered;
 }
 
-
-const GSList *
-tracker_property_get_child_ids (TrackerProperty *field)
+TrackerProperty **
+tracker_property_get_super_properties (TrackerProperty *property)
 {
 	TrackerPropertyPriv *priv;
 
-	g_return_val_if_fail (TRACKER_IS_PROPERTY (field), NULL);
+	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
 
-	priv = GET_PRIV (field);
+	priv = GET_PRIV (property);
 
-	return priv->child_ids;
+	return (TrackerProperty **) priv->super_properties->data;
 }
 
-
 void
-tracker_property_set_id (TrackerProperty *field,
-		      const gchar  *value)
+tracker_property_set_uri (TrackerProperty *field,
+		       const gchar  *value)
 {
 	TrackerPropertyPriv *priv;
 
@@ -549,20 +571,42 @@ tracker_property_set_id (TrackerProperty *field,
 
 	priv = GET_PRIV (field);
 
-	g_free (priv->id);
+	g_free (priv->uri);
+	g_free (priv->name);
+	priv->uri = NULL;
+	priv->name = NULL;
 
 	if (value) {
-		priv->id = g_strdup (value);
-	} else {
-		priv->id = NULL;
+		gchar *namespace_uri, *hash;
+		TrackerNamespace *namespace;
+
+		priv->uri = g_strdup (value);
+
+		hash = strrchr (priv->uri, '#');
+		if (hash == NULL) {
+			/* support ontologies whose namespace uri does not end in a hash, e.g. dc */
+			hash = strrchr (priv->uri, '/');
+		}
+		if (hash == NULL) {
+			g_critical ("Unknown namespace of property %s", priv->uri);
+		} else {
+			namespace_uri = g_strndup (priv->uri, hash - priv->uri + 1);
+			namespace = tracker_ontology_get_namespace_by_uri (namespace_uri);
+			if (namespace == NULL) {
+				g_critical ("Unknown namespace %s of property %s", namespace_uri, priv->uri);
+			} else {
+				priv->name = g_strdup_printf ("%s:%s", tracker_namespace_get_prefix (namespace), hash + 1);
+			}
+			g_free (namespace_uri);
+		}
 	}
 
-	g_object_notify (G_OBJECT (field), "id");
+	g_object_notify (G_OBJECT (field), "uri");
 }
 
 void
-tracker_property_set_name (TrackerProperty *field,
-			const gchar  *value)
+tracker_property_set_data_type (TrackerProperty     *field,
+			     TrackerPropertyType  value)
 {
 	TrackerPropertyPriv *priv;
 
@@ -570,20 +614,13 @@ tracker_property_set_name (TrackerProperty *field,
 
 	priv = GET_PRIV (field);
 
-	g_free (priv->name);
-
-	if (value) {
-		priv->name = g_strdup (value);
-	} else {
-		priv->name = NULL;
-	}
-
-	g_object_notify (G_OBJECT (field), "name");
+	priv->data_type = value;
+	g_object_notify (G_OBJECT (field), "data-type");
 }
 
 void
-tracker_property_set_data_type (TrackerProperty     *field,
-			     TrackerPropertyType  value)
+tracker_property_set_domain (TrackerProperty   *field,
+			   TrackerClass *value)
 {
 	TrackerPropertyPriv *priv;
 
@@ -591,29 +628,54 @@ tracker_property_set_data_type (TrackerProperty     *field,
 
 	priv = GET_PRIV (field);
 
-	priv->data_type = value;
-	g_object_notify (G_OBJECT (field), "data-type");
+	if (priv->domain) {
+		g_object_unref (priv->domain);
+		priv->domain = NULL;
+	}
+
+	if (value) {
+		priv->domain = g_object_ref (value);
+	}
+
+	g_object_notify (G_OBJECT (field), "domain");
 }
 
 void
-tracker_property_set_field_name (TrackerProperty *field,
-			      const gchar    *value)
+tracker_property_set_range (TrackerProperty   *property,
+			   TrackerClass *value)
 {
 	TrackerPropertyPriv *priv;
+	const gchar         *range_uri;
 
-	g_return_if_fail (TRACKER_IS_PROPERTY (field));
+	g_return_if_fail (TRACKER_IS_PROPERTY (property));
+	g_return_if_fail (TRACKER_IS_CLASS (value));
 
-	priv = GET_PRIV (field);
+	priv = GET_PRIV (property);
 
-	g_free (priv->field_name);
+	if (priv->range) {
+		g_object_unref (priv->range);
+	}
 
-	if (value) {
-		priv->field_name = g_strdup (value);
+	priv->range = g_object_ref (value);
+
+	range_uri = tracker_class_get_uri (priv->range);
+	if (strcmp (range_uri, XSD_STRING) == 0) {
+		priv->data_type = TRACKER_PROPERTY_TYPE_STRING;
+	} else if (strcmp (range_uri, XSD_BOOLEAN) == 0) {
+		priv->data_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
+	} else if (strcmp (range_uri, XSD_INTEGER) == 0) {
+		priv->data_type = TRACKER_PROPERTY_TYPE_INTEGER;
+	} else if (strcmp (range_uri, XSD_DOUBLE) == 0) {
+		priv->data_type = TRACKER_PROPERTY_TYPE_DOUBLE;
+	} else if (strcmp (range_uri, XSD_DATE) == 0) {
+		priv->data_type = TRACKER_PROPERTY_TYPE_DATE;
+	} else if (strcmp (range_uri, XSD_DATETIME) == 0) {
+		priv->data_type = TRACKER_PROPERTY_TYPE_DATETIME;
 	} else {
-		priv->field_name = NULL;
+		priv->data_type = TRACKER_PROPERTY_TYPE_RESOURCE;
 	}
 
-	g_object_notify (G_OBJECT (field), "field-name");
+	g_object_notify (G_OBJECT (property), "range");
 }
 
 void
@@ -634,8 +696,8 @@ tracker_property_set_weight (TrackerProperty *field,
 }
 
 void
-tracker_property_set_embedded (TrackerProperty *field,
-			    gboolean	  value)
+tracker_property_set_indexed (TrackerProperty *field,
+			   gboolean	  value)
 {
 	TrackerPropertyPriv *priv;
 
@@ -643,13 +705,13 @@ tracker_property_set_embedded (TrackerProperty *field,
 
 	priv = GET_PRIV (field);
 
-	priv->embedded = value;
-	g_object_notify (G_OBJECT (field), "embedded");
+	priv->indexed = value;
+	g_object_notify (G_OBJECT (field), "indexed");
 }
 
 void
-tracker_property_set_multiple_values (TrackerProperty *field,
-				   gboolean	 value)
+tracker_property_set_fulltext_indexed (TrackerProperty *field,
+				    gboolean	  value)
 {
 	TrackerPropertyPriv *priv;
 
@@ -657,13 +719,13 @@ tracker_property_set_multiple_values (TrackerProperty *field,
 
 	priv = GET_PRIV (field);
 
-	priv->multiple_values = value;
-	g_object_notify (G_OBJECT (field), "multiple-values");
+	priv->fulltext_indexed = value;
+	g_object_notify (G_OBJECT (field), "fulltext-indexed");
 }
 
 void
-tracker_property_set_delimited (TrackerProperty *field,
-			     gboolean	   value)
+tracker_property_set_embedded (TrackerProperty *field,
+			    gboolean	  value)
 {
 	TrackerPropertyPriv *priv;
 
@@ -671,13 +733,13 @@ tracker_property_set_delimited (TrackerProperty *field,
 
 	priv = GET_PRIV (field);
 
-	priv->delimited = value;
-	g_object_notify (G_OBJECT (field), "delimited");
+	priv->embedded = value;
+	g_object_notify (G_OBJECT (field), "embedded");
 }
 
 void
-tracker_property_set_filtered (TrackerProperty *field,
-			    gboolean	  value)
+tracker_property_set_multiple_values (TrackerProperty *field,
+				   gboolean	 value)
 {
 	TrackerPropertyPriv *priv;
 
@@ -685,13 +747,13 @@ tracker_property_set_filtered (TrackerProperty *field,
 
 	priv = GET_PRIV (field);
 
-	priv->filtered = value;
-	g_object_notify (G_OBJECT (field), "filtered");
+	priv->multiple_values = value;
+	g_object_notify (G_OBJECT (field), "multiple-values");
 }
 
 void
-tracker_property_set_store_metadata (TrackerProperty *field,
-				  gboolean	value)
+tracker_property_set_filtered (TrackerProperty *field,
+			    gboolean	  value)
 {
 	TrackerPropertyPriv *priv;
 
@@ -699,55 +761,40 @@ tracker_property_set_store_metadata (TrackerProperty *field,
 
 	priv = GET_PRIV (field);
 
-	priv->store_metadata = value;
-	g_object_notify (G_OBJECT (field), "store-metadata");
+	priv->filtered = value;
+	g_object_notify (G_OBJECT (field), "filtered");
 }
 
 void
-tracker_property_set_child_ids (TrackerProperty *field,
-			     const GSList *value)
+tracker_property_set_super_properties (TrackerProperty *property,
+			         TrackerProperty **value)
 {
 	TrackerPropertyPriv *priv;
+	TrackerProperty     **super_property;
 
-	g_return_if_fail (TRACKER_IS_PROPERTY (field));
-
-	priv = GET_PRIV (field);
+	g_return_if_fail (TRACKER_IS_PROPERTY (property));
 
-	g_slist_foreach (priv->child_ids, (GFunc) g_free, NULL);
-	g_slist_free (priv->child_ids);
+	priv = GET_PRIV (property);
 
-	if (value) {
-		GSList	     *new_list;
-		const GSList *l;
-
-		new_list = NULL;
-
-		for (l = value; l; l = l->next) {
-			new_list = g_slist_prepend (new_list, g_strdup (l->data));
-		}
+	g_array_free (priv->super_properties, TRUE);
 
-		new_list = g_slist_reverse (new_list);
-		priv->child_ids = new_list;
-	} else {
-		priv->child_ids = NULL;
+	priv->super_properties = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
+	for (super_property = value; *super_property; super_property++) {
+		g_array_append_val (priv->super_properties, *super_property);
 	}
-
-	g_object_notify (G_OBJECT (field), "child-ids");
 }
 
 void
-tracker_property_append_child_id (TrackerProperty *field,
-			       const gchar  *value)
+tracker_property_add_super_property (TrackerProperty *property,
+			         TrackerProperty *value)
 {
 	TrackerPropertyPriv *priv;
 
-	g_return_if_fail (TRACKER_IS_PROPERTY (field));
-
-	priv = GET_PRIV (field);
+	g_return_if_fail (TRACKER_IS_PROPERTY (property));
+	g_return_if_fail (TRACKER_IS_PROPERTY (value));
 
-	if (value) {
-		priv->child_ids = g_slist_append (priv->child_ids, g_strdup (value));
-	}
+	priv = GET_PRIV (property);
 
-	g_object_notify (G_OBJECT (field), "child-ids");
+	g_array_append_val (priv->super_properties, value);
 }
+
diff --git a/src/libtracker-common/tracker-property.h b/src/libtracker-common/tracker-property.h
index 22f5688..82a3230 100644
--- a/src/libtracker-common/tracker-property.h
+++ b/src/libtracker-common/tracker-property.h
@@ -24,6 +24,8 @@
 
 #include <glib-object.h>
 
+#include "tracker-class.h"
+
 G_BEGIN_DECLS
 
 #if !defined (__LIBTRACKER_COMMON_INSIDE__) && !defined (TRACKER_COMPILATION)
@@ -33,16 +35,18 @@ G_BEGIN_DECLS
 #define TRACKER_TYPE_PROPERTY_TYPE (tracker_property_type_get_type ())
 
 typedef enum {
-	TRACKER_PROPERTY_TYPE_KEYWORD,
-	TRACKER_PROPERTY_TYPE_INDEX,
-	TRACKER_PROPERTY_TYPE_FULLTEXT,
+	/* metadata */
 	TRACKER_PROPERTY_TYPE_STRING,
+	TRACKER_PROPERTY_TYPE_BOOLEAN,
 	TRACKER_PROPERTY_TYPE_INTEGER,
 	TRACKER_PROPERTY_TYPE_DOUBLE,
 	TRACKER_PROPERTY_TYPE_DATE,
+	TRACKER_PROPERTY_TYPE_DATETIME,
 	TRACKER_PROPERTY_TYPE_BLOB,
 	TRACKER_PROPERTY_TYPE_STRUCT,
-	TRACKER_PROPERTY_TYPE_LINK,
+	TRACKER_PROPERTY_TYPE_RESOURCE,
+	/* content */
+	TRACKER_PROPERTY_TYPE_FULLTEXT,
 } TrackerPropertyType;
 
 GType	     tracker_property_type_get_type  (void) G_GNUC_CONST;
@@ -73,42 +77,43 @@ GType		 tracker_property_get_type		   (void) G_GNUC_CONST;
 
 TrackerProperty *	 tracker_property_new		   (void);
 
-const gchar *	 tracker_property_get_id		   (TrackerProperty     *field);
-const gchar *	 tracker_property_get_name		   (TrackerProperty     *field);
-TrackerPropertyType tracker_property_get_data_type	   (TrackerProperty     *field);
-const gchar *	 tracker_property_get_field_name	   (TrackerProperty     *field);
-gint		 tracker_property_get_weight	   (TrackerProperty     *service);
-gboolean	 tracker_property_get_embedded	   (TrackerProperty     *field);
-gboolean	 tracker_property_get_multiple_values (TrackerProperty     *field);
-gboolean	 tracker_property_get_delimited	   (TrackerProperty     *field);
-gboolean	 tracker_property_get_filtered	   (TrackerProperty     *field);
-gboolean	 tracker_property_get_store_metadata  (TrackerProperty     *field);
-const GSList *	 tracker_property_get_child_ids	   (TrackerProperty     *field);
-
-void		 tracker_property_set_id		   (TrackerProperty     *field,
+const gchar *	 tracker_property_get_uri		   (TrackerProperty     *property);
+const gchar *	 tracker_property_get_name		   (TrackerProperty     *property);
+TrackerPropertyType tracker_property_get_data_type	   (TrackerProperty     *property);
+TrackerClass *	 tracker_property_get_domain	   (TrackerProperty     *property);
+TrackerClass *	 tracker_property_get_range	   (TrackerProperty     *property);
+gint		 tracker_property_get_weight	   (TrackerProperty     *property);
+gboolean	 tracker_property_get_indexed	   (TrackerProperty     *property);
+gboolean	 tracker_property_get_fulltext_indexed(TrackerProperty     *property);
+gboolean	 tracker_property_get_embedded	   (TrackerProperty     *property);
+gboolean	 tracker_property_get_multiple_values (TrackerProperty     *property);
+gboolean	 tracker_property_get_filtered	   (TrackerProperty     *property);
+TrackerProperty **tracker_property_get_super_properties	     (TrackerProperty *property);
+
+void		 tracker_property_set_uri		   (TrackerProperty     *property,
 						    const gchar      *value);
-void		 tracker_property_set_name		   (TrackerProperty     *field,
-						    const gchar      *value);
-void		 tracker_property_set_data_type	   (TrackerProperty     *field,
+void		 tracker_property_set_data_type	   (TrackerProperty     *property,
 						    TrackerPropertyType  value);
-void		 tracker_property_set_field_name	   (TrackerProperty     *field,
-						    const gchar      *value);
-void		 tracker_property_set_weight	   (TrackerProperty     *field,
+void		 tracker_property_set_domain	   (TrackerProperty     *property,
+						    TrackerClass     *value);
+void		 tracker_property_set_range	   (TrackerProperty     *property,
+						    TrackerClass     *range);
+void		 tracker_property_set_weight	   (TrackerProperty     *property,
 						    gint	      value);
-void		 tracker_property_set_embedded	   (TrackerProperty     *field,
+void		 tracker_property_set_indexed	   (TrackerProperty     *property,
 						    gboolean	      value);
-void		 tracker_property_set_multiple_values (TrackerProperty     *field,
+void		 tracker_property_set_fulltext_indexed(TrackerProperty     *property,
 						    gboolean	      value);
-void		 tracker_property_set_delimited	   (TrackerProperty     *field,
+void		 tracker_property_set_embedded	   (TrackerProperty     *property,
 						    gboolean	      value);
-void		 tracker_property_set_filtered	   (TrackerProperty     *field,
+void		 tracker_property_set_multiple_values (TrackerProperty     *property,
 						    gboolean	      value);
-void		 tracker_property_set_store_metadata  (TrackerProperty     *field,
+void		 tracker_property_set_filtered	   (TrackerProperty     *property,
 						    gboolean	      value);
-void		 tracker_property_set_child_ids	   (TrackerProperty     *field,
-						    const GSList     *value);
-void		 tracker_property_append_child_id	   (TrackerProperty     *field,
-						    const gchar      *id);
+void             tracker_property_set_super_properties		(TrackerProperty  *property,
+								 TrackerProperty **super_properties);
+void             tracker_property_add_super_property		(TrackerProperty  *property,
+								 TrackerProperty  *value);
 
 G_END_DECLS
 
diff --git a/src/libtracker-common/tracker-statement-list.c b/src/libtracker-common/tracker-statement-list.c
new file mode 100644
index 0000000..7b7ce30
--- /dev/null
+++ b/src/libtracker-common/tracker-statement-list.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008, Nokia
+ *
+ * This program 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 program 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 program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ *  tracker_uri_vprintf_escaped, tracker_uri_printf_escaped got copied from 
+ *  GLib's gmarkup.c
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libtracker-common/tracker-statement-list.h>
+
+
+const gchar*
+tracker_statement_list_find (GPtrArray *statements, 
+                        const gchar *subj, 
+                        const gchar *pred)
+{
+	guint i;
+	const gchar *subject;
+	const gchar *predicate;
+	const gchar *object = NULL;
+
+	for (i = 0; i < statements->len; i++) {
+		GValueArray *statement;
+
+		statement = statements->pdata[i];
+
+		subject = g_value_get_string (&statement->values[0]);
+		predicate = g_value_get_string (&statement->values[1]);
+		object = g_value_get_string (&statement->values[2]);
+
+		if (g_strcmp0 (pred, predicate) == 0 && g_strcmp0 (subj, subject) == 0)
+			break;
+	}
+
+	return object;
+}
+
+void
+tracker_statement_list_insert (GPtrArray   *statements, 
+                          const gchar *subject,
+                          const gchar *predicate,
+                          const gchar *value)
+{
+	GValueArray *statement;
+	GValue       gvalue = { 0 };
+
+	statement = g_value_array_new (3);
+
+	g_value_init (&gvalue, G_TYPE_STRING);
+	g_value_set_string (&gvalue, subject);
+	g_value_array_append (statement, &gvalue);
+	g_value_unset (&gvalue);
+
+	g_value_init (&gvalue, G_TYPE_STRING);
+	g_value_set_string (&gvalue, predicate);
+	g_value_array_append (statement, &gvalue);
+	g_value_unset (&gvalue);
+
+	g_value_init (&gvalue, G_TYPE_STRING);
+	g_value_set_string (&gvalue, value);
+	g_value_array_append (statement, &gvalue);
+	g_value_unset (&gvalue);
+
+	g_ptr_array_add (statements, statement);
+}
+
+
+void
+tracker_statement_list_insert_with_int64 (GPtrArray   *statements,
+                                     const gchar *subject,
+                                     const gchar *predicate,
+                                     gint64       value)
+{
+	gchar *value_str;
+
+	value_str = g_strdup_printf ("%" G_GINT64_FORMAT, value);
+	tracker_statement_list_insert (statements, subject, predicate, value_str);
+	g_free (value_str);
+}
+
+
+void
+tracker_statement_list_insert_with_double  (GPtrArray   *statements,
+                                       const gchar *subject,
+                                       const gchar *predicate,
+                                       gdouble      value)
+{
+	gchar *value_str;
+
+	value_str = g_strdup_printf ("%g", value);
+	tracker_statement_list_insert (statements, subject, predicate, value_str);
+	g_free (value_str);
+}
+
+void
+tracker_statement_list_insert_with_int (GPtrArray   *statements,
+                                   const gchar *subject,
+                                   const gchar *predicate,
+                                   gint         value)
+{
+	gchar *value_str;
+
+	value_str = g_strdup_printf ("%d", value);
+	tracker_statement_list_insert (statements, subject, predicate, value_str);
+	g_free (value_str);
+}
+
diff --git a/src/libtracker-common/tracker-statement-list.h b/src/libtracker-common/tracker-statement-list.h
new file mode 100644
index 0000000..a3fa4ff
--- /dev/null
+++ b/src/libtracker-common/tracker-statement-list.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008, Nokia
+ *
+ * This program 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 program 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 program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __TRACKER_STATEMENT_H__
+#define __TRACKER_STATEMENT_H__
+
+#include <glib.h>
+
+#define SHOULD_VALIDATE_UTF8
+
+G_BEGIN_DECLS
+
+void   tracker_statement_list_insert             (GPtrArray   *statements, 
+                                             const gchar *subject,
+                                             const gchar *predicate,
+                                             const gchar *value);
+void   tracker_statement_list_insert_with_int    (GPtrArray   *statements,
+                                             const gchar *subject,
+                                             const gchar *predicate,
+                                             gint         value);
+void   tracker_statement_list_insert_with_int64  (GPtrArray   *statements,
+                                             const gchar *subject,
+                                             const gchar *predicate,
+                                             gint64       value);
+void   tracker_statement_list_insert_with_double (GPtrArray   *statements,
+                                             const gchar *subject,
+                                             const gchar *predicate,
+                                             gdouble      value);
+const gchar* tracker_statement_list_find         (GPtrArray *statements, 
+                                             const gchar *subj, 
+                                             const gchar *pred);
+
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_ESCAPE_H__ */
diff --git a/src/libtracker-common/tracker-thumbnailer.c b/src/libtracker-common/tracker-thumbnailer.c
index d8a1e3c..68c8173 100644
--- a/src/libtracker-common/tracker-thumbnailer.c
+++ b/src/libtracker-common/tracker-thumbnailer.c
@@ -23,8 +23,6 @@
 
 #include <string.h>
 
-#include <libtracker-data/tracker-data-metadata.h>
-
 #include <tracker-indexer/tracker-module-file.h>
 
 #include "tracker-config.h"
diff --git a/src/libtracker-common/tracker-utils.c b/src/libtracker-common/tracker-utils.c
index aa36ecc..b7e1377 100644
--- a/src/libtracker-common/tracker-utils.c
+++ b/src/libtracker-common/tracker-utils.c
@@ -108,7 +108,7 @@ tracker_escape_string (const gchar *in)
 	gchar **array, *out;
 
 	if (!in) {
-		return NULL;
+		return g_strdup ("");
 	}
 
 	if (!strchr (in, '\'')) {
@@ -305,3 +305,222 @@ tracker_dngettext (const gchar *domain,
 
   return dngettext (domain, msgid, msgid_plural, n);
 }
+
+
+static const char *
+find_conversion (const char  *format,
+                 const char **after)
+{
+  const char *start = format;
+  const char *cp;
+
+  while (*start != '\0' && *start != '%')
+    start++;
+
+  if (*start == '\0')
+    {
+      *after = start;
+      return NULL;
+    }
+
+  cp = start + 1;
+
+  if (*cp == '\0')
+    {
+      *after = cp;
+      return NULL;
+    }
+
+  /* Test for positional argument.  */
+  if (*cp >= '0' && *cp <= '9')
+    {
+      const char *np;
+
+      for (np = cp; *np >= '0' && *np <= '9'; np++)
+        ;
+      if (*np == '$')
+        cp = np + 1;
+    }
+
+  /* Skip the flags.  */
+  for (;;)
+    {
+      if (*cp == '\'' ||
+          *cp == '-' ||
+          *cp == '+' ||
+          *cp == ' ' ||
+          *cp == '#' ||
+          *cp == '0')
+        cp++;
+      else
+        break;
+    }
+
+  /* Skip the field width.  */
+  if (*cp == '*')
+    {
+      cp++;
+
+      /* Test for positional argument.  */
+      if (*cp >= '0' && *cp <= '9')
+        {
+          const char *np;
+
+          for (np = cp; *np >= '0' && *np <= '9'; np++)
+            ;
+          if (*np == '$')
+            cp = np + 1;
+        }
+    }
+  else
+    {
+      for (; *cp >= '0' && *cp <= '9'; cp++)
+        ;
+    }
+
+  /* Skip the precision.  */
+  if (*cp == '.')
+    {
+      cp++;
+      if (*cp == '*')
+        {
+          /* Test for positional argument.  */
+          if (*cp >= '0' && *cp <= '9')
+            {
+              const char *np;
+
+              for (np = cp; *np >= '0' && *np <= '9'; np++)
+                ;
+              if (*np == '$')
+                cp = np + 1;
+            }
+        }
+      else
+        {
+          for (; *cp >= '0' && *cp <= '9'; cp++)
+            ;
+        }
+    }
+
+  /* Skip argument type/size specifiers.  */
+  while (*cp == 'h' ||
+         *cp == 'L' ||
+         *cp == 'l' ||
+         *cp == 'j' ||
+         *cp == 'z' ||
+         *cp == 'Z' ||
+         *cp == 't')
+    cp++;
+
+  /* Skip the conversion character.  */
+  cp++;
+
+  *after = cp;
+  return start;
+}
+
+gchar *
+tracker_uri_vprintf_escaped (const gchar *format, 
+                             va_list      args)
+{
+  GString *format1;
+  GString *format2;
+  GString *result = NULL;
+  gchar *output1 = NULL;
+  gchar *output2 = NULL;
+  const char *p;
+  char       *op1, *op2;
+  va_list args2;
+
+  format1 = g_string_new (NULL);
+  format2 = g_string_new (NULL);
+  p = format;
+  while (TRUE)
+    {
+      const char *after;
+      const char *conv = find_conversion (p, &after);
+      if (!conv)
+        break;
+
+      g_string_append_len (format1, conv, after - conv);
+      g_string_append_c (format1, 'X');
+      g_string_append_len (format2, conv, after - conv);
+      g_string_append_c (format2, 'Y');
+
+      p = after;
+    }
+
+  /* Use them to format the arguments
+   */
+  G_VA_COPY (args2, args);
+
+  output1 = g_strdup_vprintf (format1->str, args);
+  va_end (args);
+  if (!output1)
+    goto cleanup;
+
+  output2 = g_strdup_vprintf (format2->str, args2);
+  va_end (args2);
+  if (!output2)
+    goto cleanup;
+
+  result = g_string_new (NULL);
+
+  op1 = output1;
+  op2 = output2;
+  p = format;
+  while (TRUE)
+    {
+      const char *after;
+      const char *output_start;
+      const char *conv = find_conversion (p, &after);
+      char *escaped;
+
+      if (!conv)
+        {
+          g_string_append_len (result, p, after - p);
+          break;
+        }
+
+      g_string_append_len (result, p, conv - p);
+      output_start = op1;
+      while (*op1 == *op2)
+        {
+          op1++;
+          op2++;
+        }
+
+      *op1 = '\0';
+      escaped = g_uri_escape_string (output_start, NULL, FALSE);
+      g_string_append (result, escaped);
+      g_free (escaped);
+
+      p = after;
+      op1++;
+      op2++;
+    }
+
+ cleanup:
+  g_string_free (format1, TRUE);
+  g_string_free (format2, TRUE);
+  g_free (output1);
+  g_free (output2);
+
+  if (result)
+    return g_string_free (result, FALSE);
+  else
+    return NULL;
+}
+
+gchar *
+tracker_uri_printf_escaped (const gchar *format, ...)
+{
+  char *result;
+  va_list args;
+
+  va_start (args, format);
+  result = tracker_uri_vprintf_escaped (format, args);
+  va_end (args);
+
+  return result;
+}
diff --git a/src/libtracker-common/tracker-utils.h b/src/libtracker-common/tracker-utils.h
index 51f2bf4..93b68ab 100644
--- a/src/libtracker-common/tracker-utils.h
+++ b/src/libtracker-common/tracker-utils.h
@@ -45,6 +45,11 @@ gchar *  tracker_seconds_to_string	    (gdouble	    seconds_elapsed,
 void	 tracker_throttle		    (TrackerConfig *config,
 					     gint	    multiplier);
 
+
+gchar* tracker_uri_vprintf_escaped (const gchar *format,
+                                    va_list      args);
+gchar* tracker_uri_printf_escaped (const gchar *format, ...);
+
 /* Temporary: Just here until we upgrade to GLib 2.18. */
 G_CONST_RETURN gchar *tracker_dngettext     (const gchar *domain,
 					     const gchar *msgid,
diff --git a/src/libtracker-data/Makefile.am b/src/libtracker-data/Makefile.am
index 2e5d3e1..caf61ad 100644
--- a/src/libtracker-data/Makefile.am
+++ b/src/libtracker-data/Makefile.am
@@ -18,22 +18,20 @@ libtracker_data_LTLIBRARIES = libtracker-data.la
 libtracker_data_la_SOURCES = 						\
 	tracker-data-backup.c						\
 	tracker-data-manager.c						\
-	tracker-data-metadata.c						\
 	tracker-data-query.c						\
 	tracker-data-search.c						\
 	tracker-data-update.c						\
 	tracker-query-tree.c						\
-	tracker-turtle.c						
+	tracker-turtle.c
 
 noinst_HEADERS =							\
 	tracker-data-backup.h						\
 	tracker-data-manager.h						\
-	tracker-data-metadata.h						\
 	tracker-data-query.h						\
 	tracker-data-search.h						\
 	tracker-data-update.h						\
 	tracker-query-tree.h						\
-	tracker-turtle.h						
+	tracker-turtle.h
 
 libtracker_data_la_LDFLAGS =						\
 	-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
diff --git a/src/libtracker-data/tracker-data-backup.c b/src/libtracker-data/tracker-data-backup.c
index e08e403..8af7108 100644
--- a/src/libtracker-data/tracker-data-backup.c
+++ b/src/libtracker-data/tracker-data-backup.c
@@ -44,7 +44,7 @@ static void
 extended_result_set_to_turtle (TrackerDBResultSet  *result_set,
 			       TurtleFile          *turtle_file)
 {
-	TrackerProperty *field;
+	TrackerProperty *field = NULL;
 	gboolean valid = TRUE;
 
 	while (valid) {
@@ -58,7 +58,10 @@ extended_result_set_to_turtle (TrackerDBResultSet  *result_set,
 					   3, &str,
 					   -1);
 
-		field = tracker_ontology_get_field_by_id (metadata_id);
+		/* TODO */
+#if 0
+		field = tracker_ontology_get_property_by_id (metadata_id);
+#endif
 
 		if (!field) {
 			g_critical ("Field id %d in database but not in tracker-ontology",
@@ -117,8 +120,11 @@ tracker_data_backup_save (const gchar  *turtle_filename,
 
 	g_message ("Saving metadata backup in turtle file");
 
+	/* TODO */
+#if 0
 	service = tracker_ontology_get_service_by_name ("Files");
 	data = tracker_data_query_backup_metadata (service);
+#endif
 
 	if (data) {
 		extended_result_set_to_turtle (data, turtle_file);
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 5fdf37b..dcfa4ec 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -35,6 +35,7 @@
 #include <libtracker-common/tracker-parser.h>
 #include <libtracker-common/tracker-type-utils.h>
 #include <libtracker-common/tracker-utils.h>
+#include <libtracker-common/tracker-ontology.h>
 
 #include <libtracker-db/tracker-db-index.h>
 #include <libtracker-db/tracker-db-interface-sqlite.h>
@@ -42,6 +43,24 @@
 #include <libtracker-db/tracker-db-manager.h>
 
 #include "tracker-data-manager.h"
+#include "tracker-data-update.h"
+#include "tracker-turtle.h"
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_PROPERTY RDF_PREFIX "Property"
+#define RDF_TYPE RDF_PREFIX "type"
+
+#define RDFS_PREFIX TRACKER_RDFS_PREFIX
+#define RDFS_CLASS RDFS_PREFIX "Class"
+#define RDFS_DOMAIN RDFS_PREFIX "domain"
+#define RDFS_RANGE RDFS_PREFIX "range"
+#define RDFS_SUB_CLASS_OF RDFS_PREFIX "subClassOf"
+#define RDFS_SUB_PROPERTY_OF RDFS_PREFIX "subPropertyOf"
+
+#define NRL_PREFIX TRACKER_NRL_PREFIX
+#define NRL_MAX_CARDINALITY NRL_PREFIX "maxCardinality"
+
+#define TRACKER_PREFIX TRACKER_TRACKER_PREFIX
 
 #define ZLIBBUFSIZ 8192
 
@@ -53,6 +72,8 @@ typedef struct {
 /* Private */
 static GStaticPrivate private_key = G_STATIC_PRIVATE_INIT;
 
+static gchar		  *ontologies_dir;
+
 static void
 private_free (gpointer data)
 {
@@ -72,24 +93,583 @@ private_free (gpointer data)
 }
 
 
-void
-tracker_data_manager_init (TrackerConfig   *config,
-			   TrackerLanguage *language,
-			   TrackerDBIndex  *file_index,
-			   TrackerDBIndex  *email_index)
+static void
+load_ontology_file_from_path (const gchar	 *ontology_file)
+{
+	tracker_turtle_reader_init (ontology_file, NULL);
+	while (tracker_turtle_reader_next ()) {
+		const gchar *subject, *predicate, *object;
+
+		subject = tracker_turtle_reader_get_subject ();
+		predicate = tracker_turtle_reader_get_predicate ();
+		object = tracker_turtle_reader_get_object ();
+
+		if (strcmp (predicate, RDF_TYPE) == 0) {
+			if (strcmp (object, RDFS_CLASS) == 0) {
+				TrackerClass *class;
+
+				if (tracker_ontology_get_class_by_uri (subject) != NULL) {
+					g_critical ("%s: Duplicate definition of class %s", ontology_file, subject);
+					continue;
+				}
+
+				class = tracker_class_new ();
+				tracker_class_set_uri (class, subject);
+				tracker_ontology_add_class (class);
+				g_object_unref (class);
+			} else if (strcmp (object, RDF_PROPERTY) == 0) {
+				TrackerProperty *property;
+
+				if (tracker_ontology_get_property_by_uri (subject) != NULL) {
+					g_critical ("%s: Duplicate definition of property %s", ontology_file, subject);
+					continue;
+				}
+
+				property = tracker_property_new ();
+				tracker_property_set_uri (property, subject);
+				tracker_ontology_add_property (property);
+				g_object_unref (property);
+			} else if (strcmp (object, TRACKER_PREFIX "Namespace") == 0) {
+				TrackerNamespace *namespace;
+
+				if (tracker_ontology_get_namespace_by_uri (subject) != NULL) {
+					g_critical ("%s: Duplicate definition of namespace %s", ontology_file, subject);
+					continue;
+				}
+
+				namespace = tracker_namespace_new ();
+				tracker_namespace_set_uri (namespace, subject);
+				tracker_ontology_add_namespace (namespace);
+				g_object_unref (namespace);
+			}
+		} else if (strcmp (predicate, RDFS_SUB_CLASS_OF) == 0) {
+			TrackerClass *class, *super_class;
+
+			class = tracker_ontology_get_class_by_uri (subject);
+			if (class == NULL) {
+				g_critical ("%s: Unknown class %s", ontology_file, subject);
+				continue;
+			}
+
+			super_class = tracker_ontology_get_class_by_uri (object);
+			if (super_class == NULL) {
+				g_critical ("%s: Unknown class %s", ontology_file, object);
+				continue;
+			}
+
+			tracker_class_add_super_class (class, super_class);
+		} else if (strcmp (predicate, RDFS_SUB_PROPERTY_OF) == 0) {
+			TrackerProperty *property, *super_property;
+
+			property = tracker_ontology_get_property_by_uri (subject);
+			if (property == NULL) {
+				g_critical ("%s: Unknown property %s", ontology_file, subject);
+				continue;
+			}
+
+			super_property = tracker_ontology_get_property_by_uri (object);
+			if (super_property == NULL) {
+				g_critical ("%s: Unknown property %s", ontology_file, object);
+				continue;
+			}
+
+			tracker_property_add_super_property (property, super_property);
+		} else if (strcmp (predicate, RDFS_DOMAIN) == 0) {
+			TrackerProperty *property;
+			TrackerClass *domain;
+
+			property = tracker_ontology_get_property_by_uri (subject);
+			if (property == NULL) {
+				g_critical ("%s: Unknown property %s", ontology_file, subject);
+				continue;
+			}
+
+			domain = tracker_ontology_get_class_by_uri (object);
+			if (domain == NULL) {
+				g_critical ("%s: Unknown class %s", ontology_file, object);
+				continue;
+			}
+
+			tracker_property_set_domain (property, domain);
+		} else if (strcmp (predicate, RDFS_RANGE) == 0) {
+			TrackerProperty *property;
+			TrackerClass *range;
+
+			property = tracker_ontology_get_property_by_uri (subject);
+			if (property == NULL) {
+				g_critical ("%s: Unknown property %s", ontology_file, subject);
+				continue;
+			}
+
+			range = tracker_ontology_get_class_by_uri (object);
+			if (range == NULL) {
+				g_critical ("%s: Unknown class %s", ontology_file, object);
+				continue;
+			}
+
+			tracker_property_set_range (property, range);
+		} else if (strcmp (predicate, NRL_MAX_CARDINALITY) == 0) {
+			TrackerProperty *property;
+
+			property = tracker_ontology_get_property_by_uri (subject);
+			if (property == NULL) {
+				g_critical ("%s: Unknown property %s", ontology_file, subject);
+				continue;
+			}
+
+			if (atoi (object) == 1) {
+				tracker_property_set_multiple_values (property, FALSE);
+			}
+		} else if (strcmp (predicate, TRACKER_PREFIX "indexed") == 0) {
+			TrackerProperty *property;
+
+			property = tracker_ontology_get_property_by_uri (subject);
+			if (property == NULL) {
+				g_critical ("%s: Unknown property %s", ontology_file, subject);
+				continue;
+			}
+
+			if (strcmp (object, "true") == 0) {
+				tracker_property_set_indexed (property, TRUE);
+			}
+		} else if (strcmp (predicate, TRACKER_PREFIX "fulltextIndexed") == 0) {
+			TrackerProperty *property;
+
+			property = tracker_ontology_get_property_by_uri (subject);
+			if (property == NULL) {
+				g_critical ("%s: Unknown property %s", ontology_file, subject);
+				continue;
+			}
+
+			if (strcmp (object, "true") == 0) {
+				tracker_property_set_fulltext_indexed (property, TRUE);
+			}
+		} else if (strcmp (predicate, TRACKER_PREFIX "prefix") == 0) {
+			TrackerNamespace *namespace;
+
+			namespace = tracker_ontology_get_namespace_by_uri (subject);
+			if (namespace == NULL) {
+				g_critical ("%s: Unknown namespace %s", ontology_file, subject);
+				continue;
+			}
+
+			tracker_namespace_set_prefix (namespace, object);
+		}
+	}
+}
+
+static void
+load_ontology_file (const gchar	      *filename)
+{
+	gchar		*ontology_file;
+
+	ontology_file = g_build_filename (ontologies_dir, filename, NULL);
+	load_ontology_file_from_path (ontology_file);
+	g_free (ontology_file);
+}
+
+static void
+import_ontology_file_from_path (const gchar	 *ontology_file)
+{
+	tracker_turtle_reader_init (ontology_file, NULL);
+	while (tracker_turtle_reader_next ()) {
+		tracker_data_insert_statement (
+			tracker_turtle_reader_get_subject (),
+			tracker_turtle_reader_get_predicate (),
+			tracker_turtle_reader_get_object ());
+	}
+}
+
+static void
+import_ontology_file (const gchar	      *filename)
+{
+	gchar		*ontology_file;
+
+	ontology_file = g_build_filename (ontologies_dir, filename, NULL);
+	import_ontology_file_from_path (ontology_file);
+	g_free (ontology_file);
+}
+
+static void
+class_add_super_classes_from_db (TrackerDBInterface *iface, TrackerClass *class)
+{
+	TrackerDBStatement *stmt;
+	TrackerDBResultSet *result_set;
+
+	stmt = tracker_db_interface_create_statement (iface,
+						      "SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:subClassOf\") "
+						      "FROM \"rdfs:Class_rdfs:subClassOf\" "
+						      "WHERE ID = (SELECT ID FROM \"rdfs:Resource\" WHERE Uri = ?)");
+	tracker_db_statement_bind_text (stmt, 0, tracker_class_get_uri (class));
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	if (result_set) {
+		gboolean valid = TRUE;
+
+		while (valid) {
+			TrackerClass *super_class;
+			gchar *super_class_uri;
+
+			tracker_db_result_set_get (result_set, 0, &super_class_uri, -1);
+			super_class = tracker_ontology_get_class_by_uri (super_class_uri);
+			tracker_class_add_super_class (class, super_class);
+
+			g_free (super_class_uri);
+
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
+
+		g_object_unref (result_set);
+	}
+}
+
+static void
+property_add_super_properties_from_db (TrackerDBInterface *iface, TrackerProperty *property)
+{
+	TrackerDBStatement *stmt;
+	TrackerDBResultSet *result_set;
+
+	stmt = tracker_db_interface_create_statement (iface,
+						      "SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:subPropertyOf\") "
+						      "FROM \"rdf:Property_rdfs:subPropertyOf\" "
+						      "WHERE ID = (SELECT ID FROM \"rdfs:Resource\" WHERE Uri = ?)");
+	tracker_db_statement_bind_text (stmt, 0, tracker_property_get_uri (property));
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	if (result_set) {
+		gboolean valid = TRUE;
+
+		while (valid) {
+			TrackerProperty *super_property;
+			gchar *super_property_uri;
+
+			tracker_db_result_set_get (result_set, 0, &super_property_uri, -1);
+			super_property = tracker_ontology_get_property_by_uri (super_property_uri);
+			tracker_property_add_super_property (property, super_property);
+
+			g_free (super_property_uri);
+
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
+
+		g_object_unref (result_set);
+	}
+}
+
+static void
+db_get_static_data (TrackerDBInterface *iface)
+{
+	TrackerDBStatement *stmt;
+	TrackerDBResultSet *result_set;
+
+	stmt = tracker_db_interface_create_statement (iface,
+						      "SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"tracker:Namespace\".ID), "
+						      "\"tracker:prefix\" "
+						      "FROM \"tracker:Namespace\"");
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	if (result_set) {
+		gboolean valid = TRUE;
+
+		while (valid) {
+			TrackerNamespace *namespace;
+			gchar	         *uri, *prefix;
+
+			namespace = tracker_namespace_new ();
+
+			tracker_db_result_set_get (result_set,
+						   0, &uri,
+						   1, &prefix,
+						   -1);
+
+			tracker_namespace_set_uri (namespace, uri);
+			tracker_namespace_set_prefix (namespace, prefix);
+			tracker_ontology_add_namespace (namespace);
+
+			g_object_unref (namespace);
+			g_free (uri);
+			g_free (prefix);
+
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
+
+		g_object_unref (result_set);
+	}
+
+	stmt = tracker_db_interface_create_statement (iface,
+						      "SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:Class\".ID) "
+						      "FROM \"rdfs:Class\" ORDER BY ID");
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	if (result_set) {
+		gboolean valid = TRUE;
+
+		while (valid) {
+			TrackerClass *class;
+			gchar	     *uri;
+
+			class = tracker_class_new ();
+
+			tracker_db_result_set_get (result_set,
+						   0, &uri,
+						   -1);
+
+			tracker_class_set_uri (class, uri);
+			class_add_super_classes_from_db (iface, class);
+			tracker_ontology_add_class (class);
+
+			g_object_unref (class);
+			g_free (uri);
+
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
+
+		g_object_unref (result_set);
+	}
+
+	stmt = tracker_db_interface_create_statement (iface,
+						      "SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdf:Property\".ID), "
+						      "(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:domain\"), "
+						      "(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:range\"), "
+						      "\"nrl:maxCardinality\", "
+						      "\"tracker:indexed\", "
+						      "\"tracker:fulltextIndexed\" "
+						      "FROM \"rdf:Property\" ORDER BY ID");
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	if (result_set) {
+		gboolean valid = TRUE;
+
+		while (valid) {
+			GValue value = { 0 };
+			TrackerProperty *property;
+			gchar	        *uri, *domain_uri, *range_uri;
+			gboolean         multi_valued, indexed, fulltext_indexed;
+
+			property = tracker_property_new ();
+
+			tracker_db_result_set_get (result_set,
+						   0, &uri,
+						   1, &domain_uri,
+						   2, &range_uri,
+						   -1);
+
+			_tracker_db_result_set_get_value (result_set, 3, &value);
+			if (G_VALUE_TYPE (&value) != 0) {
+				multi_valued = (g_value_get_int (&value) > 1);
+				g_value_unset (&value);
+			} else {
+				/* nrl:maxCardinality not set
+				   not limited to single value */
+				multi_valued = TRUE;
+			}
+
+			_tracker_db_result_set_get_value (result_set, 4, &value);
+			if (G_VALUE_TYPE (&value) != 0) {
+				indexed = (g_value_get_int (&value) == 1);
+				g_value_unset (&value);
+			} else {
+				/* NULL */
+				indexed = FALSE;
+			}
+
+			_tracker_db_result_set_get_value (result_set, 5, &value);
+			if (G_VALUE_TYPE (&value) != 0) {
+				fulltext_indexed = (g_value_get_int (&value) == 1);
+				g_value_unset (&value);
+			} else {
+				/* NULL */
+				fulltext_indexed = FALSE;
+			}
+
+			tracker_property_set_uri (property, uri);
+			tracker_property_set_domain (property, tracker_ontology_get_class_by_uri (domain_uri));
+			tracker_property_set_range (property, tracker_ontology_get_class_by_uri (range_uri));
+			tracker_property_set_multiple_values (property, multi_valued);
+			tracker_property_set_indexed (property, indexed);
+			tracker_property_set_fulltext_indexed (property, fulltext_indexed);
+			property_add_super_properties_from_db (iface, property);
+			tracker_ontology_add_property (property);
+
+			g_object_unref (property);
+			g_free (uri);
+			g_free (domain_uri);
+			g_free (range_uri);
+
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
+
+		g_object_unref (result_set);
+	}
+}
+
+static void
+create_decomposed_metadata_tables (TrackerDBInterface *iface,
+				   TrackerClass       *service,
+				   gint               *max_id)
+{
+	const char *service_name;
+	GString    *sql;
+	TrackerProperty	  **properties, **property;
+	GSList      *class_properties, *field_it;
+	gboolean    main_class;
+
+	service_name = tracker_class_get_name (service);
+	main_class = (strcmp (service_name, "rdfs:Resource") == 0);
+
+	if (g_str_has_prefix (service_name, "xsd:")) {
+		/* xsd classes do not derive from rdfs:Resource and do not need separate tables */
+		return;
+	}
+
+	sql = g_string_new ("");
+	g_string_append_printf (sql, "CREATE TABLE \"%s\" (ID INTEGER NOT NULL PRIMARY KEY", service_name);
+	if (main_class) {
+		g_string_append (sql, ", Uri TEXT NOT NULL, Modified INTEGER NOT NULL, Available INTEGER NOT NULL");
+	}
+
+	properties = tracker_ontology_get_properties ();
+	class_properties = NULL;
+	for (property = properties; *property; property++) {
+		const char   *field_name;
+
+		field_name = tracker_property_get_name (*property);
+		if (tracker_property_get_domain (*property) == service) {
+			const char *sql_type;
+
+			switch (tracker_property_get_data_type (*property)) {
+			case TRACKER_PROPERTY_TYPE_STRING:
+				sql_type = "TEXT";
+				break;
+			case TRACKER_PROPERTY_TYPE_INTEGER:
+			case TRACKER_PROPERTY_TYPE_BOOLEAN:
+			case TRACKER_PROPERTY_TYPE_DATE:
+			case TRACKER_PROPERTY_TYPE_DATETIME:
+			case TRACKER_PROPERTY_TYPE_RESOURCE:
+				sql_type = "INTEGER";
+				break;
+			case TRACKER_PROPERTY_TYPE_DOUBLE:
+				sql_type = "REAL";
+				break;
+			default:
+				sql_type = "";
+				break;
+			}
+
+			if (tracker_property_get_multiple_values (*property)) {
+				/* multiple values */
+				if (tracker_property_get_indexed (*property)) {
+					/* use different UNIQUE index for properties whose
+					 * value should be indexed to minimize index size */
+					tracker_db_interface_execute_query (iface, NULL,
+						"CREATE TABLE \"%s_%s\" ("
+						"ID INTEGER NOT NULL, "
+						"\"%s\" %s NOT NULL, "
+						"UNIQUE (\"%s\", ID))",
+						service_name,
+						field_name,
+						field_name,
+						sql_type,
+						field_name);
+
+					tracker_db_interface_execute_query (iface, NULL,
+						"CREATE INDEX \"%s_%s_ID\" ON \"%s_%s\" (ID)",
+						service_name,
+						field_name,
+						service_name,
+						field_name);
+				} else {
+					/* we still have to include the property value in
+					 * the unique index for proper constraints */
+					tracker_db_interface_execute_query (iface, NULL,
+						"CREATE TABLE \"%s_%s\" ("
+						"ID INTEGER NOT NULL, "
+						"\"%s\" %s NOT NULL, "
+						"UNIQUE (ID, \"%s\"))",
+						service_name,
+						field_name,
+						field_name,
+						sql_type,
+						field_name);
+				}
+			} else {
+				/* single value */
+
+				class_properties = g_slist_prepend (class_properties, *property);
+				g_string_append_printf (sql, ", \"%s\" %s", field_name, sql_type);
+			}
+		}
+	}
+
+	if (main_class) {
+		g_string_append (sql, ", UNIQUE (Uri)");
+	}
+	g_string_append (sql, ")");
+	tracker_db_interface_execute_query (iface, NULL, "%s", sql->str);
+
+	g_free (properties);
+	g_string_free (sql, TRUE);
+
+	/* create index for single-valued fields */
+	for (field_it = class_properties; field_it != NULL; field_it = field_it->next) {
+		TrackerProperty *field;
+		const char   *field_name;
+
+		field = field_it->data;
+
+		if (!tracker_property_get_multiple_values (field)
+		    && tracker_property_get_indexed (field)) {
+			field_name = tracker_property_get_name (field);
+			tracker_db_interface_execute_query (iface, NULL,
+							    "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\")",
+							    service_name,
+							    field_name,
+							    service_name,
+							    field_name);
+		}
+	}
+
+	g_slist_free (class_properties);
+
+	/* insert class uri in rdfs:Resource table */
+	if (tracker_class_get_uri (service) != NULL) {
+		TrackerDBStatement *stmt;
+
+		stmt = tracker_db_interface_create_statement (iface,
+							      "INSERT OR IGNORE INTO \"rdfs:Resource\" (ID, Uri, Modified) VALUES (?, ?, ?)");
+		tracker_db_statement_bind_int (stmt, 0, ++(*max_id));
+		tracker_db_statement_bind_text (stmt, 1, tracker_class_get_uri (service));
+		tracker_db_statement_bind_int64 (stmt, 2, (gint64) time (NULL));
+		tracker_db_statement_execute (stmt, NULL);
+		g_object_unref (stmt);
+	}
+}
+
+gboolean
+tracker_data_manager_init (TrackerConfig              *config,
+			   TrackerLanguage            *language,
+			   TrackerDBManagerFlags       flags,
+			   TrackerDBIndexManagerFlags  index_flags,
+			   const gchar                *test_schema,
+			   gboolean                   *first_time)
 {
 	TrackerDBPrivate *private;
+	TrackerDBInterface *iface;
+	gboolean is_first_time_index;
 
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (TRACKER_IS_LANGUAGE (language));
-	g_return_if_fail (TRACKER_IS_DB_INDEX (file_index));
-	g_return_if_fail (TRACKER_IS_DB_INDEX (email_index));
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), FALSE);
+	g_return_val_if_fail (TRACKER_IS_LANGUAGE (language), FALSE);
 
 	private = g_static_private_get (&private_key);
 	if (private) {
 		g_warning ("Already initialized (%s)",
 			   __FUNCTION__);
-		return;
+		return FALSE;
 	}
 
 	private = g_new0 (TrackerDBPrivate, 1);
@@ -100,6 +680,110 @@ tracker_data_manager_init (TrackerConfig   *config,
 	g_static_private_set (&private_key,
 			      private,
 			      private_free);
+
+	tracker_db_manager_init (flags, &is_first_time_index, TRUE);
+	if (!tracker_db_index_manager_init (index_flags,
+					    tracker_config_get_min_bucket_count (config),
+					    tracker_config_get_max_bucket_count (config))) {
+		return FALSE;
+	}
+
+	if (first_time != NULL) {
+		*first_time = is_first_time_index;
+	}
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	if (is_first_time_index) {
+		TrackerClass **classes;
+		TrackerClass **cl;
+		gint           max_id = 0;
+		GList *sorted = NULL, *l;
+		gchar *test_schema_path;
+
+
+		if (flags & TRACKER_DB_MANAGER_TEST_MODE) {
+			ontologies_dir = g_build_filename ("..", "..",
+							 "data",
+							 "ontologies",
+							 NULL);
+		} else {
+			ontologies_dir = g_build_filename (SHAREDIR,
+							 "tracker",
+							 "ontologies",
+							 NULL);
+		}
+
+		if (test_schema) {
+			/* load test schema, not used in normal operation */
+			test_schema_path = g_strconcat (test_schema, ".ontology", NULL);
+
+			sorted = g_list_prepend (sorted, g_strdup ("12-nrl.ontology"));
+			sorted = g_list_prepend (sorted, g_strdup ("11-rdf.ontology"));
+			sorted = g_list_prepend (sorted, g_strdup ("10-xsd.ontology"));
+		} else {
+			GDir        *ontologies;
+			const gchar *conf_file;
+
+			ontologies = g_dir_open (ontologies_dir, 0, NULL);
+
+			conf_file = g_dir_read_name (ontologies);
+
+			/* .ontology files */
+			while (conf_file) {
+				if (g_str_has_suffix (conf_file, ".ontology")) {
+					sorted = g_list_insert_sorted (sorted,
+					                                   g_strdup (conf_file), 
+					                                   (GCompareFunc) strcmp);
+				}
+				conf_file = g_dir_read_name (ontologies);
+			}
+
+			g_dir_close (ontologies);
+		}
+
+		/* load ontology from files into memory */
+		for (l = sorted; l; l = l->next) {
+			g_debug ("Loading ontology %s", (char *) l->data);
+			load_ontology_file (l->data);
+		}
+		if (test_schema) {
+			load_ontology_file_from_path (test_schema_path);
+		}
+
+		classes = tracker_ontology_get_classes ();
+
+		tracker_data_begin_transaction ();
+
+		/* create tables */
+		for (cl = classes; *cl; cl++) {
+			create_decomposed_metadata_tables (iface, *cl, &max_id);
+		}
+
+		/* store ontology in database */
+		for (l = sorted; l; l = l->next) {
+			import_ontology_file (l->data);
+		}
+		if (test_schema) {
+			import_ontology_file_from_path (test_schema_path);
+			g_free (test_schema_path);
+		}
+
+		tracker_data_commit_transaction ();
+
+		g_free (classes);
+
+		g_list_foreach (sorted, (GFunc) g_free, NULL);
+		g_list_free (sorted);
+
+		g_free (ontologies_dir);
+		ontologies_dir = NULL;
+	} else {
+		/* load ontology from database into memory */
+		db_get_static_data (iface);
+	}
+
+	return TRUE;
 }
 
 void
@@ -107,6 +791,9 @@ tracker_data_manager_shutdown (void)
 {
 	TrackerDBPrivate *private;
 
+	tracker_db_index_manager_shutdown ();
+	tracker_db_manager_shutdown ();
+
 	private = g_static_private_get (&private_key);
 	if (!private) {
 		g_warning ("Not initialized (%s)",
@@ -139,57 +826,6 @@ tracker_data_manager_get_language (void)
 	return private->language;
 }
 
-gboolean
-tracker_data_manager_exec_no_reply (TrackerDBInterface *iface,
-				    const gchar	     *query,
-				    ...)
-{
-	TrackerDBResultSet *result_set;
-	va_list		    args;
-
-	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (iface), FALSE);
-	g_return_val_if_fail (query != NULL, FALSE);
-
-	tracker_nfs_lock_obtain ();
-
-	va_start (args, query);
-	result_set = tracker_db_interface_execute_vquery (iface, NULL, query, args);
-	va_end (args);
-
-	if (result_set) {
-		g_object_unref (result_set);
-	}
-
-	tracker_nfs_lock_release ();
-
-	return TRUE;
-}
-
-TrackerDBResultSet *
-tracker_data_manager_exec (TrackerDBInterface *iface,
-			   const gchar	    *query,
-			   ...)
-{
-	TrackerDBResultSet *result_set;
-	va_list		    args;
-
-	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (iface), NULL);
-	g_return_val_if_fail (query != NULL, NULL);
-
-	tracker_nfs_lock_obtain ();
-
-	va_start (args, query);
-	result_set = tracker_db_interface_execute_vquery (iface,
-							  NULL,
-							  query,
-							  args);
-	va_end (args);
-
-	tracker_nfs_lock_release ();
-
-	return result_set;
-}
-
 TrackerDBResultSet *
 tracker_data_manager_exec_proc (TrackerDBInterface *iface,
 			        const gchar	   *procedure,
@@ -215,22 +851,19 @@ gint
 tracker_data_manager_get_db_option_int (const gchar *option)
 {
 	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
 	TrackerDBResultSet *result_set;
 	gchar		   *str;
 	gint		    value = 0;
 
 	g_return_val_if_fail (option != NULL, 0);
 
-	/* Here it doesn't matter which one we ask, as long as it has common.db
-	 * attached. The service ones are cached connections, so we can use
-	 * those instead of asking for an individual-file connection (like what
-	 * the original code had) */
-
-	/* iface = tracker_db_manager_get_db_interfaceX (TRACKER_DB_COMMON); */
+	iface = tracker_db_manager_get_db_interface ();
 
-	iface = tracker_db_manager_get_db_interface_by_service (TRACKER_DB_FOR_FILE_SERVICE);
-
-	result_set = tracker_data_manager_exec_proc (iface, "GetOption", option, NULL);
+	stmt = tracker_db_interface_create_statement (iface, "SELECT OptionValue FROM Options WHERE OptionKey = ?");
+	tracker_db_statement_bind_text (stmt, 0, option);
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 
 	if (result_set) {
 		tracker_db_result_set_get (result_set, 0, &str, -1);
@@ -251,25 +884,21 @@ tracker_data_manager_set_db_option_int (const gchar *option,
 					gint	     value)
 {
 	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
 	TrackerDBResultSet *result_set;
 	gchar		   *str;
 
 	g_return_if_fail (option != NULL);
 
-	/* Here it doesn't matter which one we ask, as long as it has common.db
-	 * attached. The service ones are cached connections, so we can use
-	 * those instead of asking for an individual-file connection (like what
-	 * the original code had) */
-
-	/* iface = tracker_db_manager_get_db_interfaceX (TRACKER_DB_COMMON); */
+	iface = tracker_db_manager_get_db_interface ();
 
-	iface = tracker_db_manager_get_db_interface_by_service (TRACKER_DB_FOR_FILE_SERVICE);
+	stmt = tracker_db_interface_create_statement (iface, "REPLACE INTO Options (OptionKey, OptionValue) VALUES (?,?)");
+	tracker_db_statement_bind_text (stmt, 0, option);
 
 	str = tracker_gint_to_string (value);
-	result_set = tracker_data_manager_exec_proc (iface, "SetOption", option, str, NULL);
+	tracker_db_statement_bind_text (stmt, 1, str);
 	g_free (str);
 
-	if (result_set) {
-		g_object_unref (result_set);
-	}
+	tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 }
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index 0989791..f1015e0 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -27,20 +27,23 @@
 #include <glib.h>
 
 #include <libtracker-common/tracker-config.h>
-#include <libtracker-common/tracker-property.h>
 #include <libtracker-common/tracker-language.h>
 #include <libtracker-common/tracker-ontology.h>
 
 #include <libtracker-db/tracker-db-interface.h>
 #include <libtracker-db/tracker-db-file-info.h>
 #include <libtracker-db/tracker-db-index.h>
+#include <libtracker-db/tracker-db-index-manager.h>
+#include <libtracker-db/tracker-db-manager.h>
 
 G_BEGIN_DECLS
 
-void                tracker_data_manager_init              (TrackerConfig      *config,
-							    TrackerLanguage    *language,
-							    TrackerDBIndex     *file_index,
-							    TrackerDBIndex     *email_index);
+gboolean            tracker_data_manager_init              (TrackerConfig              *config,
+							    TrackerLanguage            *language,
+							    TrackerDBManagerFlags       flags,
+							    TrackerDBIndexManagerFlags  index_flags,
+							    const gchar                *test_schema,
+							    gboolean                   *first_time);
 void                tracker_data_manager_shutdown          (void);
 TrackerConfig *     tracker_data_manager_get_config        (void);
 TrackerLanguage *   tracker_data_manager_get_language      (void);
@@ -49,12 +52,6 @@ TrackerLanguage *   tracker_data_manager_get_language      (void);
 TrackerDBResultSet *tracker_data_manager_exec_proc         (TrackerDBInterface *iface,
 							    const gchar        *procedure,
 							    ...);
-gboolean            tracker_data_manager_exec_no_reply     (TrackerDBInterface *iface,
-							    const gchar        *query,
-							    ...);
-TrackerDBResultSet *tracker_data_manager_exec              (TrackerDBInterface *iface,
-							    const char         *query,
-							    ...);
 gint                tracker_data_manager_get_db_option_int (const gchar        *option);
 void                tracker_data_manager_set_db_option_int (const gchar        *option,
 							    gint                value);
diff --git a/src/libtracker-data/tracker-data-metadata.c b/src/libtracker-data/tracker-data-metadata.c
deleted file mode 100644
index 9ba136e..0000000
--- a/src/libtracker-data/tracker-data-metadata.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
- * Copyright (C) 2008, Nokia
-
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include "config.h"
-
-#include <glib.h>
-
-#include <libtracker-common/tracker-ontology.h>
-
-#include "tracker-data-metadata.h"
-
-struct TrackerDataMetadata {
-	GHashTable *table;
-};
-
-/**
- * tracker_data_metadata_new:
- *
- * Creates a new #TrackerDataMetadata with no data in it.
- *
- * Returns: The newly created #TrackerDataMetadata
- **/
-TrackerDataMetadata *
-tracker_data_metadata_new (void)
-{
-	TrackerDataMetadata *metadata;
-
-	metadata = g_slice_new (TrackerDataMetadata);
-	metadata->table = g_hash_table_new_full (g_direct_hash,
-						 g_direct_equal,
-						 (GDestroyNotify) g_object_unref,
-						 NULL);
-	return metadata;
-}
-
-static gboolean
-remove_metadata_foreach (gpointer key,
-			 gpointer value,
-			 gpointer user_data)
-{
-	TrackerProperty *field;
-
-	field = (TrackerProperty *) key;
-
-	if (tracker_property_get_multiple_values (field)) {
-		GList *list;
-
-		list = (GList *) value;
-		g_list_foreach (list, (GFunc) g_free, NULL);
-		g_list_free (list);
-	} else {
-		g_free (value);
-	}
-
-	return TRUE;
-}
-
-/**
- * tracker_data_metadata_free:
- * @metadata: A #TrackerDataMetadata
- *
- * Frees the #TrackerDataMetadata and any contained data.
- **/
-void
-tracker_data_metadata_free (TrackerDataMetadata *metadata)
-{
-	g_return_if_fail (metadata != NULL);
-
-	g_hash_table_foreach_remove (metadata->table,
-				     remove_metadata_foreach,
-				     NULL);
-
-	g_hash_table_destroy (metadata->table);
-	g_slice_free (TrackerDataMetadata, metadata);
-}
-
-/**
- * tracker_data_metadata_insert:
- * @metadata: A #TrackerDataMetadata
- * @field_name: Field name for the metadata to insert.
- * @value: Value for the metadata to insert.
- *
- * Inserts a new metadata element into @metadata.
- **/
-void
-tracker_data_metadata_insert (TrackerDataMetadata *metadata,
-			      const gchar	  *field_name,
-			      const gchar         *value)
-{
-	TrackerProperty *field;
-	gchar *old_value;
-
-	g_return_if_fail (metadata != NULL);
-	g_return_if_fail (field_name != NULL);
-	g_return_if_fail (value != NULL);
-
-	field = tracker_ontology_get_field_by_name (field_name);
-
-	g_return_if_fail (TRACKER_IS_PROPERTY (field));
-	g_return_if_fail (tracker_property_get_multiple_values (field) == FALSE);
-
-	old_value = g_hash_table_lookup (metadata->table, field);
-	g_free (old_value);
-
-	g_hash_table_replace (metadata->table,
-			      g_object_ref (field),
-			      g_strdup (value));
-}
-
-
-/**
- * tracker_data_metadata_insert_values:
- * @metadata: A #TrackerDataMetadata
- * @field_name: Field name for the metadata to insert
- * @list: Value list for the metadata to insert
- *
- * Inserts a list of values into @metadata for the given @field_name.
- * The ontology has to specify that @field_name allows multiple values.
- * 
- * The values in @list and the list itself are copied, the caller is
- * still responsible for the memory @list uses after calling this
- * function. 
- **/
-void
-tracker_data_metadata_insert_values (TrackerDataMetadata *metadata,
-				     const gchar         *field_name,
-				     const GList	 *list)
-{
-	TrackerProperty *field;
-	GList        *old_values, *copy;
-
-	g_return_if_fail (metadata != NULL);
-	g_return_if_fail (field_name != NULL);
-
-	if (!list) {
-		return;
-	}
-
-	field = tracker_ontology_get_field_by_name (field_name);
-
-	if (!field) {
-		g_warning ("Field name '%s' has isn't described in the ontology", field_name);
-		return;
-	}
-
-	g_return_if_fail (TRACKER_IS_PROPERTY (field));
-	g_return_if_fail (tracker_property_get_multiple_values (field) == TRUE);
-
-	copy = tracker_glist_copy_with_string_data ((GList *)list);
-
-	old_values = g_hash_table_lookup (metadata->table, field);
-
-	if (old_values) {
-		g_list_foreach (old_values, (GFunc) g_free, NULL);
-		g_list_free (old_values);
-	}
-
-	g_hash_table_replace (metadata->table,
-			      g_object_ref (field),
-			      copy);
-}
-
-/**
- * tracker_data_metadata_lookup:
- * @metadata: A #TrackerDataMetadata
- * @field_name: Field name to look up
- *
- * Returns the value corresponding to the metadata specified by
- * @field_name. 
- *
- * Returns: The value. This string is owned by @metadata and must not
- * be modified or freed. 
- **/
-G_CONST_RETURN gchar *
-tracker_data_metadata_lookup (TrackerDataMetadata *metadata,
-			      const gchar	  *field_name)
-{
-	TrackerProperty *field;
-
-	g_return_val_if_fail (metadata != NULL, NULL);
-	g_return_val_if_fail (field_name != NULL, NULL);
-
-	field = tracker_ontology_get_field_by_name (field_name);
-
-	g_return_val_if_fail (TRACKER_IS_PROPERTY (field), NULL);
-	g_return_val_if_fail (tracker_property_get_multiple_values (field) == FALSE, NULL);
-
-	return g_hash_table_lookup (metadata->table, field);
-}
-
-/**
- * tracker_data_metadata_lookup_values:
- * @metadata: A #TrackerDataMetadata
- * @field_name: Field name to look up
- *
- * Returns the value list corresponding to the metadata specified by
- * @field_name. 
- *
- * Returns: A List containing strings. Both the list and the contained
- *          strings are owned by @metadata and must not be modified or
- *          freed. 
- **/
-G_CONST_RETURN GList *
-tracker_data_metadata_lookup_values (TrackerDataMetadata *metadata,
-				     const gchar         *field_name)
-{
-	TrackerProperty *field;
-
-	g_return_val_if_fail (metadata != NULL, NULL);
-	g_return_val_if_fail (field_name != NULL, NULL);
-
-	field = tracker_ontology_get_field_by_name (field_name);
-
-	g_return_val_if_fail (TRACKER_IS_PROPERTY (field), NULL);
-	g_return_val_if_fail (tracker_property_get_multiple_values (field) == TRUE, NULL);
-
-	return g_hash_table_lookup (metadata->table, field);
-}
-
-/**
- * tracker_data_metadata_foreach:
- * @metadata: A #TrackerDataMetadata.
- * @func: The function to call with each metadata.
- * @user_data: user data to pass to the function.
- *
- * Calls a function for each element in @metadata.
- **/
-void
-tracker_data_metadata_foreach (TrackerDataMetadata	  *metadata,
-			       TrackerDataMetadataForeach  func,
-			       gpointer			   user_data)
-{
-	g_return_if_fail (metadata != NULL);
-	g_return_if_fail (func != NULL);
-
-	g_hash_table_foreach (metadata->table,
-			      (GHFunc) func,
-			      user_data);
-}
-
-/**
- * tracker_data_metadata_foreach_remove:
- * @metadata: A #TrackerDataMetadata.
- * @func: The function to call with each metadata. 
- * @user_data: user data to pass to the function.
- *
- * Calls a function for each element in @metadata and remove the
- * element if @func returns %TRUE. 
- **/
-void
-tracker_data_metadata_foreach_remove (TrackerDataMetadata       *metadata,
-				      TrackerDataMetadataRemove  func,
-				      gpointer		         user_data)
-{
-	g_return_if_fail (metadata != NULL);
-	g_return_if_fail (func != NULL);
-
-	g_hash_table_foreach_remove (metadata->table,
-				     (GHRFunc) func,
-				     user_data);
-}
-
diff --git a/src/libtracker-data/tracker-data-metadata.h b/src/libtracker-data/tracker-data-metadata.h
deleted file mode 100644
index 7a89e18..0000000
--- a/src/libtracker-data/tracker-data-metadata.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
- * Copyright (C) 2008, Nokia
-
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#ifndef __TRACKER_DATA_METADATA_H__
-#define __TRACKER_DATA_METADATA_H__
-
-#include <glib.h>
-
-#include <libtracker-common/tracker-common.h>
-
-typedef struct TrackerDataMetadata TrackerDataMetadata;
-
-typedef void (* TrackerDataMetadataForeach) (TrackerProperty *field,
-					     gpointer      value,
-					     gpointer      user_data);
-typedef gboolean (* TrackerDataMetadataRemove) (TrackerProperty *field,
-						gpointer      value,
-						gpointer      user_data);
-
-TrackerDataMetadata * tracker_data_metadata_new            (void);
-void                  tracker_data_metadata_free           (TrackerDataMetadata        *metadata);
-void                  tracker_data_metadata_insert         (TrackerDataMetadata        *metadata,
-							    const gchar                *field_name,
-							    const gchar                *value);
-void                  tracker_data_metadata_insert_values  (TrackerDataMetadata        *metadata,
-							    const gchar                *field_name,
-							    const GList                *list);
-G_CONST_RETURN gchar *tracker_data_metadata_lookup         (TrackerDataMetadata        *metadata,
-							    const gchar                *field_name);
-G_CONST_RETURN GList *tracker_data_metadata_lookup_values  (TrackerDataMetadata        *metadata,
-							    const gchar                *field_name);
-void                  tracker_data_metadata_foreach        (TrackerDataMetadata        *metadata,
-							    TrackerDataMetadataForeach  func,
-							    gpointer                    user_data);
-void                  tracker_data_metadata_foreach_remove (TrackerDataMetadata        *metadata,
-							    TrackerDataMetadataRemove   func,
-							    gpointer                    user_data);
-
-G_END_DECLS
-
-#endif /* __TRACKER_DATA_METADATA_H__*/
diff --git a/src/libtracker-data/tracker-data-query.c b/src/libtracker-data/tracker-data-query.c
index 32f6145..748126c 100644
--- a/src/libtracker-data/tracker-data-query.c
+++ b/src/libtracker-data/tracker-data-query.c
@@ -41,128 +41,191 @@
 #include "tracker-data-manager.h"
 #include "tracker-data-query.h"
 
-static void
-db_result_set_to_ptr_array (TrackerDBResultSet *result_set,
-			    GPtrArray         **previous)
+static gchar *
+get_string_for_value (GValue *value)
 {
-	gchar        *prop_id_str;
-	gchar        *value;
-	TrackerProperty *field;
-	gboolean      valid = result_set != NULL;
-
-	while (valid) {
-		/* Item is a pair (property_name, value) */
-		gchar **item = g_new0 (gchar *, 2);
-
-		tracker_db_result_set_get (result_set, 0, &prop_id_str, 1, &value, -1);
-		item[1] = g_strdup (value);
-
-		field = tracker_ontology_get_field_by_id (GPOINTER_TO_UINT (prop_id_str));
-
-		item[0] = g_strdup (tracker_property_get_name (field));
-
-		g_ptr_array_add (*previous, item);
-		
-		valid = tracker_db_result_set_iter_next (result_set);
+	switch (G_VALUE_TYPE (value)) {
+	case G_TYPE_INT:
+		return g_strdup_printf ("%d", g_value_get_int (value));
+	case G_TYPE_DOUBLE:
+		return g_strdup_printf ("%f", g_value_get_double (value));
+	case G_TYPE_STRING:
+		return g_strdup (g_value_get_string (value));
+	default:
+		return NULL;
 	}
 }
 
 GPtrArray *
-tracker_data_query_all_metadata (const gchar *service_type,
-				 const gchar *service_id) 
+tracker_data_query_all_metadata (guint32 resource_id) 
 {
 	TrackerDBInterface *iface;
-	TrackerDBResultSet *result_set;
+	TrackerDBStatement *stmt;
+	TrackerDBResultSet *result_set, *single_result_set, *multi_result_set;
+	TrackerClass	   *class;
+	GString		   *sql;
 	GPtrArray          *result;
+	TrackerProperty	  **properties, **property;
+	gchar		   *class_uri;
+	int		    i;
+	gboolean            first;
+	gchar		  **item;
+	GValue		    value = { 0 };
 
 	result = g_ptr_array_new ();
 
-	iface = tracker_db_manager_get_db_interface_by_service (service_type);
-	if (!iface) {
-		g_warning ("Unable to obtain a DB connection for service type '%s'",
-			   service_type);
-		return result;
-	}
+	iface = tracker_db_manager_get_db_interface ();
 
-	result_set = tracker_data_manager_exec_proc (iface, 
-						     "GetAllMetadata", 
-						     service_id, 
-						     service_id, 
-						     service_id, 
-						     NULL);
+	properties = tracker_ontology_get_properties ();
+
+	stmt = tracker_db_interface_create_statement (iface, "SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdf:type\") FROM \"rdfs:Resource_rdf:type\" WHERE ID = ?");
+	tracker_db_statement_bind_int (stmt, 0, resource_id);
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 
 	if (result_set) {
-		db_result_set_to_ptr_array (result_set, &result);
-		g_object_unref (result_set);
-	}
+		do {
+			tracker_db_result_set_get (result_set, 0, &class_uri, -1);
+
+			class = tracker_ontology_get_class_by_uri (class_uri);
+			if (class == NULL) {
+				g_warning ("Class '%s' not found in the ontology", class_uri);
+				g_free (class_uri);
+				continue;
+			}
 
-	return result;
+			/* retrieve single value properties for current class */
+
+			sql = g_string_new ("SELECT ");
+
+			first = TRUE;
+			for (property = properties; *property; property++) {
+				if (tracker_property_get_domain (*property) == class) {
+					if (!tracker_property_get_multiple_values (*property)) {
+						if (!first) {
+							g_string_append (sql, ", ");
+						}
+						first = FALSE;
+
+						if (tracker_property_get_data_type (*property) == TRACKER_PROPERTY_TYPE_RESOURCE) {
+							g_string_append_printf (sql, "(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"%s\")", tracker_property_get_name (*property));
+						} else {
+							g_string_append_printf (sql, "\"%s\"", tracker_property_get_name (*property));
+						}
+					}
+				}
+			}
 
-}
+			if (!first) {
+				g_string_append_printf (sql, " FROM \"%s\" WHERE ID = ?", tracker_class_get_name (class));
+				stmt = tracker_db_interface_create_statement (iface, "%s", sql->str);
+				tracker_db_statement_bind_int (stmt, 0, resource_id);
+				single_result_set = tracker_db_statement_execute (stmt, NULL);
+				g_object_unref (stmt);
+			}
 
-/*
- * Obtain the concrete service type name for the file id.
- */
-G_CONST_RETURN gchar *
-tracker_data_query_service_type_by_id (TrackerDBInterface *iface,
-				       guint32             service_id)
-{
-	TrackerDBResultSet *result_set;
-	gint		    service_type_id;
-	gchar              *service_id_str;
-	const gchar	   *result = NULL;
+			g_string_free (sql, TRUE);
 
-	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (iface), NULL);
-	g_return_val_if_fail (service_id > 0, NULL);
+			i = 0;
+			for (property = properties; *property; property++) {
+				if (tracker_property_get_domain (*property) != class) {
+					continue;
+				}
 
-	service_id_str = tracker_guint32_to_string (service_id);
+				if (!tracker_property_get_multiple_values (*property)) {
+					/* single value property, value in single_result_set */
 
-	result_set = tracker_data_manager_exec_proc (iface,
-					   "GetFileByID",
-					   service_id_str,
-					   NULL);
+					_tracker_db_result_set_get_value (single_result_set, i++, &value);
+					if (G_VALUE_TYPE (&value) == 0) {
+						/* NULL, property not set */
+						continue;
+					}
 
-	g_free (service_id_str);
+					/* Item is a pair (property_name, value) */
+					item = g_new0 (gchar *, 2);
 
-	if (result_set) {
-		tracker_db_result_set_get (result_set, 3, &service_type_id, -1);
-		g_object_unref (result_set);
+					item[0] = g_strdup (tracker_property_get_name (*property));
+					item[1] = get_string_for_value (&value);
+
+					g_value_unset (&value);
+
+					g_ptr_array_add (result, item);
+				} else {
+					/* multi value property, retrieve values from DB */
+
+					sql = g_string_new ("SELECT ");
+
+					if (tracker_property_get_data_type (*property) == TRACKER_PROPERTY_TYPE_RESOURCE) {
+						g_string_append_printf (sql, "(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"%s\")", tracker_property_get_name (*property));
+					} else {
+						g_string_append_printf (sql, "\"%s\"", tracker_property_get_name (*property));
+					}
+
+					g_string_append_printf (sql,
+								" FROM \"%s_%s\" WHERE ID = ?",
+								tracker_class_get_name (tracker_property_get_domain (*property)),
+								tracker_property_get_name (*property));
+
+					stmt = tracker_db_interface_create_statement (iface, "%s", sql->str);
+					tracker_db_statement_bind_int (stmt, 0, resource_id);
+					multi_result_set = tracker_db_statement_execute (stmt, NULL);
+					g_object_unref (stmt);
+
+					if (multi_result_set) {
+						do {
+
+							/* Item is a pair (property_name, value) */
+							item = g_new0 (gchar *, 2);
+
+							item[0] = g_strdup (tracker_property_get_name (*property));
+
+							_tracker_db_result_set_get_value (multi_result_set, 0, &value);
+							item[1] = get_string_for_value (&value);
+							g_value_unset (&value);
+
+							g_ptr_array_add (result, item);
+						} while (tracker_db_result_set_iter_next (multi_result_set));
+
+						g_object_unref (multi_result_set);
+					}
+
+					g_string_free (sql, TRUE);
+				}
+			}
+
+			if (!first) {
+				g_object_unref (single_result_set);
+			}
+
+			g_free (class_uri);
+		} while (tracker_db_result_set_iter_next (result_set));
 
-		result = tracker_ontology_get_service_by_id (service_type_id);
+		g_object_unref (result_set);
 	}
 
+	g_free (properties);
+
 	return result;
+
 }
 
 guint32
-tracker_data_query_file_id (const gchar *service_type,
-			    const gchar *path)
+tracker_data_query_resource_id (const gchar	   *uri)
 {
 	TrackerDBResultSet *result_set;
 	TrackerDBInterface *iface;
-	gchar		   *dir, *name;
+	TrackerDBStatement *stmt;
 	guint32		    id = 0;
 
-	g_return_val_if_fail (path != NULL, 0);
-
-	iface = tracker_db_manager_get_db_interface_by_service (service_type);
-	
-	if (!iface) {
-		g_warning ("Unable to obtain interface for service type '%s'",
-			   service_type);
-		return 0;
-	}
-
-	tracker_file_get_path_and_name (path, &dir, &name);
+	g_return_val_if_fail (uri != NULL, 0);
 
-	result_set = tracker_data_manager_exec_proc (iface,
-					   "GetServiceID",
-					   dir,
-					   name,
-					   NULL);
+	iface = tracker_db_manager_get_db_interface ();
 
-	g_free (dir);
-	g_free (name);
+	stmt = tracker_db_interface_create_statement (iface,
+		"SELECT ID FROM \"rdfs:Resource\" WHERE Uri = ?");
+	tracker_db_statement_bind_text (stmt, 0, uri);
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 
 	if (result_set) {
 		tracker_db_result_set_get (result_set, 0, &id, -1);
@@ -172,31 +235,13 @@ tracker_data_query_file_id (const gchar *service_type,
 	return id;
 }
 
-gchar *
-tracker_data_query_file_id_as_string (const gchar	*service_type,
-				      const gchar	*path)
-{
-	guint32	id;
-
-	g_return_val_if_fail (path != NULL, NULL);
-
-	id = tracker_data_query_file_id (service_type, path);
-
-	if (id > 0) {
-		return tracker_guint_to_string (id);
-	}
-
-	return NULL;
-}
-
 gboolean
-tracker_data_query_service_exists (TrackerClass *service,
-				   const gchar	  *dirname,
-				   const gchar	  *basename,
+tracker_data_query_resource_exists (const gchar	  *uri,
 				   guint32	  *service_id,
 				   time_t	  *mtime)
 {
 	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
 	TrackerDBResultSet *result_set;
 	guint db_id;
 	guint db_mtime;
@@ -204,14 +249,14 @@ tracker_data_query_service_exists (TrackerClass *service,
 
 	db_id = db_mtime = 0;
 
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	iface = tracker_db_manager_get_db_interface ();
+
+	stmt = tracker_db_interface_create_statement (iface,
+		"SELECT ID, Modified FROM \"rdfs:Resource\" WHERE Uri = ?");
+	tracker_db_statement_bind_text (stmt, 0, uri);
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 
-	result_set = tracker_db_interface_execute_procedure (iface, NULL,
-							     "GetServiceID",
-							     dirname,
-							     basename,
-							     NULL);
 	if (result_set) {
 		tracker_db_result_set_get (result_set,
 					   0, &db_id,
@@ -232,383 +277,162 @@ tracker_data_query_service_exists (TrackerClass *service,
 	return found;
 }
 
-guint
-tracker_data_query_service_type_id (const gchar *dirname,
-				    const gchar *basename)
-{
-	TrackerDBInterface *iface;
-	TrackerDBResultSet *result_set;
-	guint service_type_id;
-
-	/* We are asking this because the module cannot assign service_type -> probably it is files */
-	iface = tracker_db_manager_get_db_interface_by_type ("Files",
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
-
-	result_set = tracker_db_interface_execute_procedure (iface, NULL,
-							     "GetServiceID",
-							     dirname,
-							     basename,
-							     NULL);
-	if (!result_set) {
-		return 0;
-	}
-
-	tracker_db_result_set_get (result_set, 3, &service_type_id, -1);
-	g_object_unref (result_set);
-
-	return service_type_id;
-}
 
-GHashTable *
-tracker_data_query_service_children (TrackerClass *service,
-				     const gchar    *dirname)
+/* TODO */
+#if 0
+TrackerDBResultSet *
+tracker_data_query_backup_metadata (TrackerClass *service)
 {
 	TrackerDBInterface *iface;
 	TrackerDBResultSet *result_set;
-	gboolean valid = TRUE;
-	GHashTable *children;
-
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
-
-	result_set = tracker_db_interface_execute_procedure (iface, NULL,
-							     "GetFileChildren",
-							     dirname,
-							     NULL);
-
-	if (!result_set) {
-		return NULL;
-	}
-
-	children = g_hash_table_new_full (g_direct_hash,
-					  g_direct_equal,
-					  NULL,
-					  (GDestroyNotify) g_free);
-
-	while (valid) {
-		guint32 id;
-		gchar *child_name;
-
-		tracker_db_result_set_get (result_set,
-					   0, &id,
-					   2, &child_name,
-					   -1);
-
-		g_hash_table_insert (children, GUINT_TO_POINTER (id), child_name);
 
-		valid = tracker_db_result_set_iter_next (result_set);
-	}
+	g_return_val_if_fail (TRACKER_IS_CLASS (service), NULL);
 
-	g_object_unref (result_set);
+	iface = tracker_db_manager_get_db_interface_by_service (tracker_class_get_name (service));
 
-	return children;
+	result_set = tracker_data_manager_exec_proc (iface,
+						     "GetUserMetadataBackup", 
+						     NULL);
+	return result_set;
 }
+#endif
 
-/*
- * Result set with (metadataID, value) per row
- */
-static void
-result_set_to_metadata (TrackerDBResultSet  *result_set,
-			TrackerDataMetadata *metadata,
-			gboolean	     embedded)
+gchar *
+tracker_data_query_property_value (const gchar *subject,
+				   const gchar *predicate)
 {
-	TrackerProperty *field;
-	gint	      metadata_id;
-	gboolean      valid = TRUE;
-
-	while (valid) {
-		GValue transform = {0, };
-		GValue value = {0, };
-		gchar *str;
-
-		g_value_init (&transform, G_TYPE_STRING);
-		tracker_db_result_set_get (result_set, 0, &metadata_id, -1);
-		_tracker_db_result_set_get_value (result_set, 1, &value);
-
-		if (g_value_transform (&value, &transform)) {
-			str = g_value_dup_string (&transform);
-			
-			if (!str) {
-				str = g_strdup ("");
-			} else if (!g_utf8_validate (str, -1, NULL)) {
-				g_warning ("Could not add string:'%s' to GStrv, invalid UTF-8", str);
-				g_free (str);
-				str = g_strdup ("");
-			}
-
-			g_value_unset (&transform);
-		} else {
-			str = g_strdup ("");
-		}
-
-		g_value_unset (&value);
-		field = tracker_ontology_get_field_by_id (metadata_id);
-		if (!field) {
-			g_critical ("Field id %d in database but not in tracker-ontology",
-				    metadata_id);
-			g_free (str);
-			return;
-		}
-
-		if (tracker_property_get_embedded (field) == embedded) {
-			if (tracker_property_get_multiple_values (field)) {
-				GList *new_values;
-				const GList *old_values;
-
-				new_values = NULL;
-				old_values = tracker_data_metadata_lookup_values (metadata,
-										  tracker_property_get_name (field));
-				if (old_values) {
-					new_values = g_list_copy ((GList*) old_values);
-				}
+	TrackerDBInterface  *iface;
+	TrackerDBStatement  *stmt;
+	TrackerDBResultSet  *result_set;
+	TrackerProperty *property;
+	guint32		    subject_id;
+	const gchar *table_name, *field_name;
+	gchar *result = NULL;
 
-				new_values = g_list_prepend (new_values, str);
-				tracker_data_metadata_insert_values (metadata,
-								     tracker_property_get_name (field),
-								     new_values);
+	property = tracker_ontology_get_property_by_uri (predicate);
 
-				g_list_free (new_values);
-			} else {
-				tracker_data_metadata_insert (metadata,
-							      tracker_property_get_name (field),
-							      str);
-			}
-		}
+	/* only single-value field supported */
+	g_return_val_if_fail (!tracker_property_get_multiple_values (property), NULL);
 
-		g_free (str);
+	iface = tracker_db_manager_get_db_interface ();
 
-		valid = tracker_db_result_set_iter_next (result_set);
-	}
-}
+	table_name = tracker_class_get_name (tracker_property_get_domain (property));
+	field_name = tracker_property_get_name (property);
 
-TrackerDataMetadata *
-tracker_data_query_metadata (TrackerClass *service,
-			     guint32	     service_id,
-			     gboolean        embedded)
-{
-	TrackerDBInterface  *iface;
-	TrackerDBResultSet  *result_set = NULL;
-	gchar		    *service_id_str;
-	TrackerDataMetadata *metadata;
+	subject_id = tracker_data_query_resource_id (subject);
 
-	metadata = tracker_data_metadata_new ();
+	if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_RESOURCE) {
+		/* retrieve object URI */
+		stmt = tracker_db_interface_create_statement (iface,
+			"SELECT "
+			"(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"%s\") "
+			"FROM \"%s\" WHERE ID = ?",
+			field_name, table_name);
+	} else {
+		/* retrieve literal */
+		stmt = tracker_db_interface_create_statement (iface,
+			"SELECT \"%s\" FROM \"%s\" WHERE ID = ?",
+			field_name, table_name);
+	}
 
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), metadata);
+	tracker_db_statement_bind_int (stmt, 0, subject_id);
+	result_set = tracker_db_statement_execute (stmt, NULL);
 
-	service_id_str = g_strdup_printf ("%d", service_id);
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	if (result_set) {
+		GValue value = { 0 };
 
+		_tracker_db_result_set_get_value (result_set, 0, &value);
+		result = get_string_for_value (&value);
 
-	result_set = tracker_data_manager_exec_proc (iface,
-						     "GetAllMetadata", 
-						     service_id_str,
-						     service_id_str,
-						     service_id_str, NULL);
-	if (result_set) {
-		result_set_to_metadata (result_set, metadata, embedded);
 		g_object_unref (result_set);
 	}
 
-	g_free (service_id_str);
+	g_object_unref (stmt);
 
-	return metadata;
+	return result;
 }
 
-TrackerDBResultSet *
-tracker_data_query_backup_metadata (TrackerClass *service)
+gchar **
+tracker_data_query_property_values (const gchar *subject,
+				    const gchar *predicate)
 {
 	TrackerDBInterface *iface;
+	TrackerDBStatement  *stmt;
 	TrackerDBResultSet *result_set;
+	TrackerProperty *property;
+	gchar		  **result = NULL;
+	guint32             subject_id;
+	gboolean            multiple_values;
+	gchar              *table_name;
+	const gchar        *field_name;
 
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), NULL);
-
-	iface = tracker_db_manager_get_db_interface_by_service (tracker_class_get_name (service));
-
-	result_set = tracker_data_manager_exec_proc (iface,
-						     "GetUserMetadataBackup", 
-						     NULL);
-	return result_set;
-}
-
-static gchar *
-db_get_metadata (TrackerClass *service,
-		 guint		 service_id,
-		 gboolean	 keywords)
-{
-	TrackerDBInterface *iface;
-	TrackerDBResultSet *result_set;
-	gchar		   *query;
-	GString		   *result;
-	gchar		   *str = NULL;
+	property = tracker_ontology_get_property_by_uri (predicate);
 
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	/* multi or single-value field supported */
 
-	result = g_string_new ("");
+	iface = tracker_db_manager_get_db_interface ();
 
-	if (service_id < 1) {
-		return g_string_free (result, FALSE);
+	multiple_values = tracker_property_get_multiple_values (property);
+	if (multiple_values) {
+		table_name = g_strdup_printf ("%s_%s",
+			tracker_class_get_name (tracker_property_get_domain (property)),
+			tracker_property_get_name (property));
+	} else {
+		table_name = g_strdup (tracker_class_get_name (tracker_property_get_domain (property)));
 	}
+	field_name = tracker_property_get_name (property);
+
+	subject_id = tracker_data_query_resource_id (subject);
 
-	if (keywords) {
-		query = g_strdup_printf ("Select MetadataValue From ServiceKeywordMetadata WHERE serviceID = %d",
-					 service_id);
+	if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_RESOURCE) {
+		/* retrieve object URI */
+		stmt = tracker_db_interface_create_statement (iface,
+			"SELECT "
+			"(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"%s\") "
+			"FROM \"%s\" WHERE ID = ?",
+			field_name, table_name);
 	} else {
-		query = g_strdup_printf ("Select MetadataValue From ServiceMetadata WHERE serviceID = %d",
-					 service_id);
+		/* retrieve literal */
+		stmt = tracker_db_interface_create_statement (iface,
+			"SELECT \"%s\" FROM \"%s\" WHERE ID = ?",
+			field_name, table_name);
 	}
 
-	result_set = tracker_db_interface_execute_query (iface, NULL, "%s", query);
-	g_free (query);
+	tracker_db_statement_bind_int (stmt, 0, subject_id);
+	result_set = tracker_db_statement_execute (stmt, NULL);
 
 	if (result_set) {
-		gboolean valid = TRUE;
-
-		while (valid) {
-			tracker_db_result_set_get (result_set, 0, &str, -1);
-			result = g_string_append (result, str);
-			result = g_string_append (result, " ");
-			valid = tracker_db_result_set_iter_next (result_set);
-			g_free (str);
-		}
-
-		g_object_unref (result_set);
-	}
+		gint i = 0;
 
-	return g_string_free (result, FALSE);
-}
+		result = g_new0 (gchar *, tracker_db_result_set_get_n_rows (result_set + 1));
 
-gchar *
-tracker_data_query_unparsed_metadata (TrackerClass *service,
-				      guint	      service_id)
-{
-	return db_get_metadata (service, service_id, TRUE);
-}
+		do {
+			GValue value = { 0 };
 
-gchar *
-tracker_data_query_parsed_metadata (TrackerClass *service,
-				    guint	    service_id)
-{
-	return db_get_metadata (service, service_id, FALSE);
-}
+			_tracker_db_result_set_get_value (result_set, 0, &value);
+			result[i++] = get_string_for_value (&value);
+		} while (tracker_db_result_set_iter_next (result_set));
 
-gchar **
-tracker_data_query_metadata_field_values (TrackerClass *service_def,
-					  guint32	  service_id,
-					  TrackerProperty   *field)
-{
-	TrackerDBInterface *iface;
-	TrackerDBResultSet *result_set = NULL;
-	gint		    metadata_key;
-	gchar		  **final_result = NULL;
-	gboolean	    is_numeric = FALSE;
-
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service_def),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
-	metadata_key = tracker_ontology_service_get_key_metadata (tracker_class_get_name (service_def),
-								  tracker_property_get_name (field));
-
-	if (metadata_key > 0) {
-		gchar *query;
-
-		query = g_strdup_printf ("SELECT KeyMetadata%d FROM Services WHERE id = '%d'",
-					 metadata_key,
-					 service_id);
-		result_set = tracker_db_interface_execute_query (iface,
-								 NULL,
-								 query,
-								 NULL);
-		g_free (query);
+		g_object_unref (result_set);
 	} else {
-		gchar *id_str;
-
-		id_str = tracker_guint32_to_string (service_id);
-
-		switch (tracker_property_get_data_type (field)) {
-		case TRACKER_PROPERTY_TYPE_KEYWORD:
-			result_set = tracker_db_interface_execute_procedure (iface, NULL,
-									     "GetMetadataKeyword",
-									     id_str,
-									     tracker_property_get_id (field),
-									     NULL);
-			break;
-		case TRACKER_PROPERTY_TYPE_INDEX:
-		case TRACKER_PROPERTY_TYPE_STRING:
-		case TRACKER_PROPERTY_TYPE_DOUBLE:
-			result_set = tracker_db_interface_execute_procedure (iface, NULL,
-									     "GetMetadata",
-									     id_str,
-									     tracker_property_get_id (field),
-									     NULL);
-			break;
-		case TRACKER_PROPERTY_TYPE_INTEGER:
-		case TRACKER_PROPERTY_TYPE_DATE:
-			result_set = tracker_db_interface_execute_procedure (iface, NULL,
-									     "GetMetadataNumeric",
-									     id_str,
-									     tracker_property_get_id (field),
-									     NULL);
-			is_numeric = TRUE;
-			break;
-		case TRACKER_PROPERTY_TYPE_FULLTEXT:
-			tracker_data_query_content (service_def, service_id);
-			break;
-		case TRACKER_PROPERTY_TYPE_BLOB:
-		case TRACKER_PROPERTY_TYPE_STRUCT:
-		case TRACKER_PROPERTY_TYPE_LINK:
-			/* not handled */
-		default:
-			break;
-		}
-		g_free (id_str);
+		result = g_new0 (gchar *, 1);
 	}
 
-	if (result_set) {
-		if (tracker_db_result_set_get_n_rows (result_set) > 1) {
-			g_warning ("More than one result in tracker_db_get_property_value");
-		}
-
-		if (!is_numeric) {
-			final_result = tracker_dbus_query_result_to_strv (result_set, 0, NULL);
-		} else {
-			final_result = tracker_dbus_query_result_numeric_to_strv (result_set, 0, NULL);
-		}
-
-		g_object_unref (result_set);
-	}
+	g_object_unref (stmt);
+	g_free (table_name);
 
-	return final_result;
+	return result;
 }
 
-gchar *
-tracker_data_query_content (TrackerClass *service,
-			    guint32	    service_id)
-{
-	TrackerDBInterface *iface;
-	TrackerProperty	   *field;
-	gchar		   *service_id_str, *contents = NULL;
-	TrackerDBResultSet *result_set;
-
-	service_id_str = tracker_guint32_to_string (service_id);
-	field = tracker_ontology_get_field_by_name ("File:Contents");
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_CONTENTS);
 
-	/* Delete contents if it has! */
-	result_set = tracker_db_interface_execute_procedure (iface, NULL,
-							     "GetContents",
-							     service_id_str,
-							     tracker_property_get_id (field),
-							     NULL);
-
-	if (result_set) {
-		tracker_db_result_set_get (result_set, 0, &contents, -1);
-		g_object_unref (result_set);
-	}
+TrackerDBResultSet *
+tracker_data_query_sparql (const gchar  *query,
+			   GError      **error)
+{
+	g_return_val_if_fail (query != NULL, NULL);
 
-	g_free (service_id_str);
+	/* TODO */
 
-	return contents;
+	return NULL;
 }
 
diff --git a/src/libtracker-data/tracker-data-query.h b/src/libtracker-data/tracker-data-query.h
index d4f6953..6743f89 100644
--- a/src/libtracker-data/tracker-data-query.h
+++ b/src/libtracker-data/tracker-data-query.h
@@ -27,56 +27,38 @@
 #include <glib.h>
 
 #include <libtracker-common/tracker-config.h>
-#include <libtracker-common/tracker-property.h>
 #include <libtracker-common/tracker-language.h>
 #include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-property.h>
 
 #include <libtracker-db/tracker-db-interface.h>
 #include <libtracker-db/tracker-db-file-info.h>
 #include <libtracker-db/tracker-db-index.h>
 
-#include "tracker-data-metadata.h"
-
 G_BEGIN_DECLS
 
+gchar *              tracker_data_query_property_value        (const gchar         *subject,
+							       const gchar         *predicate);
+gchar **             tracker_data_query_property_values       (const gchar         *subject,
+							       const gchar         *predicate);
+
 /* Metadata API */
-GPtrArray *          tracker_data_query_all_metadata          (const gchar         *service_type,
-							       const gchar         *service_id);
-TrackerDataMetadata *tracker_data_query_metadata              (TrackerClass      *service,
-							       guint32              service_id,
-							       gboolean             embedded);
-TrackerDBResultSet  *tracker_data_query_backup_metadata       (TrackerClass      *service);
-gchar *              tracker_data_query_parsed_metadata       (TrackerClass      *service,
-							       guint32              service_id);
-gchar *              tracker_data_query_unparsed_metadata     (TrackerClass      *service,
-							       guint32              service_id);
-gchar **             tracker_data_query_metadata_field_values (TrackerClass      *service_def,
-							       guint32              service_id,
+GPtrArray *          tracker_data_query_all_metadata          (guint32              resource_id);
+
+/* TODO */
+#if 0
+TrackerDBResultSet  *tracker_data_query_backup_metadata       (TrackerService      *service);
 							       TrackerProperty        *field_def);
+#endif
 
-/* Using path */
-gboolean             tracker_data_query_service_exists        (TrackerClass      *service,
-							       const gchar         *dirname,
-							       const gchar         *basename,
+gboolean             tracker_data_query_resource_exists        (const gchar         *uri,
 							       guint32             *service_id,
 							       time_t              *mtime);
-guint                tracker_data_query_service_type_id       (const gchar         *dirname,
-							       const gchar         *basename);
-GHashTable *         tracker_data_query_service_children      (TrackerClass      *service,
-							       const gchar         *dirname);
 
-/* Service API */
-G_CONST_RETURN gchar *
-                     tracker_data_query_service_type_by_id    (TrackerDBInterface  *iface,
-							       guint32              service_id);
+guint32              tracker_data_query_resource_id           (const gchar         *uri);
 
-/* Files API */
-guint32              tracker_data_query_file_id               (const gchar         *service_type,
-							       const gchar         *path);
-gchar *              tracker_data_query_file_id_as_string     (const gchar         *service_type,
-							       const gchar         *path);
-gchar *              tracker_data_query_content               (TrackerClass      *service,
-							       guint32              service_id);
+TrackerDBResultSet *tracker_data_query_sparql			(const gchar       *query,
+								 GError	          **error);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-data-search.c b/src/libtracker-data/tracker-data-search.c
index 4004e99..a10dbfd 100644
--- a/src/libtracker-data/tracker-data-search.c
+++ b/src/libtracker-data/tracker-data-search.c
@@ -42,44 +42,35 @@
 
 #define DEFAULT_METADATA_MAX_HITS 1024
 
-gchar **
-tracker_data_search_files_get (TrackerDBInterface *iface,
-			       const gchar	  *folder_path)
+gint *
+tracker_data_search_get_matches (const gchar       *search_string,
+				 gint		   *result_length)
 {
-	TrackerDBResultSet *result_set;
-	GPtrArray	   *array;
+	GArray		    *hits;
+	TrackerQueryTree    *tree;
+	gint		    *result;
+	gint                 i;
 
-	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (iface), NULL);
-	g_return_val_if_fail (folder_path != NULL, NULL);
+	g_return_val_if_fail (search_string != NULL, NULL);
+	g_return_val_if_fail (result_length != NULL, NULL);
 
-	result_set = tracker_data_manager_exec_proc (iface,
-						     "GetFileChildren",
-						     folder_path,
-						     NULL);
-	array = g_ptr_array_new ();
+	tree = tracker_query_tree_new (search_string,
+				       tracker_data_manager_get_config (),
+				       tracker_data_manager_get_language ());
+	hits = tracker_query_tree_get_hits (tree, 0, 0);
 
-	if (result_set) {
-		gchar	 *name, *prefix;
-		gboolean  valid = TRUE;
+	result = g_new0 (gint, hits->len);
+	*result_length = hits->len;
 
-		while (valid) {
-			tracker_db_result_set_get (result_set,
-						   1, &prefix,
-						   2, &name,
-						   -1);
+	for (i = 0; i < hits->len; i++) {
+		TrackerDBIndexItemRank	rank;
 
-			g_ptr_array_add (array, g_build_filename (prefix, name, NULL));
+		rank = g_array_index (hits, TrackerDBIndexItemRank, i);
 
-			g_free (prefix);
-			g_free (name);
-			valid = tracker_db_result_set_iter_next (result_set);
-		}
-
-		g_object_unref (result_set);
+		result[i] = rank.service_id;
 	}
 
-	g_ptr_array_add (array, NULL);
-
-	return (gchar**) g_ptr_array_free (array, FALSE);
+	return result;
 }
 
+
diff --git a/src/libtracker-data/tracker-data-search.h b/src/libtracker-data/tracker-data-search.h
index b25708b..3205e48 100644
--- a/src/libtracker-data/tracker-data-search.h
+++ b/src/libtracker-data/tracker-data-search.h
@@ -26,13 +26,18 @@
 
 #include <glib.h>
 
+#include <libtracker-common/tracker-language.h>
+#include <libtracker-common/tracker-ontology.h>
+
 #include <libtracker-db/tracker-db-interface.h>
+#include <libtracker-db/tracker-db-file-info.h>
+#include <libtracker-db/tracker-db-index.h>
 
 G_BEGIN_DECLS
 
-/* Files API */
-gchar **	    tracker_data_search_files_get		 (TrackerDBInterface  *iface,
-								  const gchar	      *folder_path);
+/* Search API */
+gint		   *tracker_data_search_get_matches				(const gchar       *search_string,
+										 gint		   *result_length);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index fbc132b..6e9e3b2 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -23,9 +23,12 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <time.h>
 
+#include <libtracker-common/tracker-common.h>
 #include <libtracker-common/tracker-type-utils.h>
 #include <libtracker-common/tracker-file-utils.h>
+#include <libtracker-common/tracker-ontology.h>
 
 #include <libtracker-db/tracker-db-index-manager.h>
 #include <libtracker-db/tracker-db-manager.h>
@@ -35,15 +38,53 @@
 #include "tracker-data-update.h"
 #include "tracker-data-query.h"
 
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDFS_PREFIX TRACKER_RDFS_PREFIX
+
+typedef struct _TrackerDataUpdateBuffer TrackerDataUpdateBuffer;
+typedef struct _TrackerDataUpdateBufferProperty TrackerDataUpdateBufferProperty;
+typedef struct _TrackerDataUpdateBufferTable TrackerDataUpdateBufferTable;
+typedef struct _TrackerDataBlankBuffer TrackerDataBlankBuffer;
+
+struct _TrackerDataUpdateBuffer {
+	GHashTable *resource_cache;
+	gchar *subject;
+	guint32 id;
+	GHashTable *tables;
+};
+
+struct _TrackerDataUpdateBufferProperty {
+	gchar *name;
+	GValue value;
+};
+
+struct _TrackerDataUpdateBufferTable {
+	gboolean insert;
+	gboolean multiple_values;
+	GArray *properties;
+};
+
+/* buffer for anonymous blank nodes
+ * that are not yet in the database */
+struct _TrackerDataBlankBuffer {
+	GHashTable *table;
+	gchar *subject;
+	GArray *predicates;
+	GArray *objects;
+};
+
 typedef struct {
-	TrackerClass *service;
-	guint32 iid_value;
+	const gchar *uri;
 	TrackerLanguage *language;
 	TrackerConfig *config;
 } ForeachInMetadataInfo;
 
 
-guint32
+static gboolean auto_commit = TRUE;
+static TrackerDataUpdateBuffer update_buffer;
+static TrackerDataBlankBuffer blank_buffer;
+
+static guint32
 tracker_data_update_get_new_service_id (TrackerDBInterface *iface)
 {
 	guint32		    files_max;
@@ -55,788 +96,1484 @@ tracker_data_update_get_new_service_id (TrackerDBInterface *iface)
 		return ++max;
 	}
 
-	temp_iface = tracker_db_manager_get_db_interface (TRACKER_DB_FILE_METADATA);
+	temp_iface = tracker_db_manager_get_db_interface ();
 
 	result_set = tracker_db_interface_execute_query (temp_iface, NULL,
-							 "SELECT MAX(ID) AS A FROM Services");
+							 "SELECT MAX(ID) AS A FROM \"rdfs:Resource\"");
 
 	if (result_set) {
 		GValue val = {0, };
 		_tracker_db_result_set_get_value (result_set, 0, &val);
 		if (G_VALUE_TYPE (&val) == G_TYPE_INT) {
-			max = g_value_get_int (&val);
+			files_max = g_value_get_int (&val);
+			max = MAX (files_max, max);
+			g_value_unset (&val);
 		}
-		g_value_unset (&val);
 		g_object_unref (result_set);
 	}
 
-	temp_iface = tracker_db_manager_get_db_interface (TRACKER_DB_EMAIL_METADATA);
+	return ++max;
+}
 
-	result_set = tracker_db_interface_execute_query (temp_iface, NULL,
-							 "SELECT MAX(ID) AS A FROM Services");
+static TrackerDataUpdateBufferTable *
+cache_table_new (gboolean multiple_values)
+{
+	TrackerDataUpdateBufferTable *table;
 
-	if (result_set) {
-		GValue val = {0, };
-		_tracker_db_result_set_get_value (result_set, 0, &val);
-		if (G_VALUE_TYPE (&val) == G_TYPE_INT) {
-			files_max = g_value_get_int (&val);
-			max = MAX (files_max, max);
-		}
-		g_value_unset (&val);
-		g_object_unref (result_set);
+	table = g_slice_new0 (TrackerDataUpdateBufferTable);
+	table->multiple_values = multiple_values;
+	table->properties = g_array_sized_new (FALSE, FALSE, sizeof (TrackerDataUpdateBufferProperty), 4);
+
+	return table;
+}
+
+static void
+cache_table_free (TrackerDataUpdateBufferTable *table)
+{
+	TrackerDataUpdateBufferProperty *property;
+	gint                            i;
+
+	for (i = 0; i < table->properties->len; i++) {
+		property = &g_array_index (table->properties, TrackerDataUpdateBufferProperty, i);
+		g_free (property->name);
+		g_value_unset (&property->value);
 	}
 
-	return ++max;
+	g_array_free (table->properties, TRUE);
+	g_slice_free (TrackerDataUpdateBufferTable, table);
 }
 
-gboolean
-tracker_data_update_create_service (TrackerClass *service,
-				    guint32	    service_id,
-				    const gchar	   *dirname,
-				    const gchar	   *basename,
-				    GHashTable     *metadata)
+static TrackerDataUpdateBufferTable *
+cache_ensure_table (const gchar            *table_name,
+		    gboolean                multiple_values)
 {
-	TrackerDBInterface *iface;
-	TrackerDBResultSet *result_set;
-	guint32	volume_id = 1;
-	gchar *id_str, *service_type_id_str, *path, *volume_id_str;
-	gboolean is_dir, is_symlink;
+	TrackerDataUpdateBufferTable *table;
 
-	if (!service) {
-		return FALSE;
+	table = g_hash_table_lookup (update_buffer.tables, table_name);
+	if (table == NULL) {
+		table = cache_table_new (multiple_values);
+		g_hash_table_insert (update_buffer.tables, g_strdup (table_name), table);
+		table->insert = multiple_values;
 	}
 
-	/* retrieve VolumeID */
-	iface = tracker_db_manager_get_db_interface (TRACKER_DB_COMMON);
-	result_set = tracker_db_interface_execute_procedure (iface, NULL,
-							     "GetVolumeByPath",
-							     dirname,
-							     dirname,
-							     NULL);
-	if (result_set) {
-		tracker_db_result_set_get (result_set, 0, &volume_id, -1);
-		g_object_unref (result_set);
+	return table;
+}
+
+static void
+cache_insert_row (const gchar            *table_name)
+{
+	TrackerDataUpdateBufferTable    *table;
+
+	table = cache_ensure_table (table_name, FALSE);
+	table->insert = TRUE;
+}
+
+static void
+cache_insert_value (const gchar            *table_name,
+		    const gchar            *field_name,
+		    GValue                 *value,
+		    gboolean                multiple_values)
+{
+	TrackerDataUpdateBufferTable    *table;
+	TrackerDataUpdateBufferProperty  property;
+
+	property.name = g_strdup (field_name);
+	property.value = *value;
+
+	table = cache_ensure_table (table_name, multiple_values);
+	g_array_append_val (table->properties, property);
+}
+
+static void
+tracker_data_begin_implicit_transaction (void)
+{
+	TrackerDBInterface *iface;
+
+	update_buffer.resource_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+	update_buffer.tables = g_hash_table_new_full (g_str_hash, g_str_equal,
+						      g_free, (GDestroyNotify) cache_table_free);
+	if (blank_buffer.table == NULL) {
+		blank_buffer.table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 	}
-	volume_id_str = tracker_guint32_to_string (volume_id);
 
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	iface = tracker_db_manager_get_db_interface ();
 
-	id_str = tracker_guint32_to_string (service_id);
-	service_type_id_str = tracker_gint_to_string (tracker_class_get_id (service));
+	tracker_db_interface_start_transaction (iface);
+}
 
-	path = g_build_filename (dirname, basename, NULL);
+static guint32
+query_resource_id (const gchar *uri)
+{
+	guint32 id;
 
-	is_dir = g_file_test (path, G_FILE_TEST_IS_DIR);
-	is_symlink = g_file_test (path, G_FILE_TEST_IS_SYMLINK);
+	id = GPOINTER_TO_UINT (g_hash_table_lookup (update_buffer.resource_cache, uri));
 
-	tracker_db_interface_execute_procedure (iface, NULL, "CreateService",
-						id_str,
-						dirname,
-						basename,
-						service_type_id_str,
-						is_dir ? "Folder" : g_hash_table_lookup (metadata, "File:Mime"),
-						g_hash_table_lookup (metadata, "File:Size"),
-						is_dir ? "1" : "0",
-						is_symlink ? "1" : "0",
-						"0", /* Offset */
-						g_hash_table_lookup (metadata, "File:Modified"),
-						volume_id_str, /* Aux ID */
-						NULL);
+	if (id == 0) {
+		id = tracker_data_query_resource_id (uri);
 
-	g_free (id_str);
-	g_free (service_type_id_str);
-	g_free (volume_id_str);
-	g_free (path);
+		if (id) {
+			g_hash_table_insert (update_buffer.resource_cache, g_strdup (uri), GUINT_TO_POINTER (id));
+		}
+	}
 
-	return TRUE;
+	return id;
 }
 
-void
-tracker_data_update_delete_service (TrackerClass *service,
-				    guint32	    service_id)
+static guint32
+ensure_resource_id (const gchar *uri)
 {
+	TrackerDBInterface *iface, *common;
+	TrackerDBStatement *stmt;
 
-	TrackerDBInterface *iface;
-	gchar *service_id_str;
+	guint32 id;
 
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-	g_return_if_fail (service_id >= 1);
+	id = query_resource_id (uri);
 
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	if (id == 0) {
+		/* object resource not yet in the database */
+		common = tracker_db_manager_get_db_interface ();
+		iface = tracker_db_manager_get_db_interface ();
+
+		id = tracker_data_update_get_new_service_id (common);
+		stmt = tracker_db_interface_create_statement (iface, "INSERT INTO \"rdfs:Resource\" (ID, Uri, Modified, Available) VALUES (?, ?, ?, 1)");
+		tracker_db_statement_bind_int (stmt, 0, id);
+		tracker_db_statement_bind_text (stmt, 1, uri);
+		tracker_db_statement_bind_int64 (stmt, 2, (gint64) time(NULL));
+		tracker_db_statement_execute (stmt, NULL);
+		g_object_unref (stmt);
+
+		g_hash_table_insert (update_buffer.resource_cache, g_strdup (uri), GUINT_TO_POINTER (id));
+	}
+
+	return id;
+}
 
-	service_id_str = tracker_guint32_to_string (service_id);
+static void
+statement_bind_gvalue (TrackerDBStatement *stmt,
+		       gint                index,
+		       const GValue       *value)
+{
+	switch (G_VALUE_TYPE (value)) {
+	case G_TYPE_STRING:
+		tracker_db_statement_bind_text (stmt, index, g_value_get_string (value));
+		break;
+	case G_TYPE_INT:
+		tracker_db_statement_bind_int (stmt, index, g_value_get_int (value));
+		break;
+	case G_TYPE_INT64:
+		tracker_db_statement_bind_int64 (stmt, index, g_value_get_int64 (value));
+		break;
+	case G_TYPE_BOOLEAN:
+		tracker_db_statement_bind_int (stmt, index, g_value_get_boolean (value));
+		break;
+	case G_TYPE_DOUBLE:
+		tracker_db_statement_bind_double (stmt, index, g_value_get_double (value));
+		break;
+	}
+}
 
-	/* Delete from services table */
-	tracker_db_interface_execute_procedure (iface,
-						NULL,
-						"DeleteService1",
-						service_id_str,
-						NULL);
+static void
+tracker_data_update_buffer_flush (void)
+{
+	TrackerDBInterface             *iface;
+	TrackerDBStatement             *stmt;
+	TrackerDataUpdateBufferTable    *table;
+	TrackerDataUpdateBufferProperty *property;
+	GHashTableIter                  iter;
+	const gchar                    *table_name;
+	GString                        *sql;
+	int                             i;
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	g_hash_table_iter_init (&iter, update_buffer.tables);
+	while (g_hash_table_iter_next (&iter, (gpointer*) &table_name, (gpointer*) &table)) {
+		if (table->multiple_values) {
+			for (i = 0; i < table->properties->len; i++) {
+				property = &g_array_index (table->properties, TrackerDataUpdateBufferProperty, i);
+
+				stmt = tracker_db_interface_create_statement (iface,
+					"INSERT OR IGNORE INTO \"%s\" (ID, \"%s\") VALUES (?, ?)",
+					table_name,
+					property->name);
+				tracker_db_statement_bind_int (stmt, 0, update_buffer.id);
+				statement_bind_gvalue (stmt, 1, &property->value);
+				tracker_db_statement_execute (stmt, NULL);
+				g_object_unref (stmt);
+			}
+		} else {
+			if (table->insert) {
+				/* ensure we have a row for the subject id */
+				stmt = tracker_db_interface_create_statement (iface,
+					"INSERT OR IGNORE INTO \"%s\" (ID) VALUES (?)",
+					table_name);
+				tracker_db_statement_bind_int (stmt, 0, update_buffer.id);
+				tracker_db_statement_execute (stmt, NULL);
+				g_object_unref (stmt);
+			}
+
+			if (table->properties->len == 0) {
+				continue;
+			}
+
+			sql = g_string_new ("UPDATE ");
+			g_string_append_printf (sql, "\"%s\" SET ", table_name);
+
+			for (i = 0; i < table->properties->len; i++) {
+				property = &g_array_index (table->properties, TrackerDataUpdateBufferProperty, i);
+				if (i > 0) {
+					g_string_append (sql, ", ");
+				}
+				g_string_append_printf (sql, "\"%s\" = ?", property->name);
+			}
+
+			g_string_append (sql, " WHERE ID = ?");
+
+			stmt = tracker_db_interface_create_statement (iface, "%s", sql->str);
+			tracker_db_statement_bind_int (stmt, i, update_buffer.id);
+
+			for (i = 0; i < table->properties->len; i++) {
+				property = &g_array_index (table->properties, TrackerDataUpdateBufferProperty, i);
+				statement_bind_gvalue (stmt, i, &property->value);
+			}
+
+			tracker_db_statement_execute (stmt, NULL);
+			g_object_unref (stmt);
+
+			g_string_free (sql, TRUE);
+		}
+	}
 
-	g_free (service_id_str);
+	g_hash_table_remove_all (update_buffer.tables);
+	g_free (update_buffer.subject);
+	update_buffer.subject = NULL;
 }
 
-void
-tracker_data_update_delete_service_recursively (TrackerClass *service,
-						const gchar    *service_path)
+static void
+tracker_data_blank_buffer_flush (void)
 {
-	TrackerDBInterface *iface;
+	/* end of blank node */
+	gint i, id;
+	gchar *subject;
+	gchar *blank_uri;
+	const gchar *sha1;
+	GChecksum *checksum;
+
+	subject = blank_buffer.subject;
+	blank_buffer.subject = NULL;
+
+	/* we share anonymous blank nodes with identical properties
+	   to avoid blowing up the database with duplicates */
+
+	checksum = g_checksum_new (G_CHECKSUM_SHA1);
+
+	/* generate hash uri from data to find resource
+	   assumes no collisions due to generally little contents of anonymous nodes */
+	for (i = 0; i < blank_buffer.predicates->len; i++) {
+		g_checksum_update (checksum, g_array_index (blank_buffer.predicates, guchar *, i), -1);
+		g_checksum_update (checksum, g_array_index (blank_buffer.objects, guchar *, i), -1);
+	}
+
+	sha1 = g_checksum_get_string (checksum);
+
+	/* generate name based uuid */
+	blank_uri = g_strdup_printf ("urn:uuid:%.8s-%.4s-%.4s-%.4s-%.12s",
+		sha1, sha1 + 8, sha1 + 12, sha1 + 16, sha1 + 20);
 
-	g_return_if_fail (TRACKER_IS_CLASS (service));
-	g_return_if_fail (service_path != NULL);
+	id = tracker_data_query_resource_id (blank_uri);
 
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	if (id == 0) {
+		/* uri not found
+		   replay piled up statements to create resource */
+		for (i = 0; i < blank_buffer.predicates->len; i++) {
+			tracker_data_insert_statement (blank_uri,
+				g_array_index (blank_buffer.predicates, gchar *, i),
+				g_array_index (blank_buffer.objects, gchar *, i));
+		}
+		tracker_data_update_buffer_flush ();
+	}
 
-	/* We have to give two arguments. One is the actual path and
-	 * the second is a string representing the likeness to match
-	 * sub paths. Not sure how to do this in the .sql file
-	 * instead.
-	 */
-	tracker_db_interface_execute_procedure (iface,
-						NULL,
-						"DeleteServiceRecursively",
-						service_path,
-						service_path,
-						NULL);
+	/* free piled up statements */
+	for (i = 0; i < blank_buffer.predicates->len; i++) {
+		g_free (g_array_index (blank_buffer.predicates, gchar *, i));
+		g_free (g_array_index (blank_buffer.objects, gchar *, i));
+	}
+	g_array_free (blank_buffer.predicates, TRUE);
+	g_array_free (blank_buffer.objects, TRUE);
+
+	g_hash_table_insert (blank_buffer.table, subject, blank_uri);
+	g_checksum_free (checksum);
 }
 
-gboolean
-tracker_data_update_move_service (TrackerClass *service,
-				  const gchar	*from,
-				  const gchar	*to)
+static void
+cache_create_service_decomposed (TrackerClass           *cl)
 {
 	TrackerDBInterface *iface;
-	GError *error = NULL;
-	gchar *from_dirname;
-	gchar *from_basename;
-	gchar *to_dirname;
-	gchar *to_basename;
-	gboolean retval = TRUE;
-
-	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
-	g_return_val_if_fail (from != NULL, FALSE);
-	g_return_val_if_fail (to != NULL, FALSE);
-
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
-
-	tracker_file_get_path_and_name (from,
-					&from_dirname,
-					&from_basename);
-	tracker_file_get_path_and_name (to,
-					&to_dirname,
-					&to_basename);
-
-	tracker_db_interface_execute_procedure (iface,
-						&error,
-						"MoveService",
-						to_dirname, to_basename,
-						from_dirname, from_basename,
-						NULL);
+	TrackerClass       **super_classes;
+	GValue              gvalue = { 0 };
 
-	if (error) {
-		g_warning ("%s", error->message);
-		g_error_free (error);
-		retval = FALSE;
+	iface = tracker_db_manager_get_db_interface ();
+
+	/* also create instance of all super classes */
+	super_classes = tracker_class_get_super_classes (cl);
+	while (*super_classes) {
+		cache_create_service_decomposed (*super_classes);
+		super_classes++;
 	}
 
-	g_free (to_dirname);
-	g_free (to_basename);
-	g_free (from_dirname);
-	g_free (from_basename);
+	g_value_init (&gvalue, G_TYPE_INT);
+
+	cache_insert_row (tracker_class_get_name (cl));
 
-	return retval;
+	g_value_set_int (&gvalue, ensure_resource_id (tracker_class_get_uri (cl)));
+	cache_insert_value ("rdfs:Resource_rdf:type", "rdf:type", &gvalue, TRUE);
 }
 
-void
-tracker_data_update_delete_all_metadata (TrackerClass *service,
-					 guint32	 service_id)
+guint32
+tracker_data_insert_resource (const gchar *uri)
 {
-	TrackerDBInterface *iface;
-	gchar *service_id_str;
-
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
-
-	service_id_str = tracker_guint32_to_string (service_id);
-
-	/* Delete from ServiceMetadata, ServiceKeywordMetadata,
-	 * ServiceNumberMetadata.
-	 */
-	tracker_db_interface_execute_procedure (iface,
-						NULL,
-						"DeleteServiceMetadata",
-						service_id_str,
-						NULL);
-	tracker_db_interface_execute_procedure (iface,
-						NULL,
-						"DeleteServiceKeywordMetadata",
-						service_id_str,
-						NULL);
-	tracker_db_interface_execute_procedure (iface,
-						NULL,
-						"DeleteServiceNumericMetadata",
-						service_id_str,
-						NULL);
-	g_free (service_id_str);
+	guint32 id;
+
+	if (auto_commit) {
+		tracker_data_begin_implicit_transaction ();
+	}
+
+	id = ensure_resource_id (uri);
+
+	if (auto_commit) {
+		tracker_data_commit_transaction ();
+	}
+
+	return id;
 }
 
-void
-tracker_data_update_set_metadata (TrackerClass *service,
-				  guint32	  service_id,
-				  TrackerProperty	 *field,
-				  const gchar	 *value,
-				  const gchar	 *parsed_value)
+gboolean
+tracker_data_update_resource_uri (const gchar *old_uri,
+				  const gchar *new_uri)
 {
-	TrackerDBInterface *iface;
-	gint metadata_key;
-	gint collate_key;
-	gchar *id_str;
+	guint32 resource_id;
+	TrackerDBInterface  *iface;
+	TrackerDBStatement  *stmt;
 
-	if(!strlen(value))
-		return;
+	resource_id = tracker_data_query_resource_id (old_uri);
+	if (resource_id == 0) {
+		/* old uri does not exist */
+		return FALSE;
+	}
+
+	if (tracker_data_query_resource_id (new_uri) > 0) {
+		/* new uri already exists */
+		return FALSE;
+	}
 
-	id_str = tracker_guint32_to_string (service_id);
+	iface = tracker_db_manager_get_db_interface ();
 
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	/* update URI in rdfs:Resource table */
 
-	switch (tracker_property_get_data_type (field)) {
-	case TRACKER_PROPERTY_TYPE_KEYWORD:
-		tracker_db_interface_execute_procedure (iface, NULL,
-							"SetMetadataKeyword",
-							id_str,
-							tracker_property_get_id (field),
-							value,
-							NULL);
-		break;
+	stmt = tracker_db_interface_create_statement (iface, "UPDATE \"rdfs:Resource\" SET Uri = ? WHERE ID = ?");
+	tracker_db_statement_bind_text (stmt, 0, new_uri);
+	tracker_db_statement_bind_int (stmt, 1, resource_id);
+	tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	return TRUE;
+}
+
+static void
+cache_set_metadata_decomposed (TrackerProperty	*property,
+			       const gchar	*value)
+{
+	guint32		    object_id;
+	gboolean            multiple_values;
+	gchar              *table_name;
+	const gchar        *field_name;
+	TrackerProperty   **super_properties;
+	GValue gvalue = { 0 };
+
+	/* also insert super property values */
+	super_properties = tracker_property_get_super_properties (property);
+	while (*super_properties) {
+		cache_set_metadata_decomposed (*super_properties, value);
+		super_properties++;
+	}
+
+	multiple_values = tracker_property_get_multiple_values (property);
+	if (multiple_values) {
+		table_name = g_strdup_printf ("%s_%s",
+			tracker_class_get_name (tracker_property_get_domain (property)),
+			tracker_property_get_name (property));
+	} else {
+		table_name = g_strdup (tracker_class_get_name (tracker_property_get_domain (property)));
+	}
+	field_name = tracker_property_get_name (property);
 
-	case TRACKER_PROPERTY_TYPE_INDEX:
+	switch (tracker_property_get_data_type (property)) {
 	case TRACKER_PROPERTY_TYPE_STRING:
-	case TRACKER_PROPERTY_TYPE_DOUBLE:
-		tracker_db_interface_execute_procedure (iface, NULL,
-							"SetMetadata",
-							id_str,
-							tracker_property_get_id (field),
-							parsed_value,
-							value,
-							value,
-							NULL);
+		g_value_init (&gvalue, G_TYPE_STRING);
+		g_value_set_string (&gvalue, value);
 		break;
-
 	case TRACKER_PROPERTY_TYPE_INTEGER:
+		g_value_init (&gvalue, G_TYPE_INT);
+		g_value_set_int (&gvalue, atoi (value));
+		break;
+	case TRACKER_PROPERTY_TYPE_BOOLEAN:
+		g_value_init (&gvalue, G_TYPE_BOOLEAN);
+		g_value_set_boolean (&gvalue, strcmp (value, "true") == 0);
+		break;
+	case TRACKER_PROPERTY_TYPE_DOUBLE:
+		g_value_init (&gvalue, G_TYPE_DOUBLE);
+		g_value_set_double (&gvalue, atof (value));
+		break;
 	case TRACKER_PROPERTY_TYPE_DATE:
-		tracker_db_interface_execute_procedure (iface, NULL,
-							"SetMetadataNumeric",
-							id_str,
-							tracker_property_get_id (field),
-							value,
-							NULL);
+	case TRACKER_PROPERTY_TYPE_DATETIME:
+		g_value_init (&gvalue, G_TYPE_INT);
+		g_value_set_int (&gvalue, tracker_string_to_date (value));
 		break;
-
-	case TRACKER_PROPERTY_TYPE_FULLTEXT:
-		tracker_data_update_set_content (service, service_id, value);
+	case TRACKER_PROPERTY_TYPE_RESOURCE:
+		object_id = ensure_resource_id (value);
+		g_value_init (&gvalue, G_TYPE_INT);
+		g_value_set_int (&gvalue, object_id);
 		break;
-
-	case TRACKER_PROPERTY_TYPE_BLOB:
-	case TRACKER_PROPERTY_TYPE_STRUCT:
-	case TRACKER_PROPERTY_TYPE_LINK:
-		/* not handled */
 	default:
-		break;
+		return;
 	}
 
-	metadata_key = tracker_ontology_service_get_key_metadata (tracker_class_get_name (service),
-								  tracker_property_get_name (field));
-	if (metadata_key > 0) {
-		gchar *val;
+	cache_insert_value (table_name, field_name, &gvalue, multiple_values);
+
+	g_free (table_name);
+}
+
+
+static void
+send_text_to_index (TrackerConfig  *config,
+		    TrackerLanguage*language,
+		    gint	    service_id,
+		    const gchar    *text,
+		    gboolean	    full_parsing,
+		    gint	    weight_factor)
+{
+	TrackerDBIndex *lindex;
+	GHashTable     *parsed;
+	GHashTableIter	iter;
+	gpointer	key, value;
 
-		val = tracker_escape_string (value);
+	if (!text) {
+		return;
+	}
 
-		tracker_db_interface_execute_query (iface, NULL,
-						    "update Services set KeyMetadata%d = '%s' where id = %d",
-						    metadata_key,
-						    val,
-						    service_id);
-		g_free (val);
-	} else if (tracker_property_get_data_type (field) == TRACKER_PROPERTY_TYPE_DATE &&
-		   (strcmp (tracker_property_get_name (field), "File:Modified") == 0)) {
-		/* Handle mtime */
-		tracker_db_interface_execute_query (iface, NULL,
-						    "update Services set IndexTime = '%s' where ID = %d",
-						    value,
-						    service_id);
+	if (full_parsing) {
+		parsed = tracker_parser_text (NULL,
+					      text,
+					      weight_factor,
+					      language,
+					      tracker_config_get_max_words_to_index (config),
+					      tracker_config_get_max_word_length (config),
+					      tracker_config_get_min_word_length (config),
+					      tracker_config_get_enable_stemmer (config),
+					      FALSE);
+	} else {
+		/* We dont know the exact property weight.
+		   Big value works.
+		 */
+		parsed = tracker_parser_text_fast (NULL,
+						   text,
+						   weight_factor);
 	}
 
-	collate_key = tracker_ontology_service_get_key_collate (tracker_class_get_name (service),
-								tracker_property_get_name (field));
-	if (collate_key > 0) {
-		gchar *val;
-		
-		val = tracker_escape_string (value);
-		
-		tracker_db_interface_execute_query (iface, NULL,
-			       "update Services set KeyMetadataCollation%d = CollateKey('%s') where id = %d",
-			       collate_key,
-			       val,
-			       service_id);
+	g_hash_table_iter_init (&iter, parsed);
+
+	lindex = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_RESOURCES);
 
-		g_free (val);
+	while (g_hash_table_iter_next (&iter, &key, &value)) {
+		tracker_db_index_add_word (lindex,
+					   key,
+					   service_id,
+					   GPOINTER_TO_INT (value));
 	}
 
-	g_free (id_str);
+	g_hash_table_unref (parsed);
 }
 
-void
-tracker_data_update_delete_metadata (TrackerClass *service,
-				     guint32	     service_id,
-				     TrackerProperty   *field,
-				     const gchar    *value)
+static void
+index_text_with_parsing (TrackerConfig  *config,
+			 TrackerLanguage*language,
+			 gint		 service_id,
+			 const gchar	*content,
+			 gint		 weight_factor)
 {
-	TrackerDBInterface *iface;
-	gint metadata_key;
-	gchar *id_str;
-
-	id_str = tracker_guint32_to_string (service_id);
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
-
-	switch (tracker_property_get_data_type (field)) {
-	case TRACKER_PROPERTY_TYPE_KEYWORD:
-		if (!value) {
-			g_debug ("Trying to remove keyword field with no specific value");
-			tracker_db_interface_execute_procedure (iface, NULL,
-								"DeleteMetadataKeyword",
-								id_str,
-								tracker_property_get_id (field),
-								NULL);
-		} else {
-			tracker_db_interface_execute_procedure (iface, NULL,
-								"DeleteMetadataKeywordValue",
-								id_str,
-								tracker_property_get_id (field),
-								value,
-								NULL);
-		}
-		break;
+	send_text_to_index (config,
+			    language,
+			    service_id,
+			    content,
+			    TRUE,
+			    weight_factor);
+}
+
+static void
+unindex_text_with_parsing (TrackerConfig  *config,
+			   TrackerLanguage*language,
+			   gint		   service_id,
+			   const gchar	  *content,
+			   gint		   weight_factor)
+{
+	send_text_to_index (config,
+			    language,
+			    service_id,
+			    content,
+			    TRUE,
+			    weight_factor * -1);
+}
+
+static void
+index_text_no_parsing (TrackerConfig  *config,
+		       TrackerLanguage*language,
+		       gint	       service_id,
+		       const gchar    *content,
+		       gchar	       weight_factor)
+{
+	send_text_to_index (config,
+			    language,
+			    service_id,
+			    content,
+			    FALSE,
+			    weight_factor);
+}
+
+static void
+unindex_text_no_parsing (TrackerConfig  *config,
+			 TrackerLanguage*language,
+			 gint		 service_id,
+			 const gchar	*content,
+			 gint		 weight_factor)
+{
+	send_text_to_index (config,
+			    language,
+			    service_id,
+			    content,
+			    FALSE,
+			    weight_factor * -1);
+}
+
+static void
+delete_resource_type (gint resource_id,
+		      TrackerClass           *cl)
+{
+	TrackerDBInterface  *iface;
+	TrackerDBStatement  *stmt;
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	/* remove entry from rdf:type table */
+	stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"rdfs:Resource_rdf:type\" WHERE ID = ? AND \"rdf:type\" = ?");
+	tracker_db_statement_bind_int (stmt, 0, resource_id);
+	tracker_db_statement_bind_int (stmt, 1, ensure_resource_id (tracker_class_get_uri (cl)));
+	tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	/* remove row from class table */
+	stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"%s\" WHERE ID = ?", tracker_class_get_name (cl));
+	tracker_db_statement_bind_int (stmt, 0, resource_id);
+	tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+}
+
+static void
+delete_metadata_decomposed (gint resource_id,
+			    TrackerProperty	*property,
+			    const gchar	*value)
+{
+	TrackerDBInterface  *iface;
+	TrackerDBStatement  *stmt;
+	guint32		    object_id;
+	gboolean            multiple_values;
+	const gchar *class_name, *property_name;
+	TrackerProperty   **super_properties;
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	multiple_values = tracker_property_get_multiple_values (property);
+	class_name = tracker_class_get_name (tracker_property_get_domain (property));
+	property_name = tracker_property_get_name (property);
+	if (multiple_values) {
+		/* delete rows for multiple value properties */
+		stmt = tracker_db_interface_create_statement (iface,
+			"DELETE FROM \"%s_%s\" WHERE ID = ? AND \"%s\" = ?",
+			class_name, property_name, property_name);
+	} else {
+		/* just set value to NULL for single value properties */
+		stmt = tracker_db_interface_create_statement (iface,
+			"UPDATE \"%s\" SET \"%s\" = NULL WHERE ID = ? AND \"%s\" = ?",
+			class_name, property_name, property_name);
+	}
+
+	tracker_db_statement_bind_int (stmt, 0, resource_id);
 
-	case TRACKER_PROPERTY_TYPE_INDEX:
+	switch (tracker_property_get_data_type (property)) {
 	case TRACKER_PROPERTY_TYPE_STRING:
-	case TRACKER_PROPERTY_TYPE_DOUBLE:
-		tracker_db_interface_execute_procedure (iface, NULL,
-							"DeleteMetadata",
-							id_str,
-							tracker_property_get_id (field),
-							NULL);
+		tracker_db_statement_bind_text (stmt, 1, value);
 		break;
-
 	case TRACKER_PROPERTY_TYPE_INTEGER:
+		tracker_db_statement_bind_int (stmt, 1, atoi (value));
+		break;
+	case TRACKER_PROPERTY_TYPE_BOOLEAN:
+		tracker_db_statement_bind_int (stmt, 1, strcmp (value, "true") == 0);
+		break;
+	case TRACKER_PROPERTY_TYPE_DOUBLE:
+		tracker_db_statement_bind_double (stmt, 1, atof (value));
+		break;
 	case TRACKER_PROPERTY_TYPE_DATE:
-		tracker_db_interface_execute_procedure (iface, NULL,
-							"DeleteMetadataNumeric",
-							id_str,
-							tracker_property_get_id (field),
-							NULL);
+	case TRACKER_PROPERTY_TYPE_DATETIME:
+		tracker_db_statement_bind_int (stmt, 1, tracker_string_to_date (value));
 		break;
-
-	case TRACKER_PROPERTY_TYPE_FULLTEXT:
-		tracker_data_update_delete_content (service, service_id);
+	case TRACKER_PROPERTY_TYPE_RESOURCE:
+		object_id = ensure_resource_id (value);
+		tracker_db_statement_bind_int (stmt, 1, object_id);
 		break;
-
-	case TRACKER_PROPERTY_TYPE_BLOB:
-	case TRACKER_PROPERTY_TYPE_STRUCT:
-	case TRACKER_PROPERTY_TYPE_LINK:
-		/* not handled */
 	default:
-		break;
+		g_assert_not_reached ();
 	}
 
-	metadata_key = tracker_ontology_service_get_key_metadata (tracker_class_get_name (service),
-								  tracker_property_get_name (field));
-	if (metadata_key > 0) {
-		tracker_db_interface_execute_query (iface, NULL,
-						    "update Services set KeyMetadata%d = '%s' where id = %d",
-						    metadata_key, "", service_id);
-	}
+	tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 
-	g_free (id_str);
+	/* also delete super property values */
+	super_properties = tracker_property_get_super_properties (property);
+	while (*super_properties) {
+		delete_metadata_decomposed (resource_id, *super_properties, value);
+		super_properties++;
+	}
 }
 
-void
-tracker_data_update_set_content (TrackerClass *service,
-				  guint32	 service_id,
-				  const gchar   *text)
-{
-	TrackerDBInterface *iface;
-	TrackerProperty *field;
-	gchar *id_str;
-
-	id_str = tracker_guint32_to_string (service_id);
-	field = tracker_ontology_get_field_by_name ("File:Contents");
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_CONTENTS);
 
-	tracker_db_interface_execute_procedure (iface, NULL,
-						"SaveServiceContents",
-						id_str,
-						tracker_property_get_id (field),
-						text,
-						NULL);
-	g_free (id_str);
-}
-
-void
-tracker_data_update_delete_content (TrackerClass *service,
-				     guint32	    service_id)
+static void
+delete_metadata_decomposed_all (gint resource_id,
+				TrackerProperty	*property)
 {
-	TrackerDBInterface *iface;
-	TrackerProperty *field;
-	gchar *service_id_str;
+	TrackerDBInterface  *iface;
+	TrackerDBStatement  *stmt;
+	gboolean            multiple_values;
+	const gchar *class_name, *property_name;
+	TrackerProperty   **super_properties;
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	multiple_values = tracker_property_get_multiple_values (property);
+	class_name = tracker_class_get_name (tracker_property_get_domain (property));
+	property_name = tracker_property_get_name (property);
+	if (multiple_values) {
+		/* delete rows for multiple value properties */
+		stmt = tracker_db_interface_create_statement (iface,
+			"DELETE FROM \"%s_%s\" WHERE ID = ?",
+			class_name, property_name);
+	} else {
+		/* just set value to NULL for single value properties */
+		stmt = tracker_db_interface_create_statement (iface,
+			"UPDATE \"%s\" SET \"%s\" = NULL WHERE ID = ?",
+			class_name, property_name);
+	}
 
-	service_id_str = tracker_guint32_to_string (service_id);
-	field = tracker_ontology_get_field_by_name ("File:Contents");
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_CONTENTS);
+	tracker_db_statement_bind_int (stmt, 0, resource_id);
 
-	/* Delete contents if it has! */
-	tracker_db_interface_execute_procedure (iface, NULL,
-						"DeleteContent",
-						service_id_str,
-						tracker_property_get_id (field),
-						NULL);
+	tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 
-	g_free (service_id_str);
+	/* also delete super property values */
+	super_properties = tracker_property_get_super_properties (property);
+	while (*super_properties) {
+		delete_metadata_decomposed_all (resource_id, *super_properties);
+		super_properties++;
+	}
 }
 
 void
-tracker_data_update_delete_service_by_path (const gchar *path,
-					    const gchar *rdf_type)
+tracker_data_delete_statement (const gchar            *subject,
+			       const gchar            *predicate,
+			       const gchar            *object)
 {
-	TrackerClass *service;
-	const gchar    *service_type; 
-	guint32         service_id;
+	TrackerClass       *class;
+	TrackerProperty    *field;
+	gint		    subject_id;
 
-	g_return_if_fail (path != NULL);
+	if (auto_commit) {
+		tracker_data_begin_implicit_transaction ();
+	}
 
-	if (!rdf_type)
-		return;
+	subject_id = query_resource_id (subject);
+	
+	if (subject_id == 0) {
+		/* subject not in database */
 
-	service = tracker_ontology_get_service_by_name (rdf_type);
+		if (auto_commit) {
+			tracker_data_commit_transaction ();
+		}
 
-	if (!service) {
 		return;
 	}
 
-	service_type = tracker_class_get_name (service);
-	service_id = tracker_data_query_file_id (service_type, path);
-
-	/* When merging from the decomposed branch to trunk then this function
-	 * wont exist in the decomposed branch. Create it based on this one. 
-	 */
-	if (service_id != 0) {
-		tracker_data_update_delete_service (service, service_id);
-		if (strcmp (service_type, "Folders") == 0) {
-			tracker_data_update_delete_service_recursively (service, (gchar *) path);
+	if (object && g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
+		class = tracker_ontology_get_class_by_uri (object);
+		if (class != NULL) {
+			TrackerDBInterface *iface;
+			TrackerDBStatement *stmt;
+			TrackerDBResultSet *result_set;
+			TrackerProperty   **properties, **prop;
+
+			iface = tracker_db_manager_get_db_interface ();
+
+			/* retrieve all subclasses we need to remove from the subject
+			 * before we can remove the class specified as object of the statement */
+			stmt = tracker_db_interface_create_statement (iface,
+				"SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:Class_rdfs:subClassOf\".ID) "
+				"FROM \"rdfs:Resource_rdf:type\" INNER JOIN \"rdfs:Class_rdfs:subClassOf\" ON (\"rdf:type\" = \"rdfs:Class_rdfs:subClassOf\".ID) "
+				"WHERE \"rdfs:Resource_rdf:type\".ID = ? AND \"rdfs:subClassOf\" = (SELECT ID FROM \"rdfs:Resource\" WHERE Uri = ?)");
+			tracker_db_statement_bind_int (stmt, 0, subject_id);
+			tracker_db_statement_bind_text (stmt, 1, object);
+			result_set = tracker_db_statement_execute (stmt, NULL);
+			g_object_unref (stmt);
+
+			if (result_set) {
+				do {
+					gchar *class_uri;
+
+					tracker_db_result_set_get (result_set, 0, &class_uri, -1);
+					tracker_data_delete_statement (subject, predicate, class_uri);
+					g_free (class_uri);
+				} while (tracker_db_result_set_iter_next (result_set));
+
+				g_object_unref (result_set);
+			}
+
+			properties = tracker_ontology_get_properties ();
+
+			/* delete single-valued properties for current class */
+
+			stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"%s\" WHERE ID = ?",
+			                                              tracker_class_get_name (class));
+			tracker_db_statement_bind_int (stmt, 0, subject_id);
+			tracker_db_statement_execute (stmt, NULL);
+			g_object_unref (stmt);
+
+			for (prop = properties; *prop; prop++) {
+				if (tracker_property_get_domain (*prop) != class
+				    || !tracker_property_get_multiple_values (*prop)) {
+					continue;
+				}
+
+				/* multi-valued property, delete values from DB */
+				stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"%s_%s\" WHERE ID = ?",
+							tracker_class_get_name (class),
+							tracker_property_get_name (*prop));
+				tracker_db_statement_bind_int (stmt, 0, subject_id);
+				tracker_db_statement_execute (stmt, NULL);
+				g_object_unref (stmt);
+			}
+
+			/* delete rows from class tables */
+			delete_resource_type (subject_id, class);
+		} else {
+			g_warning ("Class '%s' not found in the ontology", object);
+		}
+	} else {
+		field = tracker_ontology_get_property_by_uri (predicate);
+		if (field != NULL) {
+
+			if (object) {
+				delete_metadata_decomposed (subject_id, field, object);
+			} else {
+				delete_metadata_decomposed_all (subject_id, field);
+			}
+
+			if (object && tracker_property_get_fulltext_indexed (field)) {
+				TrackerConfig         *config;
+				TrackerLanguage       *language;
+
+				config = tracker_data_manager_get_config ();
+				language = tracker_data_manager_get_language ();
+
+				if (tracker_property_get_filtered (field)) {
+					unindex_text_no_parsing (config,
+								 language,
+								 subject_id,
+								 object,
+								 tracker_property_get_weight (field));
+				} else {
+					unindex_text_with_parsing (config,
+								   language,
+								   subject_id,
+								   object,
+								   tracker_property_get_weight (field));
+				}
+			}
+		} else {
+			g_warning ("Property '%s' not found in the ontology", predicate);
 		}
-		tracker_data_update_delete_all_metadata (service, service_id);
 	}
-}
 
+	if (auto_commit) {
+		tracker_data_commit_transaction ();
+	}
+}
 
 void
-tracker_data_update_delete_service_all (const gchar *rdf_type)
+tracker_data_insert_statement (const gchar            *subject,
+			       const gchar            *predicate,
+			       const gchar            *object)
 {
-	TrackerClass     *service;
-	gchar              *service_type_id; 
-	TrackerDBInterface *iface;
+	TrackerClass       *service;
+	TrackerProperty       *field;
 
-	if (!rdf_type)
-		return;
+	g_return_if_fail (subject != NULL);
+	g_return_if_fail (predicate != NULL);
+	g_return_if_fail (object != NULL);
 
-	service = tracker_ontology_get_service_by_name (rdf_type);
+	if (auto_commit) {
+		tracker_data_begin_implicit_transaction ();
+	}
 
-	g_return_if_fail (TRACKER_IS_CLASS (service));
+	/* subjects and objects starting with `:' are anonymous blank nodes */
+	if (g_str_has_prefix (object, ":")) {
+		/* anonymous blank node used as object in a statement */
+		const gchar *blank_uri;
 
-	service_type_id = tracker_gint_to_string (tracker_class_get_id (service));
+		if (blank_buffer.subject != NULL) {
+			if (strcmp (blank_buffer.subject, object) == 0) {
+				/* object still in blank buffer, need to flush buffer */
+				tracker_data_blank_buffer_flush ();
+			}
+		}
 
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+		blank_uri = g_hash_table_lookup (blank_buffer.table, object);
+		g_return_if_fail (blank_uri != NULL);
 
-	tracker_db_interface_execute_procedure (iface,
-						NULL,
-						"DeleteServiceAll",
-						service_type_id,
-						NULL);
+		/* now insert statement referring to blank node */
+		tracker_data_insert_statement (subject, predicate, blank_uri);
 
-	g_free (service_type_id);
-}
+		g_hash_table_remove (blank_buffer.table, object);
 
-static void
-set_metadata (TrackerProperty *field, 
-	      gpointer value, 
-	      ForeachInMetadataInfo *info)
-{
-	TrackerDBIndex *lindex;
-	gchar *parsed_value;
-	gchar **arr;
-	gint service_id;
-	gint i;
-	gint score;
-
-	/* TODO untested and unfinished port that came from the decomposed 
-	 * branch of Jürg. When merging from the decomposed branch to trunk
-	 * then pick the version in the decomposed branch for this function 
-	 */
-	parsed_value = tracker_parser_text_to_string (value,
-						      info->language,
-						      tracker_config_get_max_word_length (info->config),
-						      tracker_config_get_min_word_length (info->config),
-						      tracker_property_get_filtered (field),
-						      tracker_property_get_filtered (field),
-						      tracker_property_get_delimited (field));
-
-	if (!parsed_value) {
 		return;
 	}
 
-	score = tracker_property_get_weight (field);
+	if (g_str_has_prefix (subject, ":")) {
+		/* blank node definition
+		   pile up statements until the end of the blank node */
+		gchar *value;
+
+		if (blank_buffer.subject != NULL) {
+			/* active subject in buffer */
+			if (strcmp (blank_buffer.subject, subject) != 0) {
+				/* subject changed, need to flush buffer */
+				tracker_data_blank_buffer_flush ();
+			}
+		}
+
+		if (blank_buffer.subject == NULL) {
+			blank_buffer.subject = g_strdup (subject);
+			blank_buffer.predicates = g_array_sized_new (FALSE, FALSE, sizeof (char*), 4);
+			blank_buffer.objects = g_array_sized_new (FALSE, FALSE, sizeof (char*), 4);
+		}
 
-	arr = g_strsplit (parsed_value, " ", -1);
-	service_id = tracker_class_get_id (info->service);
-	lindex = tracker_db_index_manager_get_index_by_service_id (service_id);
+		value = g_strdup (predicate);
+		g_array_append_val (blank_buffer.predicates, value);
+		value = g_strdup (object);
+		g_array_append_val (blank_buffer.objects, value);
 
-	for (i = 0; arr[i]; i++) {
-		tracker_db_index_add_word (lindex,
-					   arr[i],
-					   info->iid_value,
-					   tracker_class_get_id (info->service),
-					   score);
+		return;
+	}
+
+	if (update_buffer.subject != NULL) {
+		/* active subject in cache */
+		if (strcmp (update_buffer.subject, subject) != 0) {
+			/* subject changed, need to flush cache */
+			tracker_data_update_buffer_flush ();
+		}
+	}
+
+	if (update_buffer.subject == NULL) {
+		GValue gvalue = { 0 };
+
+		g_value_init (&gvalue, G_TYPE_INT64);
+
+		/* subject not yet in cache, retrieve or create ID */
+		update_buffer.subject = g_strdup (subject);
+		update_buffer.id = ensure_resource_id (update_buffer.subject);
+
+		g_value_set_int64 (&gvalue, (gint64) time (NULL));
+		cache_insert_value ("rdfs:Resource", "Modified", &gvalue, FALSE);
 	}
 
-	tracker_data_update_set_metadata (info->service, info->iid_value, field, value, parsed_value);
+	if (strcmp (predicate, RDF_PREFIX "type") == 0) {
+		/* handle rdf:type statements specially to
+		   cope with inference and insert blank rows */
+		service = tracker_ontology_get_class_by_uri (object);
+		if (service != NULL) {
+			cache_create_service_decomposed (service);
+		} else {
+			g_warning ("Class '%s' not found in the ontology", object);
+		}
+	} else {
+		field = tracker_ontology_get_property_by_uri (predicate);
+		if (field != NULL) {
+			/* add value to metadata database */
+			cache_set_metadata_decomposed (field, object);
+
+			if (tracker_property_get_fulltext_indexed (field)) {
+				/* add value to fulltext index */
+				TrackerConfig         *config;
+				TrackerLanguage       *language;
+
+				config = tracker_data_manager_get_config ();
+				language = tracker_data_manager_get_language ();
+
+				if (tracker_property_get_filtered (field)) {
+					index_text_with_parsing (config,
+								 language,
+								 update_buffer.id,
+								 object,
+								 tracker_property_get_weight (field));
+				} else {
+					index_text_no_parsing (config,
+							       language,
+							       update_buffer.id,
+							       object,
+							       tracker_property_get_weight (field));
+				}
+			}
+		} else {
+			g_warning ("Property '%s' not found in the ontology", predicate);
+		}
+	}
 
-	g_free (parsed_value);
-	g_strfreev (arr);
+	if (auto_commit) {
+		tracker_data_commit_transaction ();
+	}
+}
+
+void
+tracker_data_delete_resource (const gchar     *uri)
+{
+	g_return_if_fail (uri != NULL);
+
+	tracker_data_delete_statement (uri, RDF_PREFIX "type", RDFS_PREFIX "Resource");
 }
 
 static void
-foreach_in_metadata_set_metadata (gpointer   predicate,
-				  gpointer   value,
-				  gpointer   user_data)
+foreach_in_metadata_set_metadata (gpointer      predicate,
+				  gpointer      value,
+				  gpointer      user_data)
 {
+	ForeachInMetadataInfo *info = user_data;
 	TrackerProperty *field;
-	ForeachInMetadataInfo *info;
-	gint throttle;
 
-	info = user_data;
-	field = tracker_ontology_get_field_by_name (predicate);
+	field = tracker_ontology_get_property_by_uri (predicate);
 
 	if (!field)
 		return;
 
-	/* Throttle indexer, value 9 is from older code, why 9? */
-	throttle = tracker_config_get_throttle (info->config);
-	if (throttle > 9) {
-		tracker_throttle (info->config, throttle * 100);
-	}
-
-	if (!tracker_property_get_multiple_values (field)) {
-		set_metadata (field, value, user_data);
+	if (!value) {
+		tracker_data_delete_statement (info->uri, tracker_property_get_uri (field), NULL);
 	} else {
-		GList *list;
-
-		for (list = value; list; list = list->next)
-			set_metadata (field, list->data, user_data);
+		tracker_data_insert_statement (info->uri, tracker_property_get_uri (field), value);
 	}
 }
 
 void 
-tracker_data_update_replace_service (const gchar *path,
-				     const gchar *rdf_type,
+tracker_data_update_replace_service (const gchar *uri,
 				     GHashTable  *metadata)
 {
 	TrackerDBInterface  *iface;
 	TrackerDBResultSet  *result_set;
 	const gchar         *modified;
-	TrackerClass      *service;
-	gchar               *escaped_path;
-	gchar               *dirname;
-	gchar               *basename;
-	time_t               file_mtime;
-	gboolean             set_metadata = FALSE;
-	guint32              id = 0;
-
-	g_return_if_fail (path != NULL);
+	GError              *error = NULL;
+	gchar               *escaped_uri;
+
+	g_return_if_fail (uri != NULL);
 	g_return_if_fail (metadata != NULL);
 
-	/* When merging from the decomposed branch to trunk then pick the version
-	 * in the decomposed branch for this function. However, carefully 
-	 * compare the features, as this version is more recent and has 
-	 * implemented a few significant items, whereas the version in the
-	 * decomposed branch was a proof of concept implementation, and might
-	 * not have these needed features. 
-	 */
+	modified = g_hash_table_lookup (metadata, "resource:Modified");
 
-	if (!rdf_type)
+	if (!modified) {
 		return;
+	}
 
-	/*
-	service = tracker_ontology_get_service_by_name (rdf_type); */
+	escaped_uri = tracker_escape_string (uri);
 
-	/* The current ontology doesn't allow sanity like what above would be */
-	service = tracker_ontology_get_service_by_name ("Files");
+	iface = tracker_db_manager_get_db_interface ();
 
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	result_set = tracker_db_interface_execute_query (iface, &error,
+							 "SELECT ID, Modified < '%s' FROM \"rdfs:Resource\" "
+							 "WHERE Uri = '%s'",
+							 modified,
+							 escaped_uri);
 
-	modified = g_hash_table_lookup (metadata, "File:Modified");
+	g_hash_table_remove (metadata, "resource:Modified");
 
-	if (!modified) {
-		return;
+	if (error) {
+		g_error_free (error);
 	}
 
-	file_mtime = atoi (modified);
-	escaped_path = tracker_escape_string (path);
+	if (result_set) {
+		GValue id_value = { 0, };
+		GValue is_value = { 0, };
+		gint   iid_value, iis_value;
 
-	basename = g_path_get_basename (escaped_path);
-	dirname = g_path_get_dirname (escaped_path);
+		_tracker_db_result_set_get_value (result_set, 0, &id_value);
+		iid_value = g_value_get_int (&id_value);
 
-	result_set = tracker_db_interface_execute_procedure (iface, NULL,
-							     "GetServiceID",
-							     dirname,
-							     basename,
-							     NULL);
-	if (result_set) {
-		guint mtime;
+		_tracker_db_result_set_get_value (result_set, 1, &is_value);
+		iis_value = g_value_get_int (&is_value);
 
-		tracker_db_result_set_get (result_set,
-					   0, &id,
-					   1, &mtime,
-					   -1);
+		if (iis_value) {
+			ForeachInMetadataInfo info;
 
-		if (mtime != file_mtime) {
-			set_metadata = TRUE;
-		}
+			info.uri = uri;
 
-		g_object_unref (result_set);
-	} else {
-		id = tracker_data_update_get_new_service_id (iface);
+			info.config = tracker_data_manager_get_config ();
+			info.language = tracker_data_manager_get_language ();
 
-		if (tracker_data_update_create_service (service, id,
-							dirname, basename,
-							metadata)) {
-			set_metadata = TRUE;
+			g_hash_table_foreach (metadata, 
+					      foreach_in_metadata_set_metadata,
+					      &info);
 		}
-	}
 
-	if (set_metadata) {
-		ForeachInMetadataInfo *info;
+		g_value_unset (&id_value);
+		g_value_unset (&is_value);
+
+		g_object_unref (result_set);
+	} else {
+		ForeachInMetadataInfo info;
+		guint32               id;
 
-		info = g_slice_new (ForeachInMetadataInfo);
+		id = tracker_data_insert_resource (uri);
 
-		info->service = service;
-		info->iid_value = id;
+		info.uri = uri;
 
-		info->config = tracker_data_manager_get_config ();
-		info->language = tracker_data_manager_get_language ();
+		info.config = tracker_data_manager_get_config ();
+		info.language = tracker_data_manager_get_language ();
 
-		g_hash_table_foreach (metadata,
+		g_hash_table_foreach (metadata, 
 				      foreach_in_metadata_set_metadata,
-				      info);
+				      &info);
 
-		g_slice_free (ForeachInMetadataInfo, info);
 	}
 
-	g_free (dirname);
-	g_free (basename);
-	g_free (escaped_path);
+	g_free (escaped_uri);
+
+}
+
+static void
+db_set_volume_available (const gchar *uri,
+                         gboolean     available)
+{
+	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	stmt = tracker_db_interface_create_statement (iface, "UPDATE \"rdfs:Resource\" SET Available = ? WHERE ID IN (SELECT ID FROM \"nie:DataObject\" WHERE \"nie:dataSource\" IN (SELECT ID FROM \"rdfs:Resource\" WHERE Uri = ?))");
+	tracker_db_statement_bind_int (stmt, 0, available ? 1 : 0);
+	tracker_db_statement_bind_text (stmt, 1, uri);
+	tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 }
 
 void
 tracker_data_update_enable_volume (const gchar *udi,
                                    const gchar *mount_path)
 {
-	TrackerDBInterface *iface;
-	TrackerDBResultSet *result_set;
-	guint32		    id = 0;
+	gchar		   *removable_device_urn;
+	gchar *delete_q;
+	gchar *set_q;
+	gchar *mount_path_uri;
+	GFile *mount_path_file;
+	GError *error = NULL;
 
 	g_return_if_fail (udi != NULL);
 	g_return_if_fail (mount_path != NULL);
 
-	iface = tracker_db_manager_get_db_interface (TRACKER_DB_COMMON);
+	removable_device_urn = g_strdup_printf (TRACKER_DATASOURCE_URN_PREFIX "%s", udi);
 
-	result_set = tracker_db_interface_execute_procedure (iface, NULL,
-					   "GetVolumeID",
-					   udi,
-					   NULL);
+	db_set_volume_available (removable_device_urn, TRUE);
 
+	mount_path_file = g_file_new_for_path (mount_path);
+	mount_path_uri = g_file_get_uri (mount_path_file);
 
-	if (result_set) {
-		tracker_db_result_set_get (result_set, 0, &id, -1);
-		g_object_unref (result_set);
+	delete_q = g_strdup_printf ("DELETE { <%s> tracker:mountPoint ?d } WHERE { <%s> tracker:mountPoint ?d }", 
+				    removable_device_urn, removable_device_urn);
+	set_q = g_strdup_printf ("INSERT { <%s> a tracker:Volume; tracker:mountPoint <%s> }", 
+				 removable_device_urn, mount_path_uri);
+
+	tracker_data_update_sparql (delete_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+		error = NULL;
 	}
 
-	if (id == 0) {
-		tracker_db_interface_execute_procedure (iface, NULL,
-							"InsertVolume",
-							mount_path,
-							udi,
-							NULL);
-	} else {
-		tracker_db_interface_execute_procedure (iface, NULL,
-							"EnableVolume",
-							mount_path,
-							udi,
-							NULL);
+	tracker_data_update_sparql (set_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
 	}
+
+	g_free (set_q);
+	g_free (delete_q);
+
+	delete_q = g_strdup_printf ("DELETE { <%s> tracker:isMounted ?d } WHERE { <%s> tracker:isMounted ?d }", 
+				    removable_device_urn, removable_device_urn);
+	set_q = g_strdup_printf ("INSERT { <%s> a tracker:Volume; tracker:isMounted true }", 
+				 removable_device_urn);
+
+	tracker_data_update_sparql (delete_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+		error = NULL;
+	}
+
+	tracker_data_update_sparql (set_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+	}
+
+	g_free (set_q);
+	g_free (delete_q);
+
+	g_free (mount_path_uri);
+	g_object_unref (mount_path_file);
+	g_free (removable_device_urn);
 }
 
 void
-tracker_data_update_reset_volume (guint32 volume_id)
+tracker_data_update_reset_volume (const gchar *uri)
 {
-	TrackerDBInterface *iface;
-	gchar *volume_id_str;
+	time_t mnow;
+	gchar *now_as_string;
+	gchar *delete_q;
+	gchar *set_q;
+	GError *error = NULL;
 
-	/* NOTE: The default volume id 1 is not to be changed */
-	g_return_if_fail (volume_id > 1);
+	mnow = time (NULL);
+	now_as_string = tracker_date_to_string (mnow);
+	delete_q = g_strdup_printf ("DELETE { <%s> tracker:unmountDate ?d } WHERE { <%s> tracker:unmountDate ?d }", uri, uri);
+	set_q = g_strdup_printf ("INSERT { <%s> a tracker:Volume; tracker:unmountDate \"%s\" }", 
+				 uri, now_as_string);
 
-	iface = tracker_db_manager_get_db_interface (TRACKER_DB_COMMON);
+	tracker_data_update_sparql (delete_q, &error);
 
-	volume_id_str = tracker_guint32_to_string (volume_id);
-	tracker_db_interface_execute_procedure (iface, NULL,
-						"UpdateVolumeDisabledDate",
-						volume_id_str,
-						NULL);
-	g_free (volume_id_str);
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+		error = NULL;
+	}
+
+	tracker_data_update_sparql (set_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+	}
+
+	g_free (now_as_string);
+	g_free (set_q);
+	g_free (delete_q);
 }
 
 void
 tracker_data_update_disable_volume (const gchar *udi)
 {
-	TrackerDBInterface *iface;
+	gchar *removable_device_urn;
+	gchar *delete_q;
+	gchar *set_q;
+	GError *error = NULL;
 
 	g_return_if_fail (udi != NULL);
 
-	iface = tracker_db_manager_get_db_interface (TRACKER_DB_COMMON);
-	
-	tracker_db_interface_execute_procedure (iface, NULL,
-						"DisableVolume",
-						udi,
-						NULL);
+	removable_device_urn = g_strdup_printf (TRACKER_DATASOURCE_URN_PREFIX "%s", udi);
+
+	db_set_volume_available (removable_device_urn, FALSE);
+
+	tracker_data_update_reset_volume (removable_device_urn);
+
+	delete_q = g_strdup_printf ("DELETE { <%s> tracker:isMounted ?d } WHERE { <%s> tracker:isMounted ?d }", 
+				    removable_device_urn, removable_device_urn);
+	set_q = g_strdup_printf ("INSERT { <%s> a tracker:Volume; tracker:isMounted false }", 
+				 removable_device_urn);
+
+	tracker_data_update_sparql (delete_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+		error = NULL;
+	}
+
+	tracker_data_update_sparql (set_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+	}
+
+	g_free (set_q);
+	g_free (delete_q);
+
+	g_free (removable_device_urn);
 }
 
 void
 tracker_data_update_disable_all_volumes (void)
 {
 	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
+	gchar *delete_q, *set_q;
+	GError *error = NULL;
 
-	iface = tracker_db_manager_get_db_interface (TRACKER_DB_COMMON);
-	
-	tracker_db_interface_execute_procedure (iface, NULL,
-						"DisableAllVolumes",
-						NULL);
+	iface = tracker_db_manager_get_db_interface ();
+
+	stmt = tracker_db_interface_create_statement (iface,
+		"UPDATE \"rdfs:Resource\" SET Available = 0 "
+		"WHERE ID IN ("
+			"SELECT ID FROM \"nie:DataObject\" "
+			"WHERE \"nie:dataSource\" IN ("
+				"SELECT ID FROM \"rdfs:Resource\" WHERE Uri != ?"
+			")"
+		")");
+	tracker_db_statement_bind_text (stmt, 0, TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN);
+	tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	delete_q = g_strdup_printf ("DELETE { ?o tracker:isMounted ?d } WHERE { ?o tracker:isMounted ?d  FILTER (?o != <"TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN"> ) }");
+	set_q = g_strdup_printf ("INSERT { ?o a tracker:Volume; tracker:isMounted false . FILTER (?o != <"TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN"> ) }");
+
+	tracker_data_update_sparql (delete_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+		error = NULL;
+	}
+
+	tracker_data_update_sparql (set_q, &error);
+
+	if (error) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+	}
+
+	g_free (set_q);
+	g_free (delete_q);
+}
+
+void
+tracker_data_begin_transaction (void)
+{
+	tracker_data_begin_implicit_transaction ();
+	auto_commit = FALSE;
+}
+
+void
+tracker_data_commit_transaction (void)
+{
+	TrackerDBInterface *iface;
+
+	tracker_data_update_buffer_flush ();
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	tracker_db_interface_end_transaction (iface);
+
+	g_hash_table_unref (update_buffer.resource_cache);
+
+	auto_commit = TRUE;
+}
+
+static gchar *
+get_string_for_value (GValue *value)
+{
+	switch (G_VALUE_TYPE (value)) {
+	case G_TYPE_INT:
+		return g_strdup_printf ("%d", g_value_get_int (value));
+	case G_TYPE_DOUBLE:
+		return g_strdup_printf ("%f", g_value_get_double (value));
+	case G_TYPE_STRING:
+		return g_strdup (g_value_get_string (value));
+	default:
+		return NULL;
+	}
+}
+
+/**
+ * Removes the description of a resource (embedded metadata), but keeps
+ * annotations (non-embedded/user metadata) stored about the resource.
+ */
+void
+tracker_data_delete_resource_description (const gchar *uri)
+{
+	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
+	TrackerDBResultSet *result_set, *single_result_set, *multi_result_set;
+	TrackerClass	   *class;
+	GString		   *sql;
+	TrackerProperty	  **properties, **property;
+	gchar		   *class_uri, *object;
+	int		    i;
+	gboolean            first;
+	GValue		    value = { 0 };
+	gint                resource_id;
+
+	resource_id = tracker_data_query_resource_id (uri);
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	properties = tracker_ontology_get_properties ();
+
+	stmt = tracker_db_interface_create_statement (iface, "SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdf:type\") FROM \"rdfs:Resource_rdf:type\" WHERE ID = ?");
+	tracker_db_statement_bind_int (stmt, 0, resource_id);
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	if (result_set) {
+		do {
+			tracker_db_result_set_get (result_set, 0, &class_uri, -1);
+
+			class = tracker_ontology_get_class_by_uri (class_uri);
+			if (class == NULL) {
+				g_warning ("Class '%s' not found in the ontology", class_uri);
+				g_free (class_uri);
+				continue;
+			}
+
+			/* retrieve single value properties for current class */
+
+			sql = g_string_new ("SELECT ");
+
+			first = TRUE;
+			for (property = properties; *property; property++) {
+				if (tracker_property_get_domain (*property) == class) {
+					if (!tracker_property_get_embedded (*property)) {
+						continue;
+					}
+
+					if (!tracker_property_get_multiple_values (*property)) {
+						if (!first) {
+							g_string_append (sql, ", ");
+						}
+						first = FALSE;
+
+						if (tracker_property_get_data_type (*property) == TRACKER_PROPERTY_TYPE_RESOURCE) {
+							g_string_append_printf (sql, "(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"%s\")", tracker_property_get_name (*property));
+						} else {
+							g_string_append_printf (sql, "\"%s\"", tracker_property_get_name (*property));
+						}
+					}
+				}
+			}
+
+			if (!first) {
+				g_string_append_printf (sql, " FROM \"%s\" WHERE ID = ?", tracker_class_get_name (class));
+				stmt = tracker_db_interface_create_statement (iface, "%s", sql->str);
+				tracker_db_statement_bind_int (stmt, 0, resource_id);
+				single_result_set = tracker_db_statement_execute (stmt, NULL);
+				g_object_unref (stmt);
+			}
+
+			g_string_free (sql, TRUE);
+
+			i = 0;
+			for (property = properties; *property; property++) {
+				if (tracker_property_get_domain (*property) != class) {
+					continue;
+				}
+
+				if (!tracker_property_get_embedded (*property)) {
+					continue;
+				}
+
+				if (strcmp (tracker_property_get_uri (*property), RDF_PREFIX "type") == 0) {
+					/* Do not delete rdf:type statements */
+					continue;
+				}
+
+				if (!tracker_property_get_multiple_values (*property)) {
+					/* single value property, value in single_result_set */
+
+					_tracker_db_result_set_get_value (single_result_set, i++, &value);
+					if (G_VALUE_TYPE (&value) == 0) {
+						/* NULL, property not set */
+						continue;
+					}
+
+					object = get_string_for_value (&value);
+					g_value_unset (&value);
+
+					tracker_data_delete_statement (uri, tracker_property_get_uri (*property), object);
+
+					g_free (object);
+				} else {
+					/* multi value property, retrieve values from DB */
+
+					sql = g_string_new ("SELECT ");
+
+					if (tracker_property_get_data_type (*property) == TRACKER_PROPERTY_TYPE_RESOURCE) {
+						g_string_append_printf (sql, "(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"%s\")", tracker_property_get_name (*property));
+					} else {
+						g_string_append_printf (sql, "\"%s\"", tracker_property_get_name (*property));
+					}
+
+					g_string_append_printf (sql,
+								" FROM \"%s_%s\" WHERE ID = ?",
+								tracker_class_get_name (tracker_property_get_domain (*property)),
+								tracker_property_get_name (*property));
+
+					stmt = tracker_db_interface_create_statement (iface, "%s", sql->str);
+					tracker_db_statement_bind_int (stmt, 0, resource_id);
+					multi_result_set = tracker_db_statement_execute (stmt, NULL);
+					g_object_unref (stmt);
+
+					if (multi_result_set) {
+						do {
+
+							_tracker_db_result_set_get_value (multi_result_set, 0, &value);
+							object = get_string_for_value (&value);
+							g_value_unset (&value);
+
+							tracker_data_delete_statement (uri, tracker_property_get_uri (*property), object);
+
+							g_free (object);
+						} while (tracker_db_result_set_iter_next (multi_result_set));
+
+						g_object_unref (multi_result_set);
+					}
+
+					g_string_free (sql, TRUE);
+				}
+			}
+
+			if (!first) {
+				g_object_unref (single_result_set);
+			}
+
+			g_free (class_uri);
+		} while (tracker_db_result_set_iter_next (result_set));
+
+		g_object_unref (result_set);
+	}
+
+	g_free (properties);
+}
+
+
+void
+tracker_data_update_sparql (const gchar  *update,
+			    GError      **error)
+{
+	g_return_if_fail (update != NULL);
+
+	/* TODO */
 }
 
diff --git a/src/libtracker-data/tracker-data-update.h b/src/libtracker-data/tracker-data-update.h
index a4c372f..14e1639 100644
--- a/src/libtracker-data/tracker-data-update.h
+++ b/src/libtracker-data/tracker-data-update.h
@@ -28,62 +28,38 @@
 
 #include <libtracker-db/tracker-db-interface.h>
 
-#include "tracker-data-metadata.h"
-
 G_BEGIN_DECLS
 
-guint32  tracker_data_update_get_new_service_id         (TrackerDBInterface  *iface);
-
 /* Services  */
-gboolean tracker_data_update_create_service             (TrackerClass      *service,
-							 guint32              service_id,
-							 const gchar         *dirname,
-							 const gchar         *basename,
-							 GHashTable          *metadata);
-void     tracker_data_update_delete_service             (TrackerClass      *service,
-							 guint32              service_id);
-void     tracker_data_update_delete_service_recursively (TrackerClass      *service,
-							 const gchar         *service_path);
-gboolean tracker_data_update_move_service               (TrackerClass      *service,
-							 const gchar         *from,
-							 const gchar         *to);
-
+guint32  tracker_data_insert_resource                   (const gchar         *uri);
+void     tracker_data_delete_resource                   (const gchar         *uri);
+gboolean tracker_data_update_resource_uri               (const gchar         *old_uri,
+							 const gchar         *new_uri);
 /* Turtle importing */
-void     tracker_data_update_replace_service            (const gchar         *path,
-							 const gchar         *rdf_type,
+void     tracker_data_update_replace_service            (const gchar         *uri,
 							 GHashTable          *metadata);
-void     tracker_data_update_delete_service_by_path     (const gchar         *path,
-							 const gchar         *rdf_type);
-void     tracker_data_update_delete_service_all         (const gchar *rdf_type);
-
 
 /* Metadata */
-void     tracker_data_update_set_metadata               (TrackerClass      *service,
-							 guint32              service_id,
-							 TrackerProperty        *field,
-							 const gchar         *value,
-							 const gchar         *parsed_value);
-void     tracker_data_update_delete_all_metadata        (TrackerClass      *service,
-							 guint32              service_id);
-void     tracker_data_update_delete_metadata            (TrackerClass      *service,
-							 guint32              service_id,
-							 TrackerProperty        *field,
-							 const gchar         *value);
+void     tracker_data_delete_resource_description       (const gchar         *uri);
+void     tracker_data_delete_statement			(const gchar	     *subject,
+							 const gchar         *predicate,
+							 const gchar         *object);
 
-/* Contents */
-void     tracker_data_update_set_content                (TrackerClass      *service,
-							 guint32              service_id,
-							 const gchar         *text);
-void     tracker_data_update_delete_content             (TrackerClass      *service,
-							 guint32              service_id);
+void     tracker_data_insert_statement			(const gchar	     *subject,
+							 const gchar         *predicate,
+							 const gchar         *object);
+void     tracker_data_begin_transaction			(void);
+void     tracker_data_commit_transaction		(void);
 
+void     tracker_data_update_sparql			(const gchar       *update,
+							 GError	          **error);
 
 /* Volume handling */
 void tracker_data_update_enable_volume                  (const gchar         *udi,
                                                          const gchar         *mount_path);
 void tracker_data_update_disable_volume                 (const gchar         *udi);
 void tracker_data_update_disable_all_volumes            (void);
-void tracker_data_update_reset_volume                   (guint32              volume_id);
+void tracker_data_update_reset_volume                   (const gchar         *uri);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-query-tree.c b/src/libtracker-data/tracker-query-tree.c
index e68222c..9d38815 100644
--- a/src/libtracker-data/tracker-query-tree.c
+++ b/src/libtracker-data/tracker-query-tree.c
@@ -38,6 +38,8 @@
 
 #include <libtracker-db/tracker-db-index-item.h>
 #include <libtracker-db/tracker-db-index-manager.h>
+#include <libtracker-db/tracker-db-interface.h>
+#include <libtracker-db/tracker-db-manager.h>
 
 #include "tracker-query-tree.h"
 
@@ -71,7 +73,6 @@ struct TrackerQueryTreePrivate {
 	TreeNode	*tree;
 	TrackerConfig	*config;
 	TrackerLanguage *language;
-	GArray		*services;
 };
 
 struct ComposeHitsData {
@@ -81,14 +82,12 @@ struct ComposeHitsData {
 };
 
 struct SearchHitData {
-	guint32 service_type_id;
 	guint32 score;
 };
 
 enum {
 	PROP_0,
-	PROP_QUERY,
-	PROP_SERVICES
+	PROP_QUERY
 };
 
 static void tracker_query_tree_finalize     (GObject		   *object);
@@ -119,12 +118,6 @@ tracker_query_tree_class_init (TrackerQueryTreeClass *klass)
 							      "Query",
 							      NULL,
 							      G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_SERVICES,
-					 g_param_spec_pointer ("services",
-							       "Services",
-							       "GArray of services",
-							       G_PARAM_READWRITE));
 	g_type_class_add_private (object_class,
 				  sizeof (TrackerQueryTreePrivate));
 }
@@ -182,7 +175,6 @@ tracker_query_tree_finalize (GObject *object)
 
 	tree_node_free (priv->tree);
 	g_free (priv->query_str);
-	g_array_free (priv->services, TRUE);
 
 	G_OBJECT_CLASS (tracker_query_tree_parent_class)->finalize (object);
 }
@@ -198,10 +190,6 @@ tracker_query_tree_set_property (GObject      *object,
 		tracker_query_tree_set_query (TRACKER_QUERY_TREE (object),
 					      g_value_get_string (value));
 		break;
-	case PROP_SERVICES:
-		tracker_query_tree_set_services (TRACKER_QUERY_TREE (object),
-						 g_value_get_pointer (value));
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 	}
@@ -221,9 +209,6 @@ tracker_query_tree_get_property (GObject      *object,
 	case PROP_QUERY:
 		g_value_set_string (value, priv->query_str);
 		break;
-	case PROP_SERVICES:
-		g_value_set_pointer (value, priv->services);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 	}
@@ -232,19 +217,14 @@ tracker_query_tree_get_property (GObject      *object,
 TrackerQueryTree *
 tracker_query_tree_new (const gchar	*query_str,
 			TrackerConfig	*config,
-			TrackerLanguage *language,
-			GArray		*services)
+			TrackerLanguage *language)
 {
 	TrackerQueryTree	*object;
 	TrackerQueryTreePrivate *priv;
 
-	/* We accept one or both index and services, but not NULL for
-	 * both since we require at least one of them.
-	 */
 	g_return_val_if_fail (query_str != NULL, NULL);
 	g_return_val_if_fail (TRACKER_IS_CONFIG (config), NULL);
 	g_return_val_if_fail (TRACKER_IS_LANGUAGE (language), NULL);
-	g_return_val_if_fail (services != NULL, NULL);
 
 	/* NOTE: The "query" has to come AFTER the "config" and
 	 * "language" properties since setting the query actually
@@ -259,10 +239,6 @@ tracker_query_tree_new (const gchar	*query_str,
 	priv->config = g_object_ref (config);
 	priv->language = g_object_ref (language);
 
-	if (services) {
-		tracker_query_tree_set_services (object, services);
-	}
-
 	tracker_query_tree_set_query (object, query_str);
 
 	return object;
@@ -451,43 +427,6 @@ tracker_query_tree_get_query (TrackerQueryTree *tree)
 	return priv->query_str;
 }
 
-void
-tracker_query_tree_set_services (TrackerQueryTree *tree,
-				 GArray		  *services)
-{
-	TrackerQueryTreePrivate *priv;
-	GArray *copy = NULL;
-
-	g_return_if_fail (TRACKER_IS_QUERY_TREE (tree));
-
-	priv = TRACKER_QUERY_TREE_GET_PRIVATE (tree);
-
-	if (priv->services != services) {
-		if (services) {
-			copy = g_array_new (TRUE, TRUE, sizeof (gint));
-			g_array_append_vals (copy, services->data, services->len);
-		}
-
-		if (priv->services)
-			g_array_free (priv->services, TRUE);
-
-		priv->services = copy;
-		g_object_notify (G_OBJECT (tree), "services");
-	}
-}
-
-GArray *
-tracker_query_tree_get_services (TrackerQueryTree *tree)
-{
-	TrackerQueryTreePrivate *priv;
-
-	g_return_val_if_fail (TRACKER_IS_QUERY_TREE (tree), NULL);
-
-	priv = TRACKER_QUERY_TREE_GET_PRIVATE (tree);
-
-	return priv->services;
-}
-
 static void
 get_tree_words (TreeNode *node, GSList **list)
 {
@@ -515,23 +454,6 @@ get_idf_score (TrackerDBIndexItem *details,
 	return (f > 1.0) ? lrintf (f) : 1;
 }
 
-static gboolean
-in_array (GArray *array,
-	  gint	  element)
-{
-	guint i;
-
-	if (!array)
-		return TRUE;
-
-	for (i = 0; i < array->len; i++) {
-		if (g_array_index (array, gint, i) == element)
-			return TRUE;
-	}
-
-	return FALSE;
-}
-
 static void
 search_hit_data_free (gpointer data)
 {
@@ -541,24 +463,17 @@ search_hit_data_free (gpointer data)
 static void
 add_search_term_hits_to_hash_table (TrackerDBIndexItem *items,
 				    guint		item_count,
-				    GArray	       *services,
 				    GHashTable	       *result)
 {
 	guint i;
 
 	for (i = 0; i < item_count; i++) {
 		SearchHitData *data;
-		gint	       service;
-
-		service = tracker_db_index_item_get_service_type (&items[i]);
 
-		if (in_array (services, service)) {
-			data = g_slice_new (SearchHitData);
-			data->service_type_id = service;
-			data->score = get_idf_score (&items[i], (float) 1 / item_count);
+		data = g_slice_new (SearchHitData);
+		data->score = get_idf_score (&items[i], (float) 1 / item_count);
 
-			g_hash_table_insert (result, GINT_TO_POINTER (items[i].id), data);
-		}
+		g_hash_table_insert (result, GINT_TO_POINTER (items[i].id), data);
 	}
 }
 
@@ -567,11 +482,10 @@ get_search_term_hits (TrackerQueryTree *tree,
 		      const gchar      *term)
 {
 	TrackerQueryTreePrivate *priv;
+	TrackerDBIndex *index;
 	TrackerDBIndexItem	*items;
 	guint			 item_count;
 	GHashTable		*result;
-	GHashTable		*indexes_checked;
-	guint			 i;
 
 	priv = TRACKER_QUERY_TREE_GET_PRIVATE (tree);
 
@@ -580,46 +494,17 @@ get_search_term_hits (TrackerQueryTree *tree,
 					NULL,
 					search_hit_data_free);
 
-	if (!priv->services) {
-		return result;
-	}
-
-	/* Make sure we don't get information from the same
-	 * index more than once.
-	 */
-	indexes_checked = g_hash_table_new (g_direct_hash,
-					    g_direct_equal);
-
-	for (i = 0; i < priv->services->len; i++) {
-		TrackerDBIndex *index;
-		guint		id;
-
-		id = g_array_index (priv->services, gint, i);
-		index = tracker_db_index_manager_get_index_by_service_id (id);
-
-		if (g_hash_table_lookup (indexes_checked, index)) {
-			continue;
-		}
-
-		g_hash_table_insert (indexes_checked,
-				     index,
-				     GINT_TO_POINTER (1));
+	index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_RESOURCES);
 
-		items = tracker_db_index_get_word_hits (index, term, &item_count);
-
-		if (!items) {
-			continue;
-		}
+	items = tracker_db_index_get_word_hits (index, term, &item_count);
 
+	if (items) {
 		add_search_term_hits_to_hash_table (items,
 						    item_count,
-						    priv->services,
 						    result);
 		g_free (items);
 	}
 
-	g_hash_table_unref (indexes_checked);
-
 	return result;
 }
 
@@ -730,7 +615,6 @@ get_hits_foreach (gpointer key,
 	hit_data = (SearchHitData *) value;
 
 	rank.service_id = GPOINTER_TO_UINT (key);
-	rank.service_type_id = hit_data->service_type_id;
 	rank.score = hit_data->score;
 
 	g_array_append_val (array, rank);
@@ -818,68 +702,66 @@ tracker_query_tree_get_hit_count (TrackerQueryTree *tree)
 	return count;
 }
 
-static void
-get_hit_count_foreach (gpointer key,
-		       gpointer value,
-		       gpointer user_data)
-{
-	GArray *array = (GArray *) user_data;
-	TrackerHitCount count;
-
-	count.service_type_id = GPOINTER_TO_INT (key);
-	count.count = GPOINTER_TO_INT (value);
-
-	g_array_append_val (array, count);
-}
-
 GArray *
 tracker_query_tree_get_hit_counts (TrackerQueryTree *tree)
 {
-	GHashTable *table;
+	TrackerDBInterface *iface;
+	TrackerDBResultSet *result_set;
 	GArray *hits, *counts;
 	guint i;
+	GString *sql;
 
 	g_return_val_if_fail (TRACKER_IS_QUERY_TREE (tree), NULL);
 
-	table = g_hash_table_new (NULL, NULL);
+	iface = tracker_db_manager_get_db_interface ();
+
 	hits = tracker_query_tree_get_hits (tree, 0, 0);
 	counts = g_array_sized_new (TRUE, TRUE, sizeof (TrackerHitCount), 10);
 
+	/* count RDF types for each text search result */
+	sql = g_string_new ("SELECT ");
+	g_string_append (sql, "(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdf:type\"), COUNT(*) ");
+	g_string_append (sql, "FROM (SELECT * FROM \"rdfs:Resource_rdf:type\" ");
+	g_string_append (sql, "WHERE ID IN (");
+
 	for (i = 0; i < hits->len; i++) {
 		TrackerDBIndexItemRank rank;
-		gpointer p;
-		gint count, parent_id;
 
 		rank = g_array_index (hits, TrackerDBIndexItemRank, i);
-		p = g_hash_table_lookup (table,
-					 GINT_TO_POINTER (rank.service_type_id));
-		count = GPOINTER_TO_INT (p);
-		count++;
-
-		g_hash_table_insert (table,
-				     GINT_TO_POINTER (rank.service_type_id),
-				     GINT_TO_POINTER (count));
-
-		/* Update service's parent count too (if it has a
-		 * parent).
-		 */
-		parent_id = tracker_ontology_get_service_parent_id_by_id (rank.service_type_id);
-
-		if (parent_id != -1) {
-			p = g_hash_table_lookup (table, GINT_TO_POINTER (parent_id));
-			count = GPOINTER_TO_INT (p);
-			count++;
-
-			g_hash_table_insert (table,
-					     GINT_TO_POINTER (parent_id),
-					     GINT_TO_POINTER (count));
+
+		if (i > 0) {
+			g_string_append (sql, ",");
 		}
+		g_string_append_printf (sql, "%d", rank.service_id);
 	}
 
-	g_hash_table_foreach (table, (GHFunc) get_hit_count_foreach, counts);
+	g_string_append (sql, ")) GROUP BY \"rdf:type\"");
+
+	result_set = tracker_db_interface_execute_query (iface, NULL, "%s", sql->str);
+
+	if (result_set) {
+		gboolean valid = TRUE;
+		while (valid) {
+			TrackerHitCount count;
+			TrackerClass *class;
+			gchar *class_uri;
+
+			tracker_db_result_set_get (result_set, 0, &class_uri, 1, &count.count, -1);
+
+			class = tracker_ontology_get_class_by_uri (class_uri);
+			count.class = class;
+
+			g_array_append_val (counts, count);
+
+			g_free (class_uri);
+
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
+		g_object_unref (result_set);
+	}
 
-	g_hash_table_destroy (table);
 	g_array_free (hits, TRUE);
+	g_string_free (sql, TRUE);
 
 	return counts;
 }
diff --git a/src/libtracker-data/tracker-query-tree.h b/src/libtracker-data/tracker-query-tree.h
index 058c581..58442af 100644
--- a/src/libtracker-data/tracker-query-tree.h
+++ b/src/libtracker-data/tracker-query-tree.h
@@ -50,22 +50,18 @@ struct TrackerQueryTreeClass {
 };
 
 struct TrackerHitCount {
-	guint service_type_id;
+	TrackerClass *class;
 	guint count;
 };
 
 GType		      tracker_query_tree_get_type	(void);
 TrackerQueryTree *    tracker_query_tree_new		(const gchar	  *query_str,
 							 TrackerConfig	  *config,
-							 TrackerLanguage  *language,
-							 GArray		  *services);
+							 TrackerLanguage  *language);
 G_CONST_RETURN gchar *tracker_query_tree_get_query	(TrackerQueryTree *tree);
 void		      tracker_query_tree_set_query	(TrackerQueryTree *tree,
 							 const gchar	  *query_str);
 
-GArray *	      tracker_query_tree_get_services	(TrackerQueryTree *tree);
-void		      tracker_query_tree_set_services	(TrackerQueryTree *tree,
-							 GArray		  *services);
 GSList *	      tracker_query_tree_get_words	(TrackerQueryTree *tree);
 GArray *	      tracker_query_tree_get_hits	(TrackerQueryTree *tree,
 							 guint		   offset,
diff --git a/src/libtracker-data/tracker-turtle.c b/src/libtracker-data/tracker-turtle.c
index 102eabb..6f16d04 100644
--- a/src/libtracker-data/tracker-turtle.c
+++ b/src/libtracker-data/tracker-turtle.c
@@ -427,32 +427,36 @@ tracker_turtle_process (const gchar          *turtle_file,
 			TurtleTripleCallback  callback,
 			void                 *user_data)
 {
-	unsigned char  *uri_string;
-	raptor_uri     *uri, *buri;
-	raptor_parser  *parser;
+	GThread        *parser_thread;
+	TurtleThreadData *thread_data;
 
 	if (!initialized) {
 		g_critical ("Using tracker_turtle module without initialization");
 	}
 
-	parser = raptor_new_parser ("turtle");
 
-	raptor_set_statement_handler (parser, user_data, (raptor_statement_handler) callback);
-	raptor_set_fatal_error_handler (parser, (void *)turtle_file, raptor_error);
-	raptor_set_error_handler (parser, (void *)turtle_file, raptor_error);
-	raptor_set_warning_handler (parser, (void *)turtle_file, raptor_error);
+	turtle_mutex = g_mutex_new ();
+	turtle_cond = g_cond_new ();
 
-	uri_string = raptor_uri_filename_to_uri_string (turtle_file);
-	uri = raptor_new_uri (uri_string);
-	buri = raptor_new_uri ((unsigned char *) base_uri);
+	thread_data = g_new0 (TurtleThreadData, 1);
+	thread_data->file = g_strdup (turtle_file);
+	thread_data->base_uri = g_strdup (base_uri);
 
-	raptor_parse_file (parser, uri, buri);
+	turtle_first = TRUE;
 
-	raptor_free_uri (uri);
-	raptor_free_memory (uri_string);
-	raptor_free_uri (buri);
+	parser_thread = g_thread_create (turtle_thread_func, thread_data, FALSE, NULL);
 
-	raptor_free_parser (parser);
+	while (turtle_next ()) {
+		callback (turtle_subject,
+		          turtle_predicate,
+		          turtle_object,
+		          user_data);
+	}
+
+	turtle_eof = FALSE;
+
+	g_mutex_free (turtle_mutex);
+	g_cond_free (turtle_cond);
 }
 
 void
diff --git a/src/libtracker-data/tracker-turtle.h b/src/libtracker-data/tracker-turtle.h
index 28d9558..1675f3e 100644
--- a/src/libtracker-data/tracker-turtle.h
+++ b/src/libtracker-data/tracker-turtle.h
@@ -29,16 +29,9 @@
 
 #include <raptor.h>
 
-/*
- * TODO: Is it possible to do this in the .c file? Dont expose raptor here. 
-*/
-
-typedef raptor_statement TrackerRaptorStatement;
-
 G_BEGIN_DECLS
 
-typedef void (* TurtleTripleCallback) (void                         *user_data, 
-				       const TrackerRaptorStatement *triple);
+typedef void (* TurtleTripleCallback) (const gchar *subject, const gchar *predicate, const gchar *object, void *user_data);
 
 typedef struct TurtleFile TurtleFile;
 
diff --git a/src/libtracker-db/tracker-db-dbus.c b/src/libtracker-db/tracker-db-dbus.c
index 666fa3e..c4323d4 100644
--- a/src/libtracker-db/tracker-db-dbus.c
+++ b/src/libtracker-db/tracker-db-dbus.c
@@ -303,7 +303,7 @@ tracker_dbus_query_result_columns_to_strv (TrackerDBResultSet *result_set,
 			g_value_init (&transform, G_TYPE_STRING);
 			
 			_tracker_db_result_set_get_value (result_set, i, &value);
-			if (g_value_transform (&value, &transform)) {
+			if (G_IS_VALUE (&value) && g_value_transform (&value, &transform)) {
 				if (row_counter == 0) {
 					strv[i] = g_value_dup_string (&transform);
 				} else {
@@ -323,8 +323,10 @@ tracker_dbus_query_result_columns_to_strv (TrackerDBResultSet *result_set,
 					}
 					
 				}
+				g_value_unset (&value);
+			} else if (row_counter == 0) {
+				strv[i] = g_strdup ("");
 			}
-			g_value_unset (&value);
 			g_value_unset (&transform);
 		}
 
@@ -439,7 +441,7 @@ tracker_dbus_query_result_to_ptr_array (TrackerDBResultSet *result_set)
 
 			_tracker_db_result_set_get_value (result_set, i, &value);
 
-			if (g_value_transform (&value, &transform)) {
+			if (G_IS_VALUE (&value) && g_value_transform (&value, &transform)) {
 				str = g_value_dup_string (&transform);
 			}
 
@@ -449,7 +451,9 @@ tracker_dbus_query_result_to_ptr_array (TrackerDBResultSet *result_set)
 
 			list = g_slist_prepend (list, (gchar*) str);
 
-			g_value_unset (&value);
+			if (G_IS_VALUE (&value)) {
+				g_value_unset (&value);
+			}
 			g_value_unset (&transform);
 		}
 
diff --git a/src/libtracker-db/tracker-db-index-item.c b/src/libtracker-db/tracker-db-index-item.c
index 7ee338d..b4467e8 100644
--- a/src/libtracker-db/tracker-db-index-item.c
+++ b/src/libtracker-db/tracker-db-index-item.c
@@ -20,49 +20,12 @@
 
 #include "tracker-db-index-item.h"
 
-guint32
-tracker_db_index_item_calc_amalgamated (gint service_type,
-					gint score)
-{
-	unsigned char a[4];
-	gint16	      score16;
-	guint8	      service_type_8;
-
-	score = CLAMP (score, G_MININT16, G_MAXINT16);
-	score16 = (gint16) score;
-
-	service_type_8 = (guint8) service_type;
-
-	/* Amalgamate and combine score and service_type into a single
-	 * 32-bit int for compact storage.
-	 */
-	a[0] = service_type_8;
-	a[1] = (score16 >> 8) & 0xFF;
-	a[2] = score16 & 0xFF;
-	a[3] = 0;
-
-	return (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
-}
-
-guint8
-tracker_db_index_item_get_service_type (TrackerDBIndexItem *item)
-{
-	g_return_val_if_fail (item != NULL, 0);
-
-	return (item->amalgamated >> 24) & 0xFF;
-}
-
-gint16
+gint
 tracker_db_index_item_get_score (TrackerDBIndexItem *item)
 {
-	unsigned char a[2];
-
 	g_return_val_if_fail (item != NULL, 0);
 
-	a[0] = (item->amalgamated >> 16) & 0xFF;
-	a[1] = (item->amalgamated >> 8) & 0xFF;
-
-	return (gint16) (a[0] << 8) | (a[1]);
+	return item->score;
 }
 
 guint32
diff --git a/src/libtracker-db/tracker-db-index-item.h b/src/libtracker-db/tracker-db-index-item.h
index b479a1b..a62cea1 100644
--- a/src/libtracker-db/tracker-db-index-item.h
+++ b/src/libtracker-db/tracker-db-index-item.h
@@ -29,22 +29,17 @@ typedef struct {
 	/* Service ID number of the document */
 	guint32 id;
 
-	/* Amalgamation of service_type and score of the word in the
-	 * document's metadata.
+	/* Score of the word in the document's metadata.
 	 */
-	gint	amalgamated;
+	gint	score;
 } TrackerDBIndexItem;
 
 typedef struct {
 	guint32 service_id;	 /* Service ID of the document */
-	guint32 service_type_id; /* Service type ID of the document */
 	guint32 score;		 /* Ranking score */
 } TrackerDBIndexItemRank;
 
-guint32 tracker_db_index_item_calc_amalgamated (gint		    service_type,
-						gint		    score);
-guint8	tracker_db_index_item_get_service_type (TrackerDBIndexItem *details);
-gint16	tracker_db_index_item_get_score        (TrackerDBIndexItem *details);
+gint	tracker_db_index_item_get_score        (TrackerDBIndexItem *details);
 guint32 tracker_db_index_item_get_id	       (TrackerDBIndexItem *details);
 
 G_END_DECLS
diff --git a/src/libtracker-db/tracker-db-index-manager.c b/src/libtracker-db/tracker-db-index-manager.c
index 49c4ebb..6eadeb9 100644
--- a/src/libtracker-db/tracker-db-index-manager.c
+++ b/src/libtracker-db/tracker-db-index-manager.c
@@ -51,15 +51,10 @@ static TrackerDBIndexDefinition  indexes[] = {
 	  NULL,
 	  NULL,
 	  NULL },
-	{ TRACKER_DB_INDEX_FILE,
+	{ TRACKER_DB_INDEX_RESOURCES,
 	  NULL,
-	  "file-index.db",
-	  "file-index",
-	  NULL },
-	{ TRACKER_DB_INDEX_EMAIL,
-	  NULL,
-	  "email-index.db",
-	  "email-index",
+	  "index.db",
+	  "index",
 	  NULL }
 };
 
@@ -185,23 +180,7 @@ tracker_db_index_manager_init (TrackerDBIndexManagerFlags flags,
 
 	g_message ("Merging old temporary indexes");
 
-	i = TRACKER_DB_INDEX_FILE;
-	name = g_strconcat (indexes[i].name, "-final", NULL);
-	final_index_filename = g_build_filename (data_dir, name, NULL);
-	g_free (name);
-
-	if (g_file_test (final_index_filename, G_FILE_TEST_EXISTS) &&
-	    !has_tmp_merge_files (i)) {
-		g_message ("  Overwriting '%s' with '%s'",
-			   indexes[i].abs_filename,
-			   final_index_filename);
-
-		g_rename (final_index_filename, indexes[i].abs_filename);
-	}
-
-	g_free (final_index_filename);
-
-	i = TRACKER_DB_INDEX_EMAIL;
+	i = TRACKER_DB_INDEX_RESOURCES;
 	name = g_strconcat (indexes[i].name, "-final", NULL);
 	final_index_filename = g_build_filename (data_dir, name, NULL);
 	g_free (name);
@@ -297,76 +276,10 @@ tracker_db_index_manager_get_index (TrackerDBIndexType type)
 TrackerDBIndex *
 tracker_db_index_manager_get_index_by_service (const gchar *service)
 {
-	TrackerDBType	   type;
-	TrackerDBIndexType index_type;
-
 	g_return_val_if_fail (initialized == TRUE, NULL);
 	g_return_val_if_fail (service != NULL, NULL);
 
-	type = tracker_ontology_get_service_db_by_name (service);
-
-	switch (type) {
-	case TRACKER_DB_TYPE_FILES:
-		index_type = TRACKER_DB_INDEX_FILE;
-		break;
-	case TRACKER_DB_TYPE_EMAIL:
-		index_type = TRACKER_DB_INDEX_EMAIL;
-		break;
-	case TRACKER_DB_TYPE_UNKNOWN:
-	case TRACKER_DB_TYPE_DATA:
-	case TRACKER_DB_TYPE_INDEX:
-	case TRACKER_DB_TYPE_CONTENT:
-	case TRACKER_DB_TYPE_COMMON:
-	case TRACKER_DB_TYPE_CACHE:
-	case TRACKER_DB_TYPE_USER:
-	default:
-		index_type = TRACKER_DB_INDEX_UNKNOWN;
-		break;
-	}
-
-	return indexes[index_type].index;
-}
-
-TrackerDBIndex *
-tracker_db_index_manager_get_index_by_service_id (gint id)
-{
-	TrackerDBType	    type;
-	TrackerDBIndexType  index_type;
-	const gchar        *service;
-
-	g_return_val_if_fail (initialized == TRUE, NULL);
-
-	service = tracker_ontology_get_service_by_id (id);
-	if (!service) {
-		return NULL;
-	}
-
-	type = tracker_ontology_get_service_db_by_name (service);
-
-	switch (type) {
-	case TRACKER_DB_TYPE_FILES:
-		index_type = TRACKER_DB_INDEX_FILE;
-		break;
-	case TRACKER_DB_TYPE_EMAIL:
-		index_type = TRACKER_DB_INDEX_EMAIL;
-		break;
-	case TRACKER_DB_TYPE_UNKNOWN:
-	case TRACKER_DB_TYPE_DATA:
-	case TRACKER_DB_TYPE_INDEX:
-	case TRACKER_DB_TYPE_CONTENT:
-	case TRACKER_DB_TYPE_COMMON:
-	case TRACKER_DB_TYPE_CACHE:
-	case TRACKER_DB_TYPE_USER:
-	default:
-		index_type = TRACKER_DB_INDEX_UNKNOWN;
-		break;
-	}
-
-	if (index_type == TRACKER_DB_INDEX_UNKNOWN) {
-		return NULL;
-	}
-
-	return indexes[index_type].index;
+	return indexes[TRACKER_DB_INDEX_RESOURCES].index;
 }
 
 const gchar *
diff --git a/src/libtracker-db/tracker-db-index-manager.h b/src/libtracker-db/tracker-db-index-manager.h
index 2be01f7..e899dcb 100644
--- a/src/libtracker-db/tracker-db-index-manager.h
+++ b/src/libtracker-db/tracker-db-index-manager.h
@@ -30,8 +30,7 @@ G_BEGIN_DECLS
 
 typedef enum {
 	TRACKER_DB_INDEX_UNKNOWN,
-	TRACKER_DB_INDEX_FILE,
-	TRACKER_DB_INDEX_EMAIL
+	TRACKER_DB_INDEX_RESOURCES,
 } TrackerDBIndexType;
 
 typedef enum {
@@ -47,7 +46,6 @@ void		tracker_db_index_manager_shutdown		 (void);
 void            tracker_db_index_manager_remove_all              (void);
 TrackerDBIndex *tracker_db_index_manager_get_index		 (TrackerDBIndexType	      index);
 TrackerDBIndex *tracker_db_index_manager_get_index_by_service	 (const gchar		     *service);
-TrackerDBIndex *tracker_db_index_manager_get_index_by_service_id (gint			      id);
 const gchar *	tracker_db_index_manager_get_filename		 (TrackerDBIndexType	      index);
 gboolean	tracker_db_index_manager_are_indexes_too_big	 (void);
 
diff --git a/src/libtracker-db/tracker-db-index.c b/src/libtracker-db/tracker-db-index.c
index 9ff2250..9d30720 100644
--- a/src/libtracker-db/tracker-db-index.c
+++ b/src/libtracker-db/tracker-db-index.c
@@ -733,13 +733,7 @@ indexer_update_word (const gchar *word,
 						   (old_hit_count - center - 1) * sizeof (TrackerDBIndexItem));
 					old_hit_count--;
 				} else {
-					guint32 service_type;
-
-					service_type =
-						tracker_db_index_item_get_service_type (&previous_hits[center]);
-					previous_hits[center].amalgamated =
-						tracker_db_index_item_calc_amalgamated (service_type,
-											score);
+					previous_hits[center].score = score;
 				}
 
 				edited = TRUE;
@@ -1226,7 +1220,6 @@ void
 tracker_db_index_add_word (TrackerDBIndex *indez,
 			   const gchar	  *word,
 			   guint32	   service_id,
-			   gint		   service_type,
 			   gint		   weight)
 {
 	TrackerDBIndexPrivate *priv;
@@ -1247,7 +1240,7 @@ tracker_db_index_add_word (TrackerDBIndex *indez,
 	}
 
 	elem.id = service_id;
-	elem.amalgamated = tracker_db_index_item_calc_amalgamated (service_type, weight);
+	elem.score = weight;
 
 	array = g_hash_table_lookup (priv->cur_cache, word);
 
@@ -1267,15 +1260,11 @@ tracker_db_index_add_word (TrackerDBIndex *indez,
 		current = &g_array_index (array, TrackerDBIndexItem, i);
 
 		if (current->id == service_id) {
-			guint32 serv_type;
-
 			/* The word was already found in the same
 			 * service_id (file), modify score
 			 */
 			new_score = tracker_db_index_item_get_score (current) + weight;
-
-			serv_type = tracker_db_index_item_get_service_type (current);
-			current->amalgamated = tracker_db_index_item_calc_amalgamated (serv_type, new_score);
+			current->score = new_score;
 
 			return;
 		}
@@ -1308,3 +1297,4 @@ tracker_db_index_get_overloaded (TrackerDBIndex *indez)
 
 	return priv->overloaded;
 }
+
diff --git a/src/libtracker-db/tracker-db-index.h b/src/libtracker-db/tracker-db-index.h
index 8726480..21882dc 100644
--- a/src/libtracker-db/tracker-db-index.h
+++ b/src/libtracker-db/tracker-db-index.h
@@ -89,12 +89,10 @@ TrackerDBIndexItem *tracker_db_index_get_word_hits   (TrackerDBIndex *index,
 void		    tracker_db_index_add_word	     (TrackerDBIndex *index,
 						      const gchar    *word,
 						      guint32	      service_id,
-						      gint	      service_type,
 						      gint	      weight);
 gboolean            tracker_db_index_get_flushing    (TrackerDBIndex *indez);
 gboolean            tracker_db_index_get_overloaded  (TrackerDBIndex *indez);
 
-
 G_END_DECLS
 
 #endif /* __TRACKER_DB_INDEX_H__ */
diff --git a/src/libtracker-db/tracker-db-interface.c b/src/libtracker-db/tracker-db-interface.c
index 26d46d7..3d356b7 100644
--- a/src/libtracker-db/tracker-db-interface.c
+++ b/src/libtracker-db/tracker-db-interface.c
@@ -642,28 +642,11 @@ _tracker_db_result_set_get_value (TrackerDBResultSet *result_set,
 	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
 	row = g_ptr_array_index (priv->array, priv->current_row);
 
-	if (priv->col_types[column] != G_TYPE_INVALID) {
+	if (priv->col_types[column] != G_TYPE_INVALID && row && row[column]) {
 		g_value_init (value, priv->col_types[column]);
-		if (row && row[column]) {
-			fill_in_value (value, row[column]);
-		} else {
-			/* Make up some empty value. */
-			switch (G_VALUE_TYPE (value)) {
-			case G_TYPE_INT:
-				g_value_set_int (value, 0);
-				break;
-			case G_TYPE_DOUBLE:
-				g_value_set_double (value, 0.0);
-				break;
-			case G_TYPE_STRING:
-				g_value_set_string (value, "");
-				break;
-			}
-		}
+		fill_in_value (value, row[column]);
 	} else {
-		/* Make up some empty value */
-		g_value_init (value, G_TYPE_STRING);
-		g_value_set_string (value, "");
+		/* NULL, keep value unset */
 	}
 }
 
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index c1745f7..541e4e0 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -25,13 +25,14 @@
 #include <regex.h>
 #include <zlib.h>
 #include <locale.h>
+#include <time.h>
 
 #include <glib/gstdio.h>
 
-#include <libtracker-common/tracker-property.h>
 #include <libtracker-common/tracker-file-utils.h>
 #include <libtracker-common/tracker-nfs-lock.h>
 #include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-property.h>
 #include <libtracker-common/tracker-type-utils.h>
 #include <libtracker-common/tracker-utils.h>
 
@@ -48,7 +49,7 @@
 #define TRACKER_DB_MAX_FILE_SIZE      2000000000 
 
 /* Set current database version we are working with */
-#define TRACKER_DB_VERSION_NOW        TRACKER_DB_VERSION_4
+#define TRACKER_DB_VERSION_NOW        TRACKER_DB_VERSION_5
 #define TRACKER_DB_VERSION_FILE       "db-version.txt"
 
 typedef enum {
@@ -110,35 +111,23 @@ static TrackerDBDefinition dbs[] = {
 	  FALSE,
 	  FALSE,
  	  0 },
-	{ TRACKER_DB_FILE_METADATA,
+	{ TRACKER_DB_METADATA,
 	  TRACKER_DB_LOCATION_DATA_DIR,
 	  NULL,
-	  "file-meta.db",
-	  "file-meta",
+	  "meta.db",
+	  "meta",
 	  NULL,
-	  512,
+	  2000,
 	  TRACKER_DB_PAGE_SIZE_DONT_SET,
 	  TRUE,
 	  FALSE,
 	  FALSE,
  	  0 },
-	{ TRACKER_DB_FILE_FULLTEXT,
-	  TRACKER_DB_LOCATION_DATA_DIR,
-	  NULL,
-	  "file-fulltext.db",
-	  "file-fulltext",
-	  NULL,
-	  512,
-	  TRACKER_DB_PAGE_SIZE_DONT_SET,
-	  TRUE,
-	  FALSE,
-	  TRUE,
- 	  0 },
-	{ TRACKER_DB_FILE_CONTENTS,
+	{ TRACKER_DB_CONTENTS,
 	  TRACKER_DB_LOCATION_DATA_DIR,
 	  NULL,
-	  "file-contents.db",
-	  "file-contents",
+	  "contents.db",
+	  "contents",
 	  NULL,
 	  1024,
 	  TRACKER_DB_PAGE_SIZE_DONT_SET,
@@ -146,22 +135,11 @@ static TrackerDBDefinition dbs[] = {
 	  FALSE,
 	  FALSE,
  	  0 },
-	{ TRACKER_DB_EMAIL_METADATA,
+	{ TRACKER_DB_FULLTEXT,
 	  TRACKER_DB_LOCATION_DATA_DIR,
 	  NULL,
-	  "email-meta.db",
-	  "email-meta",
-	  NULL,
-	  512,
-	  TRACKER_DB_PAGE_SIZE_DONT_SET,
-	  TRUE,
-	  FALSE,
- 	  0 },
-	{ TRACKER_DB_EMAIL_FULLTEXT,
-	  TRACKER_DB_LOCATION_DATA_DIR,
-	  NULL,
-	  "email-fulltext.db",
-	  "email-fulltext",
+	  "fulltext.db",
+	  "fulltext",
 	  NULL,
 	  512,
 	  TRACKER_DB_PAGE_SIZE_DONT_SET,
@@ -169,18 +147,6 @@ static TrackerDBDefinition dbs[] = {
 	  FALSE,
 	  TRUE,
  	  0 },
-	{ TRACKER_DB_EMAIL_CONTENTS,
-	  TRACKER_DB_LOCATION_DATA_DIR,
-	  NULL,
-	  "email-contents.db",
-	  "email-contents",
-	  NULL,
-	  512,
-	  TRACKER_DB_PAGE_SIZE_DONT_SET,
-	  FALSE,
-	  FALSE,
-	  FALSE,
- 	  0 },
 };
 
 static gboolean		   db_exec_no_reply    (TrackerDBInterface *iface,
@@ -190,14 +156,12 @@ static TrackerDBInterface *db_interface_create (TrackerDB	    db);
 
 static gboolean		   initialized;
 static GHashTable	  *prepared_queries;
-static gchar		  *services_dir;
 static gchar		  *sql_dir;
 static gchar		  *data_dir;
 static gchar		  *user_data_dir;
 static gchar		  *sys_tmp_dir;
 static gpointer		   db_type_enum_class_pointer;
-static TrackerDBInterface *file_iface;
-static TrackerDBInterface *email_iface;
+static TrackerDBInterface *resources_iface;
 
 static const gchar *
 location_to_directory (TrackerDBLocation location)
@@ -266,303 +230,6 @@ load_sql_file (TrackerDBInterface *iface,
 	g_free (path);
 }
 
-static void
-load_metadata_file (TrackerDBInterface *iface,
-		    const gchar        *filename)
-{
-	GKeyFile      *key_file = NULL;
-	GError        *error = NULL;
-	gchar	      *service_file, *str_id;
-	gchar	     **groups, **keys;
-	TrackerProperty  *def;
-	gint	       id, i, j;
-
-	g_message ("Loading metadata file '%s'", filename);
-
-	key_file = g_key_file_new ();
-	service_file = g_build_filename (services_dir, filename, NULL);
-
-	if (!g_key_file_load_from_file (key_file, service_file, G_KEY_FILE_NONE, &error)) {
-		g_critical ("Couldn't load service file, %s", 
-			    error ? error->message : "no error given");
-		g_clear_error (&error);
-		g_free (service_file);
-		g_key_file_free (key_file);
-		return;
-	}
-
-	groups = g_key_file_get_groups (key_file, NULL);
-
-	for (i = 0; groups[i]; i++) {
-		def = tracker_ontology_get_field_by_name (groups[i]);
-
-		if (!def) {
-			g_message ("  Adding ontology metadata:'%s'", groups[i]);
-			tracker_db_interface_execute_procedure (iface,
-								NULL,
-								"InsertMetadataType",
-								groups[i],
-								NULL);
-			id = tracker_db_interface_sqlite_get_last_insert_id (TRACKER_DB_INTERFACE_SQLITE (iface));
-		} else {
-			id = atoi (tracker_property_get_id (def));
-			g_error ("Duplicated metadata description %s", groups[i]);
-		}
-
-		str_id = tracker_guint_to_string (id);
-		keys = g_key_file_get_keys (key_file, groups[i], NULL, NULL);
-
-		for (j = 0; keys[j]; j++) {
-			gchar *value, *new_value;
-
-			value = g_key_file_get_locale_string (key_file, groups[i], keys[j], NULL, NULL);
-
-			if (!value) {
-				continue;
-			}
-
-			new_value = tracker_string_boolean_to_string_gint (value);
-			g_free (value);
-
-			if (strcasecmp (keys[j], "Parent") == 0) {
-				tracker_db_interface_execute_procedure (iface,
-									NULL,
-									"InsertMetaDataChildren",
-									str_id,
-									new_value,
-									NULL);
-			} else if (strcasecmp (keys[j], "DataType") == 0) {
-				GEnumValue *enum_value;
-
-				enum_value = g_enum_get_value_by_nick (g_type_class_peek (TRACKER_TYPE_PROPERTY_TYPE), new_value);
-
-				if (enum_value) {
-					tracker_db_interface_execute_query (iface, NULL,
-									    "update MetaDataTypes set DataTypeID = %d where ID = %d",
-									    enum_value->value, id);
-				} else {
-					g_critical ("Field '%s' doesn't have a valid data type '%s'", groups[i], new_value);
-				}
-			} else {
-				gchar *esc_value;
-
-				esc_value = tracker_escape_string (new_value);
-
-				tracker_db_interface_execute_query (iface, NULL,
-								    "update MetaDataTypes set  %s = '%s' where ID = %d",
-								    keys[j], esc_value, id);
-
-				g_free (esc_value);
-			}
-
-			g_free (new_value);
-		}
-
-		g_free (str_id);
-		g_strfreev (keys);
-	}
-
-	g_strfreev (groups);
-	g_free (service_file);
-	g_key_file_free (key_file);
-}
-
-static void
-load_service_file (TrackerDBInterface *iface,
-		   const gchar	      *filename)
-{
-	TrackerClass	*service;
-	GKeyFile	*key_file = NULL;
-	GError          *error = NULL;
-	gchar		*service_file, *str_id;
-	gchar	       **groups, **keys;
-	gint		 i, j, id;
-
-	g_message ("Loading service file '%s'", filename);
-
-	service_file = g_build_filename (services_dir, filename, NULL);
-
-	key_file = g_key_file_new ();
-
-	if (!g_key_file_load_from_file (key_file, service_file, G_KEY_FILE_NONE, &error)) {
-		g_critical ("Couldn't load service file, %s", 
-			    error ? error->message : "no error given");
-		g_clear_error (&error);
-		g_free (service_file);
-		g_key_file_free (key_file);
-		return;
-	}
-
-	groups = g_key_file_get_groups (key_file, NULL);
-
-	for (i = 0; groups[i]; i++) {
-		service = tracker_ontology_get_service_by_name (groups[i]);
-
-		if (!service) {
-			g_message ("Adding ontology service type:'%s'", groups[i]);
-			tracker_db_interface_execute_procedure (iface,
-								NULL,
-								"InsertServiceType",
-								groups[i],
-								NULL);
-			id = tracker_db_interface_sqlite_get_last_insert_id (TRACKER_DB_INTERFACE_SQLITE (iface));
-		} else {
-			id = tracker_class_get_id (service);
-		}
-
-		str_id = tracker_guint_to_string (id);
-
-		keys = g_key_file_get_keys (key_file, groups[i], NULL, NULL);
-
-		for (j = 0; keys[j]; j++) {
-			if (strcasecmp (keys[j], "TabularMetadata") == 0) {
-				gchar **tab_array;
-				gint	k;
-
-				tab_array = g_key_file_get_string_list (key_file,
-									groups[i],
-									keys[j],
-									NULL,
-									NULL);
-
-				for (k = 0; tab_array[k]; k++) {
-					tracker_db_interface_execute_procedure (iface,
-										NULL,
-										"InsertServiceTabularMetadata",
-										str_id,
-										tab_array[k],
-										NULL);
-				}
-
-				g_strfreev (tab_array);
-			} else if (strcasecmp (keys[j], "TileMetadata") == 0) {
-				gchar **tab_array;
-				gint	k;
-
-				tab_array = g_key_file_get_string_list (key_file,
-									groups[i],
-									keys[j],
-									NULL,
-									NULL);
-
-				for (k = 0; tab_array[k]; k++) {
-					tracker_db_interface_execute_procedure (iface,
-										NULL,
-										"InsertServiceTileMetadata",
-										str_id,
-										tab_array[k],
-										NULL);
-				}
-
-				g_strfreev (tab_array);
-			} else if (strcasecmp (keys[j], "Mimes") == 0) {
-				gchar **tab_array;
-				gint	k;
-
-				tab_array = g_key_file_get_string_list (key_file,
-									groups[i],
-									keys[j],
-									NULL,
-									NULL);
-
-				for (k = 0; tab_array[k]; k++) {
-					tracker_db_interface_execute_procedure (iface, NULL,
-										"InsertMimes",
-										tab_array[k],
-										NULL);
-					tracker_db_interface_execute_query (iface,
-									    NULL,
-									    "update FileMimes set ServiceTypeID = %s where Mime = '%s'",
-									    str_id,
-									    tab_array[k]);
-				}
-
-				g_strfreev (tab_array);
-			} else if (strcasecmp (keys[j], "MimePrefixes") == 0) {
-				gchar **tab_array;
-				gint	k;
-
-				tab_array = g_key_file_get_string_list (key_file,
-									groups[i],
-									keys[j],
-									NULL,
-									NULL);
-
-				for (k = 0; tab_array[k]; k++) {
-					tracker_db_interface_execute_procedure (iface,
-										NULL,
-										"InsertMimePrefixes",
-										tab_array[k],
-										NULL);
-					tracker_db_interface_execute_query (iface,
-									    NULL,
-									    "update FileMimePrefixes set ServiceTypeID = %s where MimePrefix = '%s'",
-									    str_id,
-									    tab_array[k]);
-				}
-
-				g_strfreev (tab_array);
-			} else {
-				gchar *value, *new_value, *esc_value;
-
-				value = g_key_file_get_string (key_file, groups[i], keys[j], NULL);
-				new_value = tracker_string_boolean_to_string_gint (value);
-				esc_value = tracker_escape_string (new_value);
-
-				/* Special case "Parent */
-				if (g_ascii_strcasecmp (keys[j], "parent") == 0) {
-					TrackerDBResultSet *result_set;
-					gchar *query;
-
-					query = g_strdup_printf ("SELECT TypeId FROM ServiceTypes WHERE TypeName = '%s'",
-								 esc_value);
-					result_set = tracker_db_interface_execute_query (iface, NULL, "%s", query);
-					g_free (query);
-
-					if (result_set) {
-						GValue value = {0, };
-						GValue transform = {0, };
-
-						g_value_init (&transform, G_TYPE_STRING);
-						
-						_tracker_db_result_set_get_value (result_set, 0, &value);
-						if (g_value_transform (&value, &transform)) {
-							tracker_db_interface_execute_query (iface,
-											    NULL,
-											    "UPDATE ServiceTypes SET ParentId = '%s' WHERE TypeID = %s",
-											    g_value_get_string (&transform),
-											    str_id);
-
-						}
-						
-						g_value_unset (&value);
-						g_value_unset (&transform);
-						g_object_unref (result_set);
-					}
-				}
-				
-				tracker_db_interface_execute_query (iface,
-								    NULL,
-								    "UPDATE ServiceTypes SET %s = '%s' WHERE TypeID = %s",
-								    keys[j],
-								    esc_value,
-								    str_id);
-
-				g_free (esc_value);
-				g_free (value);
-				g_free (new_value);
-			}
-		}
-
-		g_free (str_id);
-		g_strfreev (keys);
-	}
-
-	g_key_file_free (key_file);
-	g_strfreev (groups);
-	g_free (service_file);
-}
-
 static gboolean
 db_exec_no_reply (TrackerDBInterface *iface,
 		  const gchar	     *query,
@@ -586,7 +253,6 @@ db_exec_no_reply (TrackerDBInterface *iface,
 	return TRUE;
 }
 
-
 static gboolean
 load_prepared_queries (void)
 {
@@ -728,181 +394,6 @@ load_prepared_queries (void)
 	return TRUE;
 }
 
-static TrackerProperty *
-db_row_to_field_def (TrackerDBResultSet *result_set)
-{
-	TrackerProperty	 *field_def;
-	TrackerPropertyType  field_type;
-	gchar		 *id_str, *field_name, *name;
-	gint		  weight, id;
-	gboolean	  embedded, multiple_values, delimited, filtered, store_metadata;
-
-	field_def = tracker_property_new ();
-
-	tracker_db_result_set_get (result_set,
-				   0, &id,
-				   1, &name,
-				   2, &field_type,
-				   3, &field_name,
-				   4, &weight,
-				   5, &embedded,
-				   6, &multiple_values,
-				   7, &delimited,
-				   8, &filtered,
-				   9, &store_metadata,
-				   -1);
-
-	id_str = tracker_gint_to_string (id);
-
-	tracker_property_set_id (field_def, id_str);
-	tracker_property_set_name (field_def, name);
-	tracker_property_set_data_type (field_def, field_type);
-	tracker_property_set_field_name (field_def, field_name);
-	tracker_property_set_weight (field_def, weight);
-	tracker_property_set_embedded (field_def, embedded);
-	tracker_property_set_multiple_values (field_def, multiple_values);
-	tracker_property_set_delimited (field_def, delimited);
-	tracker_property_set_filtered (field_def, filtered);
-	tracker_property_set_store_metadata (field_def, store_metadata);
-
-	g_free (id_str);
-	g_free (field_name);
-	g_free (name);
-
-	return field_def;
-}
-
-static TrackerClass *
-db_row_to_service (TrackerDBResultSet *result_set)
-{
-	TrackerClass *service;
-	GSList	       *new_list = NULL;
-	gint		id, i;
-	gchar	       *name, *parent, *content_metadata, *property_prefix = NULL;
-	gboolean	enabled, embedded, has_metadata, has_fulltext;
-	gboolean	has_thumbs, show_service_files, show_service_directories;
-
-	service = tracker_class_new ();
-
-	tracker_db_result_set_get (result_set,
-				   0, &id,
-				   1, &name,
-				   2, &parent,
-				   3, &property_prefix,
-				   4, &enabled,
-				   5, &embedded,
-				   6, &has_metadata,
-				   7, &has_fulltext,
-				   8, &has_thumbs,
-				   9, &content_metadata,
-				   11, &show_service_files,
-				   12, &show_service_directories,
-				   -1);
-
-	tracker_class_set_id (service, id);
-	tracker_class_set_name (service, name);
-	tracker_class_set_parent (service, parent);
-	tracker_class_set_property_prefix (service, property_prefix);
-	tracker_class_set_enabled (service, enabled);
-	tracker_class_set_embedded (service, embedded);
-	tracker_class_set_has_metadata (service, has_metadata);
-	tracker_class_set_has_full_text (service, has_fulltext);
-	tracker_class_set_has_thumbs (service, has_thumbs);
-	tracker_class_set_content_metadata (service, content_metadata);
-
-	tracker_class_set_show_service_files (service, show_service_files);
-	tracker_class_set_show_service_directories (service, show_service_directories);
-
-	for (i = 13; i < 24; i++) {
-		gchar *metadata;
-
-		tracker_db_result_set_get (result_set, i, &metadata, -1);
-
-		if (metadata) {
-			new_list = g_slist_prepend (new_list, metadata);
-		}
-	}
-
-	/* FIXME: is this necessary?
-	 * This values are set as key metadata in default.service already
-	 */
-#if 0
-	/* Hack to prevent db change late in the cycle, check the
-	 * service name matches "Applications", then add some voodoo.
-	 */
-	if (strcmp (name, "Applications") == 0) {
-		/* These strings should be definitions at the top of
-		 * this file somewhere really.
-		 */
-		new_list = g_slist_prepend (new_list, g_strdup ("App:DisplayName"));
-		new_list = g_slist_prepend (new_list, g_strdup ("App:Exec"));
-		new_list = g_slist_prepend (new_list, g_strdup ("App:Icon"));
-	}
-#endif
-
-	new_list = g_slist_reverse (new_list);
-
-	tracker_class_set_key_metadata (service, new_list);
-	g_slist_foreach (new_list, (GFunc) g_free, NULL);
-	g_slist_free (new_list);
-
-	g_free (name);
-	g_free (parent);
-	g_free (property_prefix);
-	g_free (content_metadata);
-
-	return service;
-}
-
-static GSList *
-db_mime_query (TrackerDBInterface *iface,
-	       const gchar	  *stored_proc,
-	       gint		   service_id)
-{
-	TrackerDBResultSet *result_set;
-	GSList		   *result = NULL;
-	gchar		   *service_id_str;
-
-	service_id_str = g_strdup_printf ("%d", service_id);
-
-	result_set = tracker_db_interface_execute_procedure (iface,
-							     NULL,
-							     stored_proc,
-							     service_id_str,
-							     NULL);
-	g_free (service_id_str);
-
-	if (result_set) {
-		gchar	 *str;
-		gboolean  valid = TRUE;
-
-		while (valid) {
-			tracker_db_result_set_get (result_set, 0, &str, -1);
-			result = g_slist_prepend (result, str);
-			valid = tracker_db_result_set_iter_next (result_set);
-		}
-
-		g_object_unref (result_set);
-	}
-
-	return result;
-}
-
-static GSList *
-db_get_mimes_for_service_id (TrackerDBInterface *iface,
-			     gint		 service_id)
-{
-	return db_mime_query (iface, "GetMimeForServiceId", service_id);
-}
-
-static GSList *
-db_get_mime_prefixes_for_service_id (TrackerDBInterface *iface,
-				     gint		 service_id)
-{
-	return db_mime_query (iface, "GetMimePrefixForServiceId", service_id);
-}
-
-
 /* Converts date/time in UTC format to ISO 8160 standardised format for display */
 static GValue
 function_date_to_str (TrackerDBInterface *interface,
@@ -994,46 +485,50 @@ function_group_concat_final (TrackerDBInterface *interface,
 }
 
 static GValue
-function_get_service_name (TrackerDBInterface *interface,
-			   gint		       argc,
-			   GValue	       values[])
-{
-	GValue result = { 0, };
-	const gchar *str;
-
-	str = tracker_ontology_get_service_by_id (g_value_get_int (&values[0]));
-	g_value_init (&result, G_TYPE_STRING);
-	g_value_set_string (&result, str);
-
-	return result;
-}
-
-static GValue
-function_get_service_type (TrackerDBInterface *interface,
-			   gint		       argc,
-			   GValue	       values[])
+function_sparql_regex (TrackerDBInterface *interface,
+		       gint		     argc,
+		       GValue		     values[])
 {
-	GValue result = { 0, };
-	gint   id;
+	GValue	result = { 0, };
+	gboolean	ret;
+	const gchar *text, *pattern, *flags;
+	GRegexCompileFlags regex_flags;
 
-	id = tracker_ontology_get_service_id_by_name (g_value_get_string (&values[0]));
-	g_value_init (&result, G_TYPE_INT);
-	g_value_set_int (&result, id);
+	if (argc != 3) {
+		g_critical ("Invalid argument count");
+		return result;
+	}
 
-	return result;
-}
+	text = g_value_get_string (&values[0]);
+	pattern = g_value_get_string (&values[1]);
+	flags = g_value_get_string (&values[2]);
+
+	regex_flags = 0;
+	while (*flags) {
+		switch (*flags) {
+		case 's':
+			regex_flags |= G_REGEX_DOTALL;
+			break;
+		case 'm':
+			regex_flags |= G_REGEX_MULTILINE;
+			break;
+		case 'i':
+			regex_flags |= G_REGEX_CASELESS;
+			break;
+		case 'x':
+			regex_flags |= G_REGEX_EXTENDED;
+			break;
+		default:
+			g_critical ("Invalid SPARQL regex flag '%c'", *flags);
+			return result;
+		}
+		flags++;
+	}
 
-static GValue
-function_get_max_service_type (TrackerDBInterface *interface,
-			       gint		   argc,
-			       GValue		   values[])
-{
-	GValue result = { 0, };
-	gint   id;
+	ret = g_regex_match_simple (pattern, text, regex_flags, 0);
 
-	id = tracker_ontology_get_service_id_by_name (g_value_get_string (&values[0]));
 	g_value_init (&result, G_TYPE_INT);
-	g_value_set_int (&result, id);
+	g_value_set_int (&result, ret);
 
 	return result;
 }
@@ -1331,21 +826,13 @@ db_set_params (TrackerDBInterface *iface,
 							     function_date_to_str,
 							     1);
 		tracker_db_interface_sqlite_create_function (iface,
-							     "GetServiceName",
-							     function_get_service_name,
-							     1);
-		tracker_db_interface_sqlite_create_function (iface,
-							     "GetServiceTypeID",
-							     function_get_service_type,
-							     1);
-		tracker_db_interface_sqlite_create_function (iface,
-							     "GetMaxServiceTypeID",
-							     function_get_max_service_type,
-							     1);
-		tracker_db_interface_sqlite_create_function (iface,
 							     "REGEXP",
 							     function_regexp,
 							     2);
+		tracker_db_interface_sqlite_create_function (iface,
+							     "SparqlRegex",
+							     function_sparql_regex,
+							     3);
 
 		tracker_db_interface_sqlite_create_function (iface,
 							     "uncompress",
@@ -1374,107 +861,6 @@ db_set_params (TrackerDBInterface *iface,
 	}
 }
 
-static void
-db_get_static_data (TrackerDBInterface *iface)
-{
-	TrackerDBResultSet *result_set;
-
-	/* Get static metadata info */
-	result_set = tracker_db_interface_execute_procedure (iface,
-							     NULL,
-							     "GetMetadataTypes",
-							     NULL);
-
-	if (result_set) {
-		gboolean valid = TRUE;
-		gint	 id;
-
-		while (valid) {
-			TrackerDBResultSet *result_set2;
-			TrackerProperty	   *def;
-			GSList		   *child_ids = NULL;
-
-			def = db_row_to_field_def (result_set);
-
-			result_set2 = tracker_db_interface_execute_procedure (iface,
-									      NULL,
-									      "GetMetadataAliases",
-									      tracker_property_get_id (def),
-									      NULL);
-
-			if (result_set2) {
-				valid = TRUE;
-
-				while (valid) {
-					tracker_db_result_set_get (result_set2, 1, &id, -1);
-					child_ids = g_slist_prepend (child_ids,
-								     tracker_gint_to_string (id));
-
-					valid = tracker_db_result_set_iter_next (result_set2);
-				}
-
-				tracker_property_set_child_ids (def, child_ids);
-				g_object_unref (result_set2);
-
-				g_slist_foreach (child_ids, (GFunc) g_free, NULL);
-				g_slist_free (child_ids);
-			}
-
-			tracker_ontology_field_add (def);
-			g_object_unref (def);
-
-			valid = tracker_db_result_set_iter_next (result_set);
-		}
-
-		g_object_unref (result_set);
-	}
-
-	/* Get static service info */
-	result_set = tracker_db_interface_execute_procedure (iface,
-							     NULL,
-							     "GetAllServices",
-							     NULL);
-
-	if (result_set) {
-		gboolean valid = TRUE;
-
-		while (valid) {
-			TrackerClass *service;
-			GSList	       *mimes, *mime_prefixes;
-			const gchar    *name;
-			gint		id;
-
-			service = db_row_to_service (result_set);
-
-			if (!service) {
-				continue;
-			}
-
-			id = tracker_class_get_id (service);
-			name = tracker_class_get_name (service);
-
-			mimes = db_get_mimes_for_service_id (iface, id);
-			mime_prefixes = db_get_mime_prefixes_for_service_id (iface, id);
-
-			g_message ("Loading ontology service:'%s' with id:%d and mimes:%d",
-				   name,
-				   id,
-				   g_slist_length (mimes));
-
-			tracker_ontology_service_add (service,
-						      mimes,
-						      mime_prefixes);
-
-			g_slist_free (mimes);
-			g_slist_free (mime_prefixes);
-			g_object_unref (service);
-
-			valid = tracker_db_result_set_iter_next (result_set);
-		}
-
-		g_object_unref (result_set);
-	}
-}
 
 static const gchar *
 db_type_to_string (TrackerDB db)
@@ -1536,98 +922,44 @@ db_interface_get_common (void)
 	iface = db_interface_get (TRACKER_DB_COMMON, &create);
 
 	if (create) {
-		GDir        *services;
-		const gchar *conf_file;
-
 		tracker_db_interface_start_transaction (iface);
 
 		/* Create tables */
 		load_sql_file (iface, "sqlite-tracker.sql", NULL);
-		load_sql_file (iface, "sqlite-metadata.sql", NULL);
-		load_sql_file (iface, "sqlite-service-types.sql", NULL);
-
-		/*
-		 * Loading .service and .metadata files. "default." first because
-		 * contain the parent categories. 
-		 */
-		load_service_file (iface, "default.service");
-		load_metadata_file (iface, "default.metadata");
-
-		services = g_dir_open (services_dir, 0, NULL);
-
-		conf_file = g_dir_read_name (services);
-
-		while (conf_file) {
-			if (!strcmp (conf_file, "default.service") ||
-			    !strcmp (conf_file, "default.metadata")) {
-				conf_file = g_dir_read_name (services);
-				continue;
-			}
-
-			if (g_str_has_suffix (conf_file, ".service")) {
-				load_service_file (iface, conf_file);
-			}
-
-			if (g_str_has_suffix (conf_file, ".metadata")) {
-				load_metadata_file (iface, conf_file);
-			}
-
-			conf_file = g_dir_read_name (services);
-		}
-
-		g_dir_close (services);
 
 		tracker_db_interface_end_transaction (iface);
 	}
 
-	/* Load static data into tracker ontology */
-	db_get_static_data (iface);
-
 	return iface;
 }
 
 static TrackerDBInterface *
-db_interface_get_file_metadata (void)
+db_interface_get_fulltext (void)
 {
 	TrackerDBInterface *iface;
 	gboolean	    create;
 
-	iface = db_interface_get (TRACKER_DB_FILE_METADATA, &create);
-
-	if (create) {
-		tracker_db_interface_start_transaction (iface);
-		load_sql_file (iface, "sqlite-service.sql", NULL);
-		load_sql_file (iface, "sqlite-service-triggers.sql", "!");
-		tracker_db_interface_end_transaction (iface);
-	}
-
-	return iface;
-}
-
-static TrackerDBInterface *
-db_interface_get_file_fulltext (void)
-{
-	TrackerDBInterface *iface;
-	gboolean	    create;
-
-	iface = db_interface_get (TRACKER_DB_FILE_FULLTEXT, &create);
+	iface = db_interface_get (TRACKER_DB_FULLTEXT, &create);
 
+	/*
+	 * disabled to avoid warnings while not implemented
 	if (create) {
 		tracker_db_interface_start_transaction (iface);
 		load_sql_file (iface, "sqlite-fulltext.sql", NULL);
 		tracker_db_interface_end_transaction (iface);
 	}
+	 */
 
 	return iface;
 }
 
 static TrackerDBInterface *
-db_interface_get_file_contents (void)
+db_interface_get_contents (void)
 {
 	TrackerDBInterface *iface;
 	gboolean	    create;
 
-	iface = db_interface_get (TRACKER_DB_FILE_CONTENTS, &create);
+	iface = db_interface_get (TRACKER_DB_CONTENTS, &create);
 
 	if (create) {
 		tracker_db_interface_start_transaction (iface);
@@ -1650,69 +982,17 @@ db_interface_get_file_contents (void)
 
 
 static TrackerDBInterface *
-db_interface_get_email_metadata (void)
+db_interface_get_metadata (void)
 {
 	TrackerDBInterface *iface;
 	gboolean	    create;
 
-	iface = db_interface_get (TRACKER_DB_EMAIL_METADATA, &create);
-
-	if (create) {
-		tracker_db_interface_start_transaction (iface);
-		load_sql_file (iface, "sqlite-service.sql", NULL);
-		load_sql_file (iface, "sqlite-email.sql", NULL);
-		load_sql_file (iface, "sqlite-service-triggers.sql", "!");
-		tracker_db_interface_end_transaction (iface);
-	}
-
-	return iface;
-}
-
-static TrackerDBInterface *
-db_interface_get_email_fulltext (void)
-{
-	TrackerDBInterface *iface;
-	gboolean	    create;
-
-	iface = db_interface_get (TRACKER_DB_EMAIL_FULLTEXT, &create);
-
-	if (create) {
-		tracker_db_interface_start_transaction (iface);
-		load_sql_file (iface, "sqlite-fulltext.sql", NULL);
-		tracker_db_interface_end_transaction (iface);
-	}
+	iface = db_interface_get (TRACKER_DB_METADATA, &create);
 
 	return iface;
 }
 
 static TrackerDBInterface *
-db_interface_get_email_contents (void)
-{
-	TrackerDBInterface *iface;
-	gboolean	    create;
-
-	iface = db_interface_get (TRACKER_DB_EMAIL_CONTENTS, &create);
-
-	if (create) {
-		tracker_db_interface_start_transaction (iface);
-		load_sql_file (iface, "sqlite-contents.sql", NULL);
-		tracker_db_interface_end_transaction (iface);
-	}
-
-	tracker_db_interface_sqlite_create_function (iface,
-						     "uncompress",
-						     function_uncompress,
-						     1);
-	tracker_db_interface_sqlite_create_function (iface,
-						     "compress",
-						     function_compress,
-						     1);
-
-	return iface;
-}
-
-
-static TrackerDBInterface *
 db_interface_create (TrackerDB db)
 {
 	switch (db) {
@@ -1722,23 +1002,14 @@ db_interface_create (TrackerDB db)
 	case TRACKER_DB_COMMON:
 		return db_interface_get_common ();
 
-	case TRACKER_DB_FILE_METADATA:
-		return db_interface_get_file_metadata ();
-		
-	case TRACKER_DB_FILE_FULLTEXT:
-		return db_interface_get_file_fulltext ();	
+	case TRACKER_DB_METADATA:
+		return db_interface_get_metadata ();
 
-	case TRACKER_DB_FILE_CONTENTS:
-		return db_interface_get_file_contents ();
+	case TRACKER_DB_FULLTEXT:
+		return db_interface_get_fulltext ();	
 
-	case TRACKER_DB_EMAIL_METADATA:
-		return db_interface_get_email_metadata ();
-		
-	case TRACKER_DB_EMAIL_FULLTEXT:
-		return db_interface_get_email_fulltext ();	
-		
-	case TRACKER_DB_EMAIL_CONTENTS:
-		return db_interface_get_email_contents ();
+	case TRACKER_DB_CONTENTS:
+		return db_interface_get_contents ();
 
 	default:
 		g_critical ("This TrackerDB type:%d->'%s' has no interface set up yet!!",
@@ -1829,15 +1100,13 @@ db_set_version (void)
 static void
 db_manager_analyze (TrackerDB db)
 {
-	TrackerDBInterface *iface;
 	guint64             current_mtime;
 
 	current_mtime = tracker_file_get_mtime (dbs[db].abs_filename);
 
 	if (current_mtime > dbs[db].mtime) {
 		g_message ("  Analyzing DB:'%s'", dbs[db].name);
-		iface = tracker_db_manager_get_db_interface (db);
-		db_exec_no_reply (iface, "ANALYZE %s.Services", dbs[db].name);
+		db_exec_no_reply (dbs[db].iface, "ANALYZE %s.Services", dbs[db].name);
 
 		/* Remember current mtime for future */
 		dbs[db].mtime = current_mtime;
@@ -1856,18 +1125,12 @@ tracker_db_get_type (void)
 			{ TRACKER_DB_COMMON,
 			  "TRACKER_DB_COMMON",
 			  "common" },
-			{ TRACKER_DB_FILE_METADATA,
-			  "TRACKER_DB_FILE_METADATA",
-			  "file metadata" },
-			{ TRACKER_DB_FILE_CONTENTS,
-			  "TRACKER_DB_FILE_CONTENTS",
-			  "file contents" },
-			{ TRACKER_DB_EMAIL_METADATA,
-			  "TRACKER_DB_EMAIL_METADATA",
-			  "email metadata" },
-			{ TRACKER_DB_EMAIL_CONTENTS,
-			  "TRACKER_DB_EMAIL_CONTENTS",
-			  "email contents" },
+			{ TRACKER_DB_METADATA,
+			  "TRACKER_DB_METADATA",
+			  "metadata" },
+			{ TRACKER_DB_CONTENTS,
+			  "TRACKER_DB_CONTENTS",
+			  "contents" },
 			{ 0, NULL, NULL }
 		};
 
@@ -1880,7 +1143,8 @@ tracker_db_get_type (void)
 static void
 tracker_db_manager_ensure_locale (void)
 {
-	TrackerDBInterface *common, *iface;
+	TrackerDBInterface *common;
+	TrackerDBStatement *stmt;
 	TrackerDBResultSet *result_set;
 	const gchar *current_locale;
 	gchar *stored_locale = NULL;
@@ -1888,7 +1152,10 @@ tracker_db_manager_ensure_locale (void)
 	current_locale = setlocale (LC_COLLATE, NULL);
 
 	common = dbs[TRACKER_DB_COMMON].iface;
-	result_set = tracker_db_interface_execute_procedure (common, NULL, "GetCollationLocale", NULL);
+
+	stmt = tracker_db_interface_create_statement (common, "SELECT OptionValue FROM Options WHERE OptionKey = 'CollationLocale'");
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 
 	if (result_set) {
 		tracker_db_result_set_get (result_set, 0, &stored_locale, -1);
@@ -1896,23 +1163,13 @@ tracker_db_manager_ensure_locale (void)
 	}
 
 	if (g_strcmp0 (current_locale, stored_locale) != 0) {
-		guint collate_key;
 		/* Locales differ, update collate keys */
 		g_message ("Updating DB locale dependent data to: %s\n", current_locale);
 
-		iface = dbs[TRACKER_DB_FILE_METADATA].iface;
-		tracker_db_interface_execute_procedure (iface, NULL, "UpdateMetadataCollation", NULL);
-
-		for (collate_key = 1; collate_key<6; collate_key++) {
-			tracker_db_interface_execute_query (iface, NULL,
-			   		    "UPDATE Services SET KeyMetadataCollation%d=CollateKey(KeyMetadata%d)",
-					    collate_key, collate_key);
-		} 
-
-		iface = dbs[TRACKER_DB_EMAIL_METADATA].iface;
-		tracker_db_interface_execute_procedure (iface, NULL, "UpdateMetadataCollation", NULL);
-
-		tracker_db_interface_execute_procedure (common, NULL, "SetCollationLocale", current_locale, NULL);
+		stmt = tracker_db_interface_create_statement (common, "UPDATE Options SET OptionValue = ? WHERE OptionKey = 'CollationLocale'");
+		tracker_db_statement_bind_text (stmt, 0, current_locale);
+		tracker_db_statement_execute (stmt, NULL);
+		g_object_unref (stmt);
 	}
 
 	g_free (stored_locale);
@@ -1955,27 +1212,33 @@ tracker_db_manager_init (TrackerDBManagerFlags	flags,
 	/* Set up locations */
 	g_message ("Setting database locations");
 
-	services_dir = g_build_filename (SHAREDIR,
-					 "tracker",
-					 "services",
-					 NULL);
-	sql_dir = g_build_filename (SHAREDIR,
-				    "tracker",
-				    NULL);
-
-	user_data_dir = g_build_filename (g_get_user_data_dir (),
-					  "tracker",
-					  "data",
-					  NULL);
-
-	data_dir = g_build_filename (g_get_user_cache_dir (),
-				     "tracker",
-				     NULL);
-
 	filename = g_strdup_printf ("tracker-%s", g_get_user_name ());
 	sys_tmp_dir = g_build_filename (g_get_tmp_dir (), filename, NULL);
 	g_free (filename);
 
+	if (flags & TRACKER_DB_MANAGER_TEST_MODE) {
+		sql_dir = g_build_filename ("..", "..",
+					    "data",
+					    "db",
+					    NULL);
+
+		user_data_dir = g_strdup (sys_tmp_dir);
+		data_dir = g_strdup (sys_tmp_dir);
+	} else {
+		sql_dir = g_build_filename (SHAREDIR,
+					    "tracker",
+					    NULL);
+
+		user_data_dir = g_build_filename (g_get_user_data_dir (),
+						  "tracker",
+						  "data",
+						  NULL);
+
+		data_dir = g_build_filename (g_get_user_cache_dir (),
+					     "tracker",
+					     NULL);
+	}
+
 	/* Make sure the directories exist */
 	g_message ("Checking database directories exist");
 
@@ -2007,6 +1270,10 @@ tracker_db_manager_init (TrackerDBManagerFlags	flags,
 			dbs[i].cache_size /= 2;
 		}
 
+		/* Check we have each database in place, if one is
+		 * missing, we reindex.
+		 */
+
 		/* No need to check for other files not existing (for
 		 * reindex) if one is already missing.
 		 */
@@ -2099,6 +1366,11 @@ tracker_db_manager_init (TrackerDBManagerFlags	flags,
 	tracker_db_manager_ensure_locale ();
 
 	initialized = TRUE;
+
+	resources_iface = tracker_db_manager_get_db_interfaces (3,
+							    TRACKER_DB_METADATA,
+							    TRACKER_DB_CONTENTS,
+							    TRACKER_DB_COMMON);
 }
 
 void
@@ -2130,17 +1402,11 @@ tracker_db_manager_shutdown (void)
 	g_free (data_dir);
 	g_free (user_data_dir);
 	g_free (sys_tmp_dir);
-	g_free (services_dir);
 	g_free (sql_dir);
 
-	if (file_iface) {
-		g_object_unref (file_iface);
-		file_iface = NULL;
-	}
-
-	if (email_iface) {
-		g_object_unref (email_iface);
-		email_iface = NULL;
+	if (resources_iface) {
+		g_object_unref (resources_iface);
+		resources_iface = NULL;
 	}
 
 
@@ -2198,9 +1464,8 @@ tracker_db_manager_optimize (void)
 		return;
 	}
 
-	/* Optimize the file/email content databases */
-	db_manager_analyze (TRACKER_DB_FILE_METADATA);
-	db_manager_analyze (TRACKER_DB_EMAIL_METADATA);
+	/* Optimize the metadata database */
+	db_manager_analyze (TRACKER_DB_METADATA);
 }
 
 const gchar *
@@ -2305,112 +1570,11 @@ tracker_db_manager_get_db_interfaces_ro (gint num, ...)
  * returns: (callee-owns): a database connection
  **/
 TrackerDBInterface *
-tracker_db_manager_get_db_interface (TrackerDB db)
+tracker_db_manager_get_db_interface (void)
 {
 	g_return_val_if_fail (initialized != FALSE, NULL);
 
-	return dbs[db].iface;
-}
-
-/**
- * tracker_db_manager_get_db_interface_by_service:
- * @service: the server for which you'll use the database connection
- *
- * Request a database connection that can be used for @service. At this moment
- * service can either be "Files", "Emails", "Attachments".
- *
- * The caller must NOT g_object_unref the result
- *
- * returns: (callee-owns): a database connection
- **/
-TrackerDBInterface *
-tracker_db_manager_get_db_interface_by_service (const gchar *service)
-{
-	TrackerDBInterface	  *iface;
-	TrackerDBType		   type;
-
-	g_return_val_if_fail (initialized != FALSE, NULL);
-
-	type = tracker_ontology_get_service_db_by_name (service);
-
-	switch (type) {
-	case TRACKER_DB_TYPE_EMAIL:
-		if (!email_iface) {
-			email_iface = tracker_db_manager_get_db_interfaces (3,
-									    TRACKER_DB_COMMON,
-									    TRACKER_DB_EMAIL_CONTENTS,
-									    TRACKER_DB_EMAIL_METADATA);
-		}
-
-		iface = email_iface;
-		break;
-
-	case TRACKER_DB_TYPE_UNKNOWN:
-	case TRACKER_DB_TYPE_DATA:
-	case TRACKER_DB_TYPE_INDEX:
-	case TRACKER_DB_TYPE_COMMON:
-	case TRACKER_DB_TYPE_CONTENT:
-	case TRACKER_DB_TYPE_USER:
-		g_warning ("Defaulting to Files DB. Strange DB Type for service '%s'", 
-			   service);
-
-	case TRACKER_DB_TYPE_FILES:
-	default:
-		if (!file_iface) {
-			file_iface = tracker_db_manager_get_db_interfaces (3,
-									   TRACKER_DB_COMMON,
-									   TRACKER_DB_FILE_CONTENTS,
-									   TRACKER_DB_FILE_METADATA);
-		}
-
-		iface = file_iface;
-		break;
-	}
-
-	return iface;
-}
-
-TrackerDBInterface *
-tracker_db_manager_get_db_interface_by_type (const gchar	  *service,
-					     TrackerDBContentType  content_type)
-{
-	TrackerDBType type;
-	TrackerDB     db;
-
-	g_return_val_if_fail (initialized != FALSE, NULL);
-	g_return_val_if_fail (service != NULL, NULL);
-
-	type = tracker_ontology_get_service_db_by_name (service);
-
-	switch (type) {
-	case TRACKER_DB_TYPE_EMAIL:
-		if (content_type == TRACKER_DB_CONTENT_TYPE_METADATA) {
-			db = TRACKER_DB_EMAIL_METADATA;
-		} else {
-			db = TRACKER_DB_EMAIL_CONTENTS;
-		}
-		break;
-
-	case TRACKER_DB_TYPE_FILES:
-		if (content_type == TRACKER_DB_CONTENT_TYPE_METADATA) {
-			db = TRACKER_DB_FILE_METADATA;
-		} else {
-			db = TRACKER_DB_FILE_CONTENTS;
-		}
-		break;
-
-	case TRACKER_DB_TYPE_UNKNOWN:
-	case TRACKER_DB_TYPE_DATA:
-	case TRACKER_DB_TYPE_INDEX:
-	case TRACKER_DB_TYPE_COMMON:
-	case TRACKER_DB_TYPE_CONTENT:
-	case TRACKER_DB_TYPE_USER:
-	default:
-		g_warning ("Database type not supported");
-		return NULL;
-	}
-
-	return tracker_db_manager_get_db_interface (db);
+	return resources_iface;
 }
 
 gboolean
@@ -2419,19 +1583,11 @@ tracker_db_manager_are_db_too_big (void)
 	const gchar *filename_const;
 	gboolean     too_big;
 
-	filename_const = tracker_db_manager_get_file (TRACKER_DB_FILE_METADATA);
-	too_big = tracker_file_get_size (filename_const) > TRACKER_DB_MAX_FILE_SIZE;
-
-	if (too_big) {
-		g_critical ("File metadata database is too big, discontinuing indexing");
-		return TRUE;
-	}
-
-	filename_const = tracker_db_manager_get_file (TRACKER_DB_EMAIL_METADATA);
+	filename_const = tracker_db_manager_get_file (TRACKER_DB_METADATA);
 	too_big = tracker_file_get_size (filename_const) > TRACKER_DB_MAX_FILE_SIZE;
 
 	if (too_big) {
-		g_critical ("Email metadata database is too big, discontinuing indexing");
+		g_critical ("Metadata database is too big, discontinuing indexing");
 		return TRUE;
 	}
 
diff --git a/src/libtracker-db/tracker-db-manager.h b/src/libtracker-db/tracker-db-manager.h
index 7a8df32..fe2e724 100644
--- a/src/libtracker-db/tracker-db-manager.h
+++ b/src/libtracker-db/tracker-db-manager.h
@@ -32,12 +32,9 @@ G_BEGIN_DECLS
 typedef enum {
 	TRACKER_DB_UNKNOWN,
 	TRACKER_DB_COMMON,
-	TRACKER_DB_FILE_METADATA,
-	TRACKER_DB_FILE_CONTENTS,
-	TRACKER_DB_FILE_FULLTEXT,
-	TRACKER_DB_EMAIL_METADATA,
-	TRACKER_DB_EMAIL_CONTENTS,
-	TRACKER_DB_EMAIL_FULLTEXT,
+	TRACKER_DB_METADATA,
+	TRACKER_DB_CONTENTS,
+	TRACKER_DB_FULLTEXT,
 } TrackerDB;
 
 typedef enum {
@@ -50,13 +47,10 @@ typedef enum {
 	TRACKER_DB_MANAGER_FORCE_REINDEX    = 1 << 1,
 	TRACKER_DB_MANAGER_REMOVE_CACHE     = 1 << 2,
 	TRACKER_DB_MANAGER_LOW_MEMORY_MODE  = 1 << 3,
-	TRACKER_DB_MANAGER_REMOVE_ALL       = 1 << 4
+	TRACKER_DB_MANAGER_REMOVE_ALL       = 1 << 4,
+	TRACKER_DB_MANAGER_TEST_MODE        = 1 << 5
 } TrackerDBManagerFlags;
 
-#define TRACKER_DB_FOR_FILE_SERVICE	"Files"
-#define TRACKER_DB_FOR_EMAIL_SERVICE	"Emails"
-#define TRACKER_DB_FOR_VIRTUAL_SERVICE  "Virtual"
-
 GType	     tracker_db_get_type			    (void) G_GNUC_CONST;
 
 void	     tracker_db_manager_init			    (TrackerDBManagerFlags  flags,
@@ -69,16 +63,11 @@ void         tracker_db_manager_optimize		    (void);
 
 const gchar *tracker_db_manager_get_file		    (TrackerDB		    db);
 TrackerDBInterface *
-	     tracker_db_manager_get_db_interface	    (TrackerDB		    db);
+	     tracker_db_manager_get_db_interface	    (void);
 TrackerDBInterface *
 	     tracker_db_manager_get_db_interfaces	    (gint num, ...);
 TrackerDBInterface *
 	     tracker_db_manager_get_db_interfaces_ro	    (gint num, ...);
-TrackerDBInterface *
-	     tracker_db_manager_get_db_interface_by_service (const gchar	   *service);
-TrackerDBInterface *
-	     tracker_db_manager_get_db_interface_by_type    (const gchar	   *service,
-							     TrackerDBContentType   content_type);
 gboolean     tracker_db_manager_are_db_too_big		    (void);
 
 G_END_DECLS
diff --git a/src/libtracker-gtk/tracker-metadata-tile.c b/src/libtracker-gtk/tracker-metadata-tile.c
index 9e9e090..72afac7 100644
--- a/src/libtracker-gtk/tracker-metadata-tile.c
+++ b/src/libtracker-gtk/tracker-metadata-tile.c
@@ -928,6 +928,8 @@ _property_to_label (GtkWidget *label, const char *prop, const char *string)
  *
  **/
 
+/* TODO: Port to SPARQL */
+#if 0
 void
 tracker_metadata_tile_set_uri (TrackerMetadataTile *tile, const gchar *uri,
 							  ServiceType service_type,
@@ -948,8 +950,6 @@ tracker_metadata_tile_set_uri (TrackerMetadataTile *tile, const gchar *uri,
 		gtk_widget_hide (priv->image);
 	}
 
-	/* TODO: Port to SPARQL */
-#if 0
 	/* call correct function according to service type */
 	switch (service_type) {
 
@@ -1029,7 +1029,6 @@ tracker_metadata_tile_set_uri (TrackerMetadataTile *tile, const gchar *uri,
 
 		break;
 	}
-#endif
 
 
 	if (uri) {
@@ -1041,6 +1040,7 @@ tracker_metadata_tile_set_uri (TrackerMetadataTile *tile, const gchar *uri,
 
 	gtk_widget_queue_draw (GTK_WIDGET (tile));
 }
+#endif
 
 static void
 tracker_metadata_tile_show (TrackerMetadataTile *tile)
diff --git a/src/libtracker-gtk/tracker-metadata-tile.h b/src/libtracker-gtk/tracker-metadata-tile.h
index 09dda05..53fad96 100644
--- a/src/libtracker-gtk/tracker-metadata-tile.h
+++ b/src/libtracker-gtk/tracker-metadata-tile.h
@@ -50,10 +50,12 @@ GType	   tracker_metadata_tile_get_type  (void);
 
 GtkWidget* tracker_metadata_tile_new	   (void);
 
+#if 0
 void	   tracker_metadata_tile_set_uri (TrackerMetadataTile		*tile,
 					  const gchar			*uri,
 					  ServiceType			service_type,
 					  const gchar			*type,
 					  GdkPixbuf			*icon);
+#endif
 
 #endif /* TRACKER_METADATA_TILE_H */
diff --git a/src/libtracker-gtk/tracker-tag-bar.c b/src/libtracker-gtk/tracker-tag-bar.c
index 35e0bef..311338f 100644
--- a/src/libtracker-gtk/tracker-tag-bar.c
+++ b/src/libtracker-gtk/tracker-tag-bar.c
@@ -49,7 +49,9 @@ struct _TrackerTagBarPrivate
 	gchar *uri;
 	const gchar *active_tag;
 
+#if 0
 	ServiceType type;
+#endif
 
 	GtkWidget *tag_box;
 	GtkWidget *add_button;
@@ -179,10 +181,11 @@ remove_tag_activate_cb(GtkMenuItem *menu_item, TrackerTagBar *bar)
 		g_print ("Tag Removal Error : %s", error->message);
 		return;
 	}
-#endif
+
 	gchar *temp = g_strdup (priv->uri);
 	tracker_tag_bar_set_uri (bar, priv->type, temp);
 	g_free (temp);
+#endif
 }
 
 static void
@@ -210,25 +213,25 @@ _on_apply_add_tag (GtkButton *but, TrackerTagBar *bar)
 
 	text = gtk_entry_get_text (GTK_ENTRY (priv->entry));
 
+	/* TODO: Port to SPARQL */
+#if 0
 	if (strcmp (text, "Type tags you want to add here, separated by commas") != 0) {
 
 		tags = g_strsplit (text, ",", 0);
 
-	/* TODO: Port to SPARQL */
-#if 0
 		tracker_keywords_add(priv->client, priv->type, priv->uri,
 				 tags, &error);
 		if (error) {
 			g_print ("Tag Addition Error : %s", error->message);
 			return;
 		}
-#endif
 	}
 
 	_on_close_add_tag (but, bar);
 	gchar *temp = g_strdup (priv->uri);
 	tracker_tag_bar_set_uri (bar, priv->type, temp);
 	g_free (temp);
+#endif
 }
 
 static void
@@ -320,6 +323,8 @@ _tag_bar_add_tag (TrackerTagBar *bar, GtkWidget *box, const char *tag)
 }
 
 /* HEADER FUNCTIONS */
+	/* TODO: Port to SPARQL */
+#if 0
 void
 tracker_tag_bar_set_uri (TrackerTagBar *bar, ServiceType type, const gchar *uri)
 {
@@ -332,13 +337,11 @@ tracker_tag_bar_set_uri (TrackerTagBar *bar, ServiceType type, const gchar *uri)
 	priv->uri = g_strdup (uri);
 	priv->type = type;
 
-	/* TODO: Port to SPARQL */
-#if 0
 	tracker_keywords_get_async (priv->client, priv->type, uri,
 				    (TrackerArrayReply)_keywords_reply,
 				    bar);
-#endif
 }
+#endif
 
 /* TRACKER TAG BAR NEW */
 static void
diff --git a/src/libtracker-gtk/tracker-tag-bar.h b/src/libtracker-gtk/tracker-tag-bar.h
index 6665eff..8452a0f 100644
--- a/src/libtracker-gtk/tracker-tag-bar.h
+++ b/src/libtracker-gtk/tracker-tag-bar.h
@@ -54,10 +54,12 @@ GtkWidget *tracker_tag_bar_new (void);
 uri has to be a local uri i.e.
 '/home/john/doe.mp3' not 'file:///home/john/doe.mp3'
 */
+#if 0
 void	   tracker_tag_bar_set_uri (TrackerTagBar		*bar,
 				    ServiceType			type,
 				    const gchar			*uri
 				   );
+#endif
 
 GType tracker_tag_bar_get_type (void);
 
diff --git a/src/libtracker/Makefile.am b/src/libtracker/Makefile.am
index 498f3cf..2975001 100644
--- a/src/libtracker/Makefile.am
+++ b/src/libtracker/Makefile.am
@@ -28,6 +28,7 @@ include_HEADERS = 				\
 # Generate DBus files from XML data.
 dbus_sources = 					\
 	tracker-daemon-glue.h			\
+	tracker-resources-glue.h		\
 	tracker-search-glue.h
 
 %-glue.h: $(top_srcdir)/data/dbus/%.xml
diff --git a/src/libtracker/tracker.c b/src/libtracker/tracker.c
index 2bee793..8f8c106 100644
--- a/src/libtracker/tracker.c
+++ b/src/libtracker/tracker.c
@@ -24,14 +24,14 @@
 #include "tracker.h"
 
 #include "tracker-daemon-glue.h"
+#include "tracker-resources-glue.h"
 #include "tracker-search-glue.h"
 
-#define TRACKER_CLASS			"org.freedesktop.Tracker"
+#define TRACKER_SERVICE			"org.freedesktop.Tracker"
 #define TRACKER_OBJECT			"/org/freedesktop/Tracker"
 #define TRACKER_INTERFACE		"org.freedesktop.Tracker"
+#define TRACKER_INTERFACE_RESOURCES	"org.freedesktop.Tracker.Resources"
 #define TRACKER_INTERFACE_SEARCH	"org.freedesktop.Tracker.Search"
-#define TRACKER_INTERFACE_MUSIC		"org.freedesktop.Tracker.Music"
-#define TRACKER_INTERFACE_PLAYLISTS	"org.freedesktop.Tracker.PlayLists"
 
 typedef struct {
 	TrackerArrayReply callback;
@@ -44,12 +44,6 @@ typedef struct {
 } GPtrArrayCallBackStruct;
 
 typedef struct {
-	TrackerHashTableReply	callback;
-	gpointer		data;
-} HashTableCallBackStruct;
-
-
-typedef struct {
 	TrackerBooleanReply callback;
 	gpointer	  data;
 } BooleanCallBackStruct;
@@ -70,105 +64,6 @@ typedef struct {
 } VoidCallBackStruct;
 
 
-const char *tracker_class_types[] = {
-	"Files",
-	"Folders",
-	"Documents",
-	"Images",
-	"Music",
-	"Videos",
-	"Text",
-	"Development",
-	"Other",
-	"VFS",
-	"VFSFolders",
-	"VFSDocuments",
-	"VFSImages",
-	"VFSMusic",
-	"VFSVideos",
-	"VFSText",
-	"VFSDevelopment",
-	"VFSOther",
-	"Conversations",
-	"Playlists",
-	"Applications",
-	"Contacts",
-	"Emails",
-	"EmailAttachments",
-	"Appointments",
-	"Tasks",
-	"Bookmarks",
-	"WebHistory",
-	"Projects",
-	NULL
-};
-
-
-
-
-const char *metadata_types[] = {
-	"index",
-	"string",
-	"numeric",
-	"date",
-	"blob"
-};
-
-
-ServiceType
-tracker_class_name_to_type (const char *service)
-{
-	const char **st;
-	int i = 0;
-
-	for (st=tracker_class_types; *st; st++) {
-
-		if (g_ascii_strcasecmp (service, *st) == 0) {
-			return i;
-		}
-
-		i++;
-	}
-
-	return SERVICE_OTHER_FILES;
-}
-
-
-char *
-tracker_type_to_service_name (ServiceType s)
-{
-	return g_strdup (tracker_class_types[s]);
-}
-
-
-
-static void
-tracker_array_reply (DBusGProxy *proxy, char **OUT_result, GError *error, gpointer user_data)
-{
-
-	ArrayCallBackStruct *callback_struct;
-
-	callback_struct = user_data;
-
-	(*(TrackerArrayReply) callback_struct->callback ) (OUT_result, error, callback_struct->data);
-
-	g_free (callback_struct);
-}
-
-
-static void
-tracker_hashtable_reply (DBusGProxy *proxy,  GHashTable *OUT_result, GError *error, gpointer user_data)
-{
-
-	HashTableCallBackStruct *callback_struct;
-
-	callback_struct = user_data;
-
-	(*(TrackerHashTableReply) callback_struct->callback ) (OUT_result, error, callback_struct->data);
-
-	g_free (callback_struct);
-}
-
 static void
 tracker_GPtrArray_reply (DBusGProxy *proxy,  GPtrArray *OUT_result, GError *error, gpointer user_data)
 {
@@ -265,7 +160,7 @@ tracker_connect (gboolean enable_warnings)
 	}
 
 	proxy = dbus_g_proxy_new_for_name (connection,
-			TRACKER_CLASS,
+			TRACKER_SERVICE,
 			TRACKER_OBJECT,
 			TRACKER_INTERFACE);
 
@@ -281,12 +176,20 @@ tracker_connect (gboolean enable_warnings)
 	client->proxy = proxy;
 
 	proxy = dbus_g_proxy_new_for_name (connection,
-			TRACKER_CLASS,
+			TRACKER_SERVICE,
 			TRACKER_OBJECT "/Search",
 			TRACKER_INTERFACE_SEARCH);
 
 	client->proxy_search = proxy;
 
+	proxy = dbus_g_proxy_new_for_name (connection,
+			TRACKER_SERVICE,
+			TRACKER_OBJECT "/Resources",
+			TRACKER_INTERFACE_RESOURCES);
+
+	client->proxy_resources = proxy;
+
+
 
 	return client;
 
@@ -297,8 +200,10 @@ tracker_disconnect (TrackerClient *client)
 {
 	g_object_unref (client->proxy);
 	g_object_unref (client->proxy_search);
+	g_object_unref (client->proxy_resources);
 	client->proxy = NULL;
 	client->proxy_search = NULL;
+	client->proxy_resources = NULL;
 
 	g_free (client);
 }
@@ -377,13 +282,19 @@ tracker_prompt_index_signals (TrackerClient *client, GError **error)
 }
 
 
+void
+tracker_resources_load (TrackerClient *client, const char *uri, GError **error)
+{
+	org_freedesktop_Tracker_Resources_load (client->proxy_resources, uri, &*error);
+}
+
+
 char *
-tracker_search_get_snippet (TrackerClient *client, ServiceType service, const char *uri, const char *search_text, GError **error)
+tracker_search_get_snippet (TrackerClient *client, const char *uri, const char *search_text, GError **error)
 {
 	char *result;
-	const char *service_str = tracker_class_types[service];
 
-	if (!org_freedesktop_Tracker_Search_get_snippet (client->proxy_search, service_str, uri, search_text, &result, &*error)) {
+	if (!org_freedesktop_Tracker_Search_get_snippet (client->proxy_search, uri, search_text, &result, &*error)) {
 		return NULL;
 	}
 
@@ -500,18 +411,29 @@ tracker_prompt_index_signals_async (TrackerClient *client, TrackerVoidReply call
 
 
 void
-tracker_search_get_snippet_async (TrackerClient *client, ServiceType service, const char *uri, const char *search_text, TrackerStringReply callback, gpointer user_data)
+tracker_resources_load_async (TrackerClient *client, const char *uri, TrackerVoidReply callback, gpointer user_data)
+{
+	VoidCallBackStruct *callback_struct;
+
+	callback_struct = g_new (VoidCallBackStruct, 1);
+	callback_struct->callback = callback;
+	callback_struct->data = user_data;
+
+	client->last_pending_call = org_freedesktop_Tracker_Resources_load_async (client->proxy_resources, uri, tracker_void_reply, callback_struct);
+
+}
+
+
+void
+tracker_search_get_snippet_async (TrackerClient *client, const char *uri, const char *search_text, TrackerStringReply callback, gpointer user_data)
 {
 	StringCallBackStruct *callback_struct;
-	const char *service_str;
 
 	callback_struct = g_new (StringCallBackStruct, 1);
 	callback_struct->callback = callback;
 	callback_struct->data = user_data;
 
-	service_str = tracker_class_types[service];
-
-	client->last_pending_call = org_freedesktop_Tracker_Search_get_snippet_async (client->proxy_search, service_str, uri, search_text, tracker_string_reply, callback_struct);
+	client->last_pending_call = org_freedesktop_Tracker_Search_get_snippet_async (client->proxy_search, uri, search_text, tracker_string_reply, callback_struct);
 
 }
 
diff --git a/src/libtracker/tracker.h b/src/libtracker/tracker.h
index 2ed71cd..56934b3 100644
--- a/src/libtracker/tracker.h
+++ b/src/libtracker/tracker.h
@@ -25,7 +25,6 @@
 G_BEGIN_DECLS
 
 typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data);
-typedef void (*TrackerHashTableReply) (GHashTable *result, GError *error, gpointer user_data);
 typedef void (*TrackerGPtrArrayReply) (GPtrArray *result, GError *error, gpointer user_data);
 typedef void (*TrackerBooleanReply) (gboolean result, GError *error, gpointer user_data);
 typedef void (*TrackerStringReply) (char *result, GError *error, gpointer user_data);
@@ -34,48 +33,6 @@ typedef void (*TrackerVoidReply) (GError *error, gpointer user_data);
 
 
 
-typedef enum {
-	METADATA_STRING_INDEXABLE,
-	METADATA_STRING,
-	METADATA_NUMERIC,
-	METADATA_DATE
-} MetadataTypes;
-
-typedef enum {
-	SERVICE_FILES,
-	SERVICE_FOLDERS,
-	SERVICE_DOCUMENTS,
-	SERVICE_IMAGES,
-	SERVICE_MUSIC,
-	SERVICE_VIDEOS,
-	SERVICE_TEXT_FILES,
-	SERVICE_DEVELOPMENT_FILES,
-	SERVICE_OTHER_FILES,
-	SERVICE_VFS_FILES,
-	SERVICE_VFS_FOLDERS,
-	SERVICE_VFS_DOCUMENTS,
-	SERVICE_VFS_IMAGES,
-	SERVICE_VFS_MUSIC,
-	SERVICE_VFS_VIDEOS,
-	SERVICE_VFS_TEXT_FILES,
-	SERVICE_VFS_DEVELOPMENT_FILES,
-	SERVICE_VFS_OTHER_FILES,
-	SERVICE_CONVERSATIONS,
-	SERVICE_PLAYLISTS,
-	SERVICE_APPLICATIONS,
-	SERVICE_CONTACTS,
-	SERVICE_EMAILS,
-	SERVICE_EMAILATTACHMENTS,
-	SERVICE_APPOINTMENTS,
-	SERVICE_TASKS,
-	SERVICE_BOOKMARKS,
-	SERVICE_WEBHISTORY,
-	SERVICE_PROJECTS
-} ServiceType;
-
-
-
-
 typedef struct {
 	char *		type;
 	gboolean	is_embedded;
@@ -86,7 +43,9 @@ typedef struct {
 
 typedef struct {
 	DBusGProxy	*proxy;
+	DBusGProxy	*proxy_metadata;
 	DBusGProxy	*proxy_search;
+	DBusGProxy	*proxy_resources;
 	DBusGProxyCall	*last_pending_call;
 } TrackerClient;
 
@@ -98,10 +57,6 @@ TrackerClient * tracker_connect (gboolean enable_warnings);
 void		tracker_disconnect (TrackerClient *client);
 
 
-ServiceType	tracker_class_name_to_type (const char *service);
-char *		tracker_type_to_service_name (ServiceType s);
-
-
 
 /* synchronous calls */
 
@@ -114,11 +69,16 @@ void		tracker_set_int_option				(TrackerClient *client, const char *option, int
 void		tracker_shutdown				(TrackerClient *client, gboolean reindex, GError **error);
 void		tracker_prompt_index_signals			(TrackerClient *client, GError **error);
 
-char *		tracker_search_get_snippet			(TrackerClient *client, ServiceType service, const char *uri, const char *search_text, GError **error);
+void		tracker_resources_load				(TrackerClient *client, const char *uri, GError **error);
+
+
+char *		tracker_search_get_snippet			(TrackerClient *client, const char *uri, const char *search_text, GError **error);
 gchar *		tracker_search_suggest				(TrackerClient *client, const char *search_text, int maxdist, GError **error);
 
+
 /* asynchronous calls */
 
+
 void		tracker_get_version_async				(TrackerClient *client,  TrackerIntReply callback, gpointer user_data);
 void		tracker_get_status_async				(TrackerClient *client,  TrackerStringReply callback, gpointer user_data);
 void		tracker_get_stats_async					(TrackerClient *client,  TrackerGPtrArrayReply callback, gpointer user_data);
@@ -128,9 +88,12 @@ void		tracker_set_int_option_async				(TrackerClient *client, const char *option
 void		tracker_shutdown_async					(TrackerClient *client, gboolean reindex, TrackerVoidReply callback, gpointer user_data);
 void		tracker_prompt_index_signals_async			(TrackerClient *client, TrackerVoidReply callback, gpointer user_data);
 
-void		tracker_search_get_snippet_async			(TrackerClient *client, ServiceType service, const char *uri, const char *search_text, TrackerStringReply callback, gpointer user_data);
+void		tracker_resources_load_async				(TrackerClient *client, const char *uri, TrackerVoidReply callback, gpointer user_data);
+
+void		tracker_search_get_snippet_async			(TrackerClient *client, const char *uri, const char *search_text, TrackerStringReply callback, gpointer user_data);
 void		tracker_search_suggest_async				(TrackerClient *client, const char *search_text, int maxdist, TrackerStringReply callback, gpointer user_data);
 
+
 G_END_DECLS
 
 #endif /* TRACKER_H */
diff --git a/src/plugins/evolution/tracker-evolution-indexer.c b/src/plugins/evolution/tracker-evolution-indexer.c
index f3140f9..c98bc5f 100644
--- a/src/plugins/evolution/tracker-evolution-indexer.c
+++ b/src/plugins/evolution/tracker-evolution-indexer.c
@@ -35,14 +35,11 @@
 
 #include <gmime/gmime.h>
 
+#include <libtracker-common/tracker-ontology.h>
+
 #include <libtracker-data/tracker-data-update.h>
 #include <libtracker-data/tracker-data-manager.h>
 
-/* This is okay, we run in-process of the indexer: we can access its symbols */
-#include <tracker-indexer/tracker-module.h>
-#include <tracker-indexer/tracker-push.h>
-#include <tracker-indexer/tracker-module-metadata-private.h>
-
 #include "tracker-evolution-indexer.h"
 
 /* These defines/renames are necessary for -glue.h */
@@ -57,14 +54,29 @@
 
 /* Based on data/services/email.metadata */
 
-#define METADATA_EMAIL_RECIPIENT     "Email:Recipient"
-#define METADATA_EMAIL_DATE	     "Email:Date"
-#define METADATA_EMAIL_SENDER	     "Email:Sender"
-#define METADATA_EMAIL_SUBJECT	     "Email:Subject"
-#define METADATA_EMAIL_SENT_TO	     "Email:SentTo"
-#define METADATA_EMAIL_CC	     "Email:CC"
-#define METADATA_EMAIL_TEXT	     "Email:Body"
-#define METADATA_EMAIL_TAG	     "User:Keywords"
+#define METADATA_EMAIL			       TRACKER_NMO_PREFIX "Email"
+#define METADATA_MAILBOXDATA_OBJECT	       TRACKER_NMO_PREFIX "MailboxDataObject"
+
+#define METADATA_EMAIL_RECIPIENT	       TRACKER_NMO_PREFIX "to"
+#define METADATA_EMAIL_DATE		       TRACKER_NMO_PREFIX "receivedDate"
+#define METADATA_EMAIL_SENDER		       TRACKER_NMO_PREFIX "sender"
+#define METADATA_EMAIL_SUBJECT		       TRACKER_NMO_PREFIX "subject"
+#define METADATA_EMAIL_SENT_TO		       TRACKER_NMO_PREFIX "recipient"
+#define METADATA_EMAIL_CC		       TRACKER_NMO_PREFIX "cc"
+#if 0
+#define METADATA_EMAIL_TEXT		       TRACKER_NMO_PREFIX "Body" 
+#endif
+
+#define NIE_DATASOURCE 			       TRACKER_NIE_PREFIX "DataSource"
+#define NIE_DATASOURCE_P 		       TRACKER_NIE_PREFIX "dataSource"
+
+#define RDF_TYPE 			       TRACKER_RDF_PREFIX "type"
+
+#define METADATA_EMAIL_MESSAGE_HEADER	       TRACKER_NMO_PREFIX "messageHeader"
+#define METADATA_EMAIL_MESSAGE_HEADER_NAME     TRACKER_NMO_PREFIX "headerName"
+#define METADATA_EMAIL_MESSAGE_HEADER_VALUE    TRACKER_NMO_PREFIX "headerValue"
+
+#define DATASOURCE_URN			       "urn:nepomuk:datasource:1cb1eb90-1241-11de-8c30-0800200c9a66"
 
 G_DEFINE_TYPE (TrackerEvolutionIndexer, tracker_evolution_indexer, G_TYPE_OBJECT)
 
@@ -181,22 +193,14 @@ extract_mime_parts (GMimeObject *object,
 		subject = g_strdup_printf ("%s/%s", message_subject, 
 					   filename);
 
-		metadata = tracker_module_metadata_new ();
-
-		tracker_module_metadata_add_string (metadata, 
-						    "File:Path", 
-						    subject);
+		tracker_data_insert_statement (subject, 
+					       "File:Path", 
+					       filename);
 
-		tracker_module_metadata_add_string (metadata, 
-						    "File:Name", 
-						    filename);
+		tracker_data_insert_statement (subject, 
+					       "File:Name", 
+					       filename);
 
-		data = tracker_module_metadata_get_hash_table (metadata);
-
-		tracker_data_update_replace_service (subject, "EvolutionEmails", data);
-
-		g_hash_table_destroy (data);
-		g_object_unref (metadata);
 		g_free (subject);
 	}
 }
@@ -248,10 +252,20 @@ perform_set (TrackerEvolutionIndexer *object,
 	     const GStrv values)
 {
 	guint i = 0;
-	TrackerModuleMetadata *metadata;
-	GHashTable *data;
 
-	metadata = tracker_module_metadata_new ();
+	if (!tracker_data_query_resource_exists (DATASOURCE_URN, NULL, NULL)) {
+		tracker_data_insert_statement (DATASOURCE_URN, RDF_TYPE,
+					       NIE_DATASOURCE);
+	}
+
+	tracker_data_insert_statement (subject, RDF_TYPE,
+		                       METADATA_EMAIL);
+
+	tracker_data_insert_statement (subject, RDF_TYPE,
+		                       METADATA_MAILBOXDATA_OBJECT);
+
+	tracker_data_insert_statement (subject, NIE_DATASOURCE_P,
+		                       DATASOURCE_URN);
 
 	while (predicates [i] != NULL && values[i] != NULL) {
 
@@ -337,9 +351,9 @@ perform_set (TrackerEvolutionIndexer *object,
 				} else
 					text = orig_text;
 
-				tracker_module_metadata_add_string (metadata, 
-								    METADATA_EMAIL_TEXT, 
-								    text);
+				tracker_data_insert_statement (subject, 
+							       METADATA_EMAIL_TEXT, 
+							       text);
 
 				g_free (text);
 				g_free (encoding);
@@ -357,7 +371,7 @@ perform_set (TrackerEvolutionIndexer *object,
 			if (!values[i] || strlen (values[i]) < 1)
 				goto cont;
 
-			key = g_strdup (values[i]);
+			key = g_strdup_printf ("X-Evolution-UserTag-%s", (values[i]));
 
 			value = strchr (key, '=');
 
@@ -366,45 +380,52 @@ perform_set (TrackerEvolutionIndexer *object,
 				value++;
 			}
 
-			/* TODO: what about value? The format of Evolution is
-			 * key=value, so we can store a value too here. Is this 
-			 * something Nepomuk can someday save us with? */
+			tracker_data_insert_statement (":1", RDF_TYPE,
+			                               METADATA_EMAIL_MESSAGE_HEADER);
+
+			tracker_data_insert_statement (":1", 
+			                               METADATA_EMAIL_MESSAGE_HEADER_NAME,
+			                               key);
 
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_TAG, 
-							    key);
+			tracker_data_insert_statement (":1", 
+			                               METADATA_EMAIL_MESSAGE_HEADER_VALUE,
+			                               value);
+
+			tracker_data_insert_statement (subject, 
+			                               METADATA_EMAIL_MESSAGE_HEADER, 
+			                                ":1");
 
 			g_free (key);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_SUBJECT) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_SUBJECT, 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_EMAIL_SUBJECT, 
+						       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_SENT) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_DATE, 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_EMAIL_DATE, 
+						       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_FROM) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_SENDER, 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_EMAIL_SENDER, 
+						       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_TO) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_SENT_TO, 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_EMAIL_SENT_TO, 
+						       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_CC) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_CC, 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_EMAIL_CC, 
+						       values[i]);
 		}
 
 		cont:
@@ -412,25 +433,26 @@ perform_set (TrackerEvolutionIndexer *object,
 		i++;
 	}
 
-	data = tracker_module_metadata_get_hash_table (metadata);
-
-	tracker_data_update_replace_service (subject, "EvolutionEmails", data);
-
-	g_hash_table_destroy (data);
-	g_object_unref (metadata);
 }
 
 static void 
 perform_unset (TrackerEvolutionIndexer *object, 
 	       const gchar *subject)
 {
-	tracker_data_update_delete_service_by_path (subject, "EvolutionEmails"); 
+	tracker_data_delete_resource (subject); 
 }
 
 static void
 perform_cleanup (TrackerEvolutionIndexer *object)
 {
-	tracker_data_update_delete_service_all ("EvolutionEmails");
+	GError *error = NULL;
+
+	tracker_data_update_sparql ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", &error);
+
+	if (error) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
 }
 
 static void
diff --git a/src/plugins/kmail/tracker-kmail-indexer.c b/src/plugins/kmail/tracker-kmail-indexer.c
index 9f5ba99..fd21357 100644
--- a/src/plugins/kmail/tracker-kmail-indexer.c
+++ b/src/plugins/kmail/tracker-kmail-indexer.c
@@ -20,7 +20,7 @@
  * Authors:
  *  Philip Van Hoof <philip codeminded be>
  */
-
+ 
 #include "config.h"
 
 #include <string.h>
@@ -35,6 +35,8 @@
 
 #include <gmime/gmime.h>
 
+#include <libtracker-common/tracker-ontology.h>
+
 #include <libtracker-data/tracker-data-update.h>
 #include <libtracker-data/tracker-data-manager.h>
 
@@ -57,14 +59,34 @@
 
 /* Based on data/services/email.metadata */
 
-#define METADATA_EMAIL_RECIPIENT     "Email:Recipient"
-#define METADATA_EMAIL_DATE	     "Email:Date"
-#define METADATA_EMAIL_SENDER	     "Email:Sender"
-#define METADATA_EMAIL_SUBJECT	     "Email:Subject"
-#define METADATA_EMAIL_SENT_TO	     "Email:SentTo"
-#define METADATA_EMAIL_CC	     "Email:CC"
-#define METADATA_EMAIL_TEXT	     "Email:Body"
-#define METADATA_EMAIL_TAG	     "User:Keywords"
+
+#define METADATA_EMAIL			       TRACKER_NMO_PREFIX "Email"
+#define METADATA_MAILBOXDATA_OBJECT	       TRACKER_NMO_PREFIX "MailboxDataObject"
+
+#define METADATA_EMAIL_RECIPIENT	       TRACKER_NMO_PREFIX "to"
+#define METADATA_EMAIL_DATE		       TRACKER_NMO_PREFIX "receivedDate"
+#define METADATA_EMAIL_SENDER		       TRACKER_NMO_PREFIX "sender"
+#define METADATA_EMAIL_SUBJECT		       TRACKER_NMO_PREFIX "subject"
+#define METADATA_EMAIL_SENT_TO		       TRACKER_NMO_PREFIX "recipient"
+#define METADATA_EMAIL_CC		       TRACKER_NMO_PREFIX "cc"
+#if 0
+#define METADATA_EMAIL_TEXT		       TRACKER_NMO_PREFIX "Body" 
+#endif
+
+#define NIE_DATASOURCE 			       TRACKER_NIE_PREFIX "DataSource"
+#define NIE_DATASOURCE_P 		       TRACKER_NIE_PREFIX "dataSource"
+
+#define RDF_TYPE			       TRACKER_RDF_PREFIX "type"
+
+#define METADATA_EMAIL_MESSAGE_HEADER	       TRACKER_NMO_PREFIX "messageHeader"
+#define METADATA_EMAIL_MESSAGE_HEADER_NAME     TRACKER_NMO_PREFIX "headerName"
+#define METADATA_EMAIL_MESSAGE_HEADER_VALUE    TRACKER_NMO_PREFIX "headerValue"
+
+#define NAO_TAG				       TRACKER_NAO_PREFIX "Tag"
+#define NAO_HASTAG			       TRACKER_NAO_PREFIX "hasTag"
+#define NAO_PREFLABEL			       TRACKER_NAO_PREFIX "prefLabel"
+
+#define DATASOURCE_URN			       "urn:nepomuk:datasource:4a157cf0-1241-11de-8c30-0800200c9a66"
 
 G_DEFINE_TYPE (TrackerKMailIndexer, tracker_kmail_indexer, G_TYPE_OBJECT)
 
@@ -132,10 +154,20 @@ perform_set (TrackerKMailIndexer *object,
 	     const GStrv values)
 {
 	guint i = 0;
-	TrackerModuleMetadata *metadata;
-	GHashTable *data;
 
-	metadata = tracker_module_metadata_new ();
+	if (!tracker_data_query_resource_exists (DATASOURCE_URN, NULL, NULL)) {
+		tracker_data_insert_statement (DATASOURCE_URN, RDF_TYPE,
+					       NIE_DATASOURCE);
+	}
+
+	tracker_data_insert_statement (subject, RDF_TYPE,
+		                       METADATA_EMAIL);
+
+	tracker_data_insert_statement (subject, RDF_TYPE,
+		                       METADATA_MAILBOXDATA_OBJECT);
+
+	tracker_data_insert_statement (subject, NIE_DATASOURCE_P,
+		                       DATASOURCE_URN);
 
 	while (predicates [i] != NULL && values[i] != NULL) {
 
@@ -151,63 +183,72 @@ perform_set (TrackerKMailIndexer *object,
 		 * improve this situation. */
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_TAG) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_TAG, 
-							    values[i]);
+
+			tracker_data_insert_statement (":1", RDF_TYPE,
+			                               NAO_TAG);
+
+			tracker_data_insert_statement (":1", 
+			                               NAO_PREFLABEL,
+			                               values[i]);
+
+			tracker_data_insert_statement (subject, 
+			                               NAO_HASTAG, 
+			                                ":1");
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_SUBJECT) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_SUBJECT, 
-							    values[i]);
+			tracker_data_insert_statement (subject, 
+						       METADATA_EMAIL_SUBJECT, 
+						       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_SENT) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_DATE, 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_EMAIL_DATE, 
+						       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_FROM) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_SENDER, 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_EMAIL_SENDER, 
+						       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_TO) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_SENT_TO, 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_EMAIL_SENT_TO, 
+						       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_CC) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    METADATA_EMAIL_CC, 
-							    values[i]);
+			tracker_data_insert_statement (subject, 
+						       METADATA_EMAIL_CC, 
+						       values[i]);
 		}
 
 		i++;
 	}
 
-	data = tracker_module_metadata_get_hash_table (metadata);
-
-	tracker_data_update_replace_service (subject, "KMailEmails", data);
-
-	g_hash_table_destroy (data);
-	g_object_unref (metadata);
 }
 
 static void 
 perform_unset (TrackerKMailIndexer *object, 
 	       const gchar *subject)
 {
-	tracker_data_update_delete_service_by_path (subject, "KMailEmails"); 
+	tracker_data_delete_resource (subject); 
 }
 
 static void
 perform_cleanup (TrackerKMailIndexer *object)
 {
-	tracker_data_update_delete_service_all ("KMailEmails");
+	GError *error = NULL;
+
+	tracker_data_update_sparql ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", &error);
+
+	if (error) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
 }
 
 static void
diff --git a/src/plugins/rss/tracker-rss-indexer.c b/src/plugins/rss/tracker-rss-indexer.c
index 92835eb..1578f29 100644
--- a/src/plugins/rss/tracker-rss-indexer.c
+++ b/src/plugins/rss/tracker-rss-indexer.c
@@ -20,7 +20,7 @@
  * Authors:
  *  Philip Van Hoof <philip codeminded be>
  */
-
+ 
 #include "config.h"
 
 #include <string.h>
@@ -35,6 +35,8 @@
 
 #include <gmime/gmime.h>
 
+#include <libtracker-common/tracker-ontology.h>
+
 #include <libtracker-data/tracker-data-update.h>
 #include <libtracker-data/tracker-data-manager.h>
 
@@ -55,7 +57,23 @@
 
 #include "tracker-rss-registrar-glue.h"
 
-/* Based on data/services/email.metadata */
+/* This is of course TODO (and to move to libtracker-common/tracker-ontology.h): */
+#define TRACKER_RSS_PREFIX		       "http://www.tracker-project.org/temp/rss#";
+
+#define METADATA_RSS			       TRACKER_RSS_PREFIX "RSS"
+#define METADATA_RSSDATA_OBJECT		       TRACKER_RSS_PREFIX "RSSDataObject"
+
+#define METADATA_RSS_SOMETHING		       TRACKER_RSS_PREFIX "something"
+
+#define NIE_DATASOURCE 			       TRACKER_NIE_PREFIX "DataSource"
+#define NIE_DATASOURCE_P 		       TRACKER_NIE_PREFIX "dataSource"
+
+#define RDF_TYPE			       TRACKER_RDF_PREFIX "type"
+
+#define NAO_TAG				       TRACKER_NAO_PREFIX "Tag"
+#define NAO_PREFLABEL			       TRACKER_NAO_PREFIX "prefLabel"
+
+#define DATASOURCE_URN			       "urn:nepomuk:datasource:670e2cd0-1241-11de-8c30-0800200c9a66"
 
 G_DEFINE_TYPE (TrackerRssIndexer, tracker_rss_indexer, G_TYPE_OBJECT)
 
@@ -122,44 +140,60 @@ perform_set (TrackerRssIndexer *object,
 	     const GStrv values)
 {
 	guint i = 0;
-	TrackerModuleMetadata *metadata;
-	GHashTable *data;
 
-	metadata = tracker_module_metadata_new ();
+	/* TODO */
+	return;
+
+	if (!tracker_data_query_resource_exists (DATASOURCE_URN, NULL, NULL)) {
+		tracker_data_insert_statement (DATASOURCE_URN, RDF_TYPE,
+					       NIE_DATASOURCE);
+	}
+
+	tracker_data_insert_statement (subject, RDF_TYPE,
+		                       METADATA_RSS);
+
+	tracker_data_insert_statement (subject, RDF_TYPE,
+		                       METADATA_RSSDATA_OBJECT);
+
+	tracker_data_insert_statement (subject, NIE_DATASOURCE_P,
+		                       DATASOURCE_URN);
 
 	while (predicates [i] != NULL && values[i] != NULL) {
 
 		if (g_strcmp0 (predicates[i], TRACKER_RSS_PREDICATE_THING) == 0) {
-			tracker_module_metadata_add_string (metadata, 
-							    "Rss:Something", 
-							    values[i]);
+			tracker_data_insert_statement (subject,
+						       METADATA_RSS_SOMETHING, 
+						       values[i]);
 		}
 
 		i++;
 	}
-
-	data = tracker_module_metadata_get_hash_table (metadata);
-
-	// TODO: the service for RSS
-	tracker_data_update_replace_service (subject, "Rss", data);
-
-	g_hash_table_destroy (data);
-	g_object_unref (metadata);
 }
 
 static void 
 perform_unset (TrackerRssIndexer *object, 
 	       const gchar *subject)
 {
-	// TODO: the service for RSS
-	tracker_data_update_delete_service_by_path (subject, "Rss"); 
+	/* TODO */
+	return;
+
+	tracker_data_delete_resource (subject); 
 }
 
 static void
 perform_cleanup (TrackerRssIndexer *object)
 {
-	// TODO: the service for RSS
-	tracker_data_update_delete_service_all ("Rss");
+	GError *error = NULL;
+
+	/* TODO */
+	return;
+
+	tracker_data_update_sparql ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", &error);
+
+	if (error) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
 }
 
 static void
@@ -193,7 +227,7 @@ tracker_rss_indexer_set (TrackerRssIndexer *object,
 }
 
 void
-tracker_erssindexer_set_many (TrackerRssIndexer *object, 
+tracker_rss_indexer_set_many (TrackerRssIndexer *object, 
 			      const GStrv subjects, 
 			      const GPtrArray *predicates,
 			      const GPtrArray *values,
diff --git a/src/tracker-extract/Makefile.am b/src/tracker-extract/Makefile.am
index e3709bb..2919dc0 100644
--- a/src/tracker-extract/Makefile.am
+++ b/src/tracker-extract/Makefile.am
@@ -26,7 +26,7 @@ INCLUDES = 								\
 	$(POPPLER_GLIB_CFLAGS) 						\
 	$(GSTREAMER_CFLAGS) 						\
 	$(XINE_CFLAGS) 							\
-	$(TOTEM_PL_PARSER_CFLAGS)
+	$(TOTEM_PL_PARSER_CFLAGS)					
 
 modules_LTLIBRARIES = 							\
 	libextract-abw.la 						\
@@ -108,19 +108,17 @@ albumart_libs += 							\
 	$(GDKPIXBUF_LIBS) $(DBUS_LIBS) $(GCOV_LIBS)
 endif
 
-escape_sources = 							\
-	tracker-escape.c						\
-	tracker-escape.h
-
 # ABW
-libextract_abw_la_SOURCES = tracker-extract-abw.c $(escape_sources)
+libextract_abw_la_SOURCES = tracker-extract-abw.c
 libextract_abw_la_LDFLAGS = $(module_flags)
-libextract_abw_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS)
+libextract_abw_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # MP3
-libextract_mp3_la_SOURCES = tracker-extract-mp3.c $(albumart_sources) $(escape_sources)
+libextract_mp3_la_SOURCES = tracker-extract-mp3.c $(albumart_sources)
 libextract_mp3_la_LDFLAGS = $(module_flags) $(albumart_flags)
-libextract_mp3_la_LIBADD = $(albumart_libs) $(GLIB2_LIBS) $(GCOV_LIBS)
+libextract_mp3_la_LIBADD = $(albumart_libs) $(GLIB2_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # Vorbis (OGG)
 libextract_vorbis_la_SOURCES = tracker-extract-vorbis.c $(escape_sources)
@@ -128,22 +126,25 @@ libextract_vorbis_la_LDFLAGS = $(module_flags)
 libextract_vorbis_la_LIBADD = $(GLIB2_LIBS) $(LIBVORBIS_LIBS) $(GCOV_LIBS)
 
 # MPlayer
-libextract_mplayer_la_SOURCES = tracker-extract-mplayer.c $(escape_sources)
+libextract_mplayer_la_SOURCES = tracker-extract-mplayer.c
 libextract_mplayer_la_LDFLAGS = $(module_flags)
-libextract_mplayer_la_LIBADD = $(GLIB2_LIBS)
+libextract_mplayer_la_LIBADD = $(GLIB2_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # Oasis
-libextract_oasis_la_SOURCES = tracker-extract-oasis.c $(escape_sources)
+libextract_oasis_la_SOURCES = tracker-extract-oasis.c
 libextract_oasis_la_LDFLAGS = $(module_flags)
-libextract_oasis_la_LIBADD = $(GLIB2_LIBS)  $(GCOV_LIBS)
+libextract_oasis_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # PNG
-libextract_png_la_SOURCES = tracker-extract-png.c $(xmp_sources) $(escape_sources)
+libextract_png_la_SOURCES = tracker-extract-png.c $(xmp_sources)
 libextract_png_la_LDFLAGS = $(module_flags)
-libextract_png_la_LIBADD = $(GLIB2_LIBS) $(LIBPNG_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS)
+libextract_png_la_LIBADD = $(GLIB2_LIBS) $(LIBPNG_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # PS
-libextract_ps_la_SOURCES = tracker-extract-ps.c $(escape_sources)
+libextract_ps_la_SOURCES = tracker-extract-ps.c
 libextract_ps_la_LDFLAGS = $(module_flags)
 libextract_ps_la_LIBADD = 						\
 	$(top_builddir)/src/libtracker-common/libtracker-common.la	\
@@ -151,59 +152,70 @@ libextract_ps_la_LIBADD = 						\
 	$(GCOV_LIBS)
 
 # Totem
-libextract_totem_la_SOURCES = tracker-extract-totem.c $(escape_sources)
+libextract_totem_la_SOURCES = tracker-extract-totem.c
 libextract_totem_la_LDFLAGS = $(module_flags)
-libextract_totem_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS)
+libextract_totem_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # XMP
-libextract_xmp_la_SOURCES = tracker-extract-xmp.c $(xmp_sources) $(escape_sources)
+libextract_xmp_la_SOURCES = tracker-extract-xmp.c $(xmp_sources)
 libextract_xmp_la_LDFLAGS = $(module_flags)
-libextract_xmp_la_LIBADD = $(GLIB2_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS)
+libextract_xmp_la_LIBADD = $(GLIB2_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # HTML
-libextract_html_la_SOURCES = tracker-extract-html.c $(escape_sources)
+libextract_html_la_SOURCES = tracker-extract-html.c
 libextract_html_la_LDFLAGS = $(module_flags)
-libextract_html_la_LIBADD = $(GLIB2_LIBS) $(LIBXML2_LIBS) $(GCOV_LIBS)
+libextract_html_la_LIBADD = $(GLIB2_LIBS) $(LIBXML2_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # MS Office
-libextract_msoffice_la_SOURCES = tracker-extract-msoffice.c $(escape_sources)
+libextract_msoffice_la_SOURCES = tracker-extract-msoffice.c
 libextract_msoffice_la_LDFLAGS = $(module_flags)
-libextract_msoffice_la_LIBADD = $(GLIB2_LIBS) $(LIBGSF_LIBS) $(GCOV_LIBS)
+libextract_msoffice_la_LIBADD = $(GLIB2_LIBS) $(LIBGSF_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # PDF
-libextract_pdf_la_SOURCES = tracker-extract-pdf.c $(xmp_sources) $(escape_sources)
+libextract_pdf_la_SOURCES = tracker-extract-pdf.c $(xmp_sources)
 libextract_pdf_la_LDFLAGS = $(module_flags)
-libextract_pdf_la_LIBADD = $(GLIB2_LIBS) $(POPPLER_GLIB_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS)
+libextract_pdf_la_LIBADD = $(GLIB2_LIBS) $(POPPLER_GLIB_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # GStreamer
-libextract_gstreamer_la_SOURCES = tracker-extract-gstreamer.c $(albumart_sources) $(escape_sources)
+libextract_gstreamer_la_SOURCES = tracker-extract-gstreamer.c $(albumart_sources)
 libextract_gstreamer_la_LDFLAGS = $(module_flags) $(albumart_flags)
-libextract_gstreamer_la_LIBADD = $(albumart_libs) $(GSTREAMER_LIBS) $(GLIB2_LIBS) $(GCOV_LIBS)
+libextract_gstreamer_la_LIBADD = $(albumart_libs) $(GSTREAMER_LIBS) $(GLIB2_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # GStreamer helix
-libextract_gstreamer_helix_la_SOURCES = tracker-extract-gstreamer-helix.c $(albumart_sources) $(escape_sources)
+libextract_gstreamer_helix_la_SOURCES = tracker-extract-gstreamer-helix.c $(albumart_sources)
 libextract_gstreamer_helix_la_LDFLAGS = $(module_flags) $(albumart_flags)
-libextract_gstreamer_helix_la_LIBADD = $(albumart_libs) $(GSTREAMER_LIBS) $(GLIB2_LIBS) $(GCOV_LIBS)
+libextract_gstreamer_helix_la_LIBADD = $(albumart_libs) $(GSTREAMER_LIBS) $(GLIB2_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # Xine
-libextract_xine_la_SOURCES = tracker-extract-libxine.c $(escape_sources)
+libextract_xine_la_SOURCES = tracker-extract-libxine.c
 libextract_xine_la_LDFLAGS = $(module_flags)
-libextract_xine_la_LIBADD = $(GLIB2_LIBS) $(XINE_LIBS) $(GCOV_LIBS)
+libextract_xine_la_LIBADD = $(GLIB2_LIBS) $(XINE_LIBS) $(GCOV_LIBS) \
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # JPEG
-libextract_jpeg_la_SOURCES = tracker-extract-jpeg.c $(xmp_sources) $(iptc_sources) $(escape_sources)
+libextract_jpeg_la_SOURCES = tracker-extract-jpeg.c $(xmp_sources) $(iptc_sources)
 libextract_jpeg_la_LDFLAGS = $(module_flags)
 libextract_jpeg_la_LIBADD = $(GLIB2_LIBS) $(LIBJPEG_LIBS) $(LIBEXIF_LIBS) $(LIBIPTCDATA_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS)
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # TIFF
-libextract_tiff_la_SOURCES = tracker-extract-tiff.c $(xmp_sources) $(iptc_sources) $(escape_sources)
+libextract_tiff_la_SOURCES = tracker-extract-tiff.c $(xmp_sources) $(iptc_sources)
 libextract_tiff_la_LDFLAGS = $(module_flags)
 libextract_tiff_la_LIBADD = $(GLIB2_LIBS) $(LIBTIFF_LIBS) $(LIBIPTCDATA_LIBS) $(EXEMPI_LIBS) $(GCOV_LIBS)
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 # Playlists using totem-pl-parser
-libextract_playlist_la_SOURCES = tracker-extract-playlist.c  $(escape_sources)
+libextract_playlist_la_SOURCES = tracker-extract-playlist.c
 libextract_playlist_la_LDFLAGS = $(module_flags)
 libextract_playlist_la_LIBADD = $(GLIB2_LIBS) $(TOTEM_PL_PARSER_LIBS) $(GCOV_LIBS)
+	$(top_builddir)/src/libtracker-common/libtracker-common.la
 
 #
 # Binaries
@@ -216,7 +228,8 @@ tracker_extract_SOURCES = 						\
 	tracker-extract.c						\
 	tracker-extract.h						\
 	tracker-main.c							\
-	tracker-main.h
+	tracker-main.h							
+
 
 tracker_extract_LDADD = 						\
 	$(top_builddir)/src/libtracker-common/libtracker-common.la	\
diff --git a/src/tracker-extract/tracker-escape.c b/src/tracker-extract/tracker-escape.c
deleted file mode 100644
index 071bd63..0000000
--- a/src/tracker-extract/tracker-escape.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2008, Nokia
- *
- * This program 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 program 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 program; 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 "tracker-escape.h"
-
-#ifdef SHOULD_VALIDATE_UTF8
-
-gchar *
-tracker_escape_metadata (const gchar *str)
-{
-	const gchar *end;
-
-	if (!str) {
-		return NULL;
-	}
-
-	if (g_utf8_validate (str, -1, &end)) {
-		return g_strstrip (g_strdup (str));
-	}
-
-	return g_strstrip (g_strndup (str, end - str));
-}
-
-gchar *
-tracker_escape_metadata_printf (const gchar *format,
-				...)
-{
- 	va_list args;
- 	gchar *str, *escaped;
- 	
- 	va_start (args, format);
- 	str = g_strdup_vprintf (format, args);
- 	va_end (args);
- 	
- 	escaped = tracker_escape_metadata (str);
- 	g_free (str);
- 	
- 	return escaped;
-}
-
-#endif /* SHOULD_VALIDATE_UTF8 */
diff --git a/src/tracker-extract/tracker-escape.h b/src/tracker-extract/tracker-escape.h
deleted file mode 100644
index 24b87c9..0000000
--- a/src/tracker-extract/tracker-escape.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2008, Nokia
- *
- * This program 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 program 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 program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#ifndef __TRACKER_ESCAPE_H__
-#define __TRACKER_ESCAPE_H__
-
-#include <glib.h>
-
-#define SHOULD_VALIDATE_UTF8
-
-G_BEGIN_DECLS
-
-#ifdef SHOULD_VALIDATE_UTF8
-
-gchar *tracker_escape_metadata        (const gchar *str);
-gchar *tracker_escape_metadata_printf (const gchar *format,
-				       ...);
-
-#else  /* SHOULD_VALIDATE_UTF8 */
-
-/* We used to escape strings before we used DBus */
-#define tracker_escape_metadata        g_strdup
-#define tracker_escape_metadata_printf g_strdup_printf
-
-#endif /* SHOULD_VALIDATE_UTF8 */
-
-G_END_DECLS
-
-#endif /* __TRACKER_ESCAPE_H__ */
diff --git a/src/tracker-extract/tracker-extract-abw.c b/src/tracker-extract/tracker-extract-abw.c
index d4f3267..b2e77e2 100644
--- a/src/tracker-extract/tracker-extract-abw.c
+++ b/src/tracker-extract/tracker-extract-abw.c
@@ -35,12 +35,21 @@
 #include <glib/gstdio.h>
 
 #include <libtracker-common/tracker-file-utils.h>
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
 
 #include "tracker-main.h"
-#include "tracker-escape.h"
 
-static void extract_abw (const gchar *filename,
-			 GHashTable  *metadata);
+
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+static void extract_abw (const gchar *uri,
+			 GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 	{ "application/x-abiword", extract_abw },
@@ -48,12 +57,15 @@ static TrackerExtractData data[] = {
 };
 
 static void
-extract_abw (const gchar *filename,
-	     GHashTable  *metadata)
+extract_abw (const gchar *uri,
+	     GPtrArray   *metadata)
 {
 	FILE *f;
+	gchar *filename;
 
+	filename = g_filename_from_uri (uri, NULL, NULL);
 	f = tracker_file_open (filename, "r", TRUE);
+	g_free (filename);
 
 	if (f) {
 		gchar  *line;
@@ -63,34 +75,46 @@ extract_abw (const gchar *filename,
 		line = NULL;
 		length = 0;
 
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "Document");
+
 		while ((read_char = getline (&line, &length, f)) != -1) {
 			if (g_str_has_suffix (line, "</m>\n")) {
 				line[read_char - 5] = '\0';
 			}
 			if (g_str_has_prefix (line, "<m key=\"dc.title\">")) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:Title"),
-						     tracker_escape_metadata (line + 18));
+				tracker_statement_list_insert (metadata, uri,
+							  NIE_PREFIX "title",
+							  line + 18);
 			}
 			else if (g_str_has_prefix (line, "<m key=\"dc.subject\">")) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:Subject"),
-						     tracker_escape_metadata (line + 20));
+				tracker_statement_list_insert (metadata, uri,
+							  NIE_PREFIX "subject",
+							  line + 20);
 			}
 			else if (g_str_has_prefix (line, "<m key=\"dc.creator\">")) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:Author"),
-						     tracker_escape_metadata (line + 20));
+				tracker_statement_list_insert (metadata, uri,
+							  NCO_PREFIX "creator",
+							  line + 20);
 			}
 			else if (g_str_has_prefix (line, "<m key=\"abiword.keywords\">")) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:Keywords"),
-						     tracker_escape_metadata (line + 26));
+				gchar *keywords = g_strdup (line + 26);
+				char *lasts, *keyw;
+
+				for (keyw = strtok_r (keywords, ",; ", &lasts); keyw; 
+				     keyw = strtok_r (NULL, ",; ", &lasts)) {
+					tracker_statement_list_insert (metadata,
+							  uri, NIE_PREFIX "keyword",
+							  (const gchar*) keyw);
+				}
+
+				g_free (keywords);
 			}
 			else if (g_str_has_prefix (line, "<m key=\"dc.description\">")) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:Comments"),
-						     tracker_escape_metadata (line + 24));
+				tracker_statement_list_insert (metadata, uri,
+							  NIE_PREFIX "comment",
+							  line + 24);
 			}
 
 			g_free (line);
diff --git a/src/tracker-extract/tracker-extract-gstreamer-helix.c b/src/tracker-extract/tracker-extract-gstreamer-helix.c
index a73770f..54fdd94 100644
--- a/src/tracker-extract/tracker-extract-gstreamer-helix.c
+++ b/src/tracker-extract/tracker-extract-gstreamer-helix.c
@@ -33,6 +33,8 @@
 #include <gst/gst.h>
 #include <gst/tag/tag.h>
 
+#include <libtracker-common/tracker-statement-list.h>
+
 #include "tracker-main.h"
 #include "tracker-extract-albumart.h"
 
@@ -68,8 +70,8 @@ typedef struct {
 
 } MetadataExtractor;
 
-static void extract_gstreamer_helix_audio (const gchar *uri, GHashTable *metadata);
-static void extract_gstreamer_helix_video (const gchar *uri, GHashTable *metadata);
+static void extract_gstreamer_helix_audio (const gchar *uri, GPtrArray *metadata);
+static void extract_gstreamer_helix_video (const gchar *uri, GPtrArray *metadata);
 
 static TrackerExtractData data[] = {
 	{ "audio/vnd.rn-realaudio", extract_gstreamer_helix_audio },
@@ -361,30 +363,28 @@ gst_bus_cb (GstBus	      *bus,
 	}
 }
 
+
 static void
-add_int64_info (GHashTable *metadata,
-		gchar	   *key,
+add_int64_info (GPtrArray *metadata,
+		const gchar *uri,
+		const gchar	   *key,
 		gint64	    info)
 {
-	gchar *str_info;
-
-	str_info = tracker_escape_metadata_printf ("%" G_GINT64_FORMAT, info);
-	g_hash_table_insert (metadata, key, str_info);
+	tracker_statement_list_insert_with_int64 (metadata, uri, key, info);
 }
 
 static void
-add_uint_info (GHashTable *metadata,
+add_uint_info (GPtrArray *metadata,
+		const gchar *uri,
 	       gchar	  *key,
 	       guint	   info)
 {
-	gchar *str_info;
-
-	str_info = tracker_escape_metadata_printf ("%d", info);
-	g_hash_table_insert (metadata, key, str_info);
+	tracker_statement_list_insert_with_int (metadata, uri, key, info);
 }
 
 static void
-add_string_gst_tag (GHashTable	*metadata,
+add_string_gst_tag (GPtrArray	*metadata,
+		const gchar *uri,
 		    const gchar *key,
 		    GstTagList	*tag_list,
 		    const gchar *tag)
@@ -397,9 +397,7 @@ add_string_gst_tag (GHashTable	*metadata,
 
 	if (s) {
 		if (ret && s[0] != '\0') {
-			g_hash_table_insert (metadata,
-					     g_strdup (key),
-					     tracker_escape_metadata (s));
+			tracker_statement_list_insert (metadata, uri, key, s);
 		}
 
 		g_free (s);
@@ -407,7 +405,8 @@ add_string_gst_tag (GHashTable	*metadata,
 }
 
 static void
-add_uint_gst_tag (GHashTable  *metadata,
+add_uint_gst_tag (GPtrArray  *metadata,
+		const gchar *uri,
 		  const gchar *key,
 		  GstTagList  *tag_list,
 		  const gchar *tag)
@@ -418,14 +417,13 @@ add_uint_gst_tag (GHashTable  *metadata,
 	ret = gst_tag_list_get_uint (tag_list, tag, &n);
 
 	if (ret) {
-		g_hash_table_insert (metadata,
-				     g_strdup (key),
-				     tracker_escape_metadata_printf ("%d", n));
+		tracker_statement_list_insert_with_int (metadata, uri, key, n);
 	}
 }
 
 static void
-add_double_gst_tag (GHashTable	*metadata,
+add_double_gst_tag (GPtrArray	*metadata,
+		const gchar *uri,
 		    const gchar *key,
 		    GstTagList	*tag_list,
 		    const gchar *tag)
@@ -436,14 +434,13 @@ add_double_gst_tag (GHashTable	*metadata,
 	ret = gst_tag_list_get_double (tag_list, tag, &n);
 
 	if (ret) {
-		g_hash_table_insert (metadata,
-				     g_strdup (key),
-				     tracker_escape_metadata_printf ("%f", n));
+		tracker_statement_list_insert_with_double (metadata, uri, key, n);
 	}
 }
 
 static void
-add_year_of_gdate_gst_tag (GHashTable  *metadata,
+add_year_of_gdate_gst_tag (GPtrArray  *metadata,
+		const gchar *uri,
 			   const gchar *key,
 			   GstTagList  *tag_list,
 			   const gchar *tag)
@@ -458,9 +455,8 @@ add_year_of_gdate_gst_tag (GHashTable  *metadata,
 		gchar buf[10];
 
 		if (g_date_strftime (buf, 10, "%Y", date)) {
-			g_hash_table_insert (metadata,
-					     g_strdup (key),
-					     tracker_escape_metadata (buf));
+			tracker_statement_list_insert (metadata, uri,
+						  key, buf);
 		}
 	}
 
@@ -535,90 +531,111 @@ get_embedded_album_art(MetadataExtractor *extractor)
 
 static void
 extract_metadata (MetadataExtractor *extractor,
-		  GHashTable  *metadata)
+                  const gchar *uri,
+		  GPtrArray  *metadata,
+                  gchar **artist,
+                  gchar **album,
+                  gchar **scount)
 {
 	g_return_if_fail (extractor);
 	g_return_if_fail (metadata);
 
 	if (extractor->audio_channels >= 0) {
-		add_uint_info (metadata,
-			       g_strdup ("Audio:Channels"),
+		add_uint_info (metadata, uri,
+			       ("Audio:Channels"),
 			       extractor->audio_channels);
 	}
 
 	if (extractor->audio_samplerate >= 0) {
-		add_uint_info (metadata,
-			       g_strdup ("Audio:Samplerate"),
+		add_uint_info (metadata, uri,
+			       ("Audio:Samplerate"),
 			       extractor->audio_samplerate);
 	}
 
 	if (extractor->video_height >= 0) {
-		add_uint_info (metadata,
-			       g_strdup ("Video:Height"),
+		add_uint_info (metadata, uri,
+			       ("Video:Height"),
 			       extractor->video_height);
 	}
 
 	if (extractor->video_width >= 0) {
-		add_uint_info (metadata,
-			       g_strdup ("Video:Width"),
+		add_uint_info (metadata, uri,
+			       ("Video:Width"),
 			       extractor->video_height);
 	}
 
 	if (extractor->video_fps_n >= 0 && extractor->video_fps_d >= 0) {
-		add_uint_info (metadata,
-			       g_strdup ("Video:FrameRate"),
+		add_uint_info (metadata, uri,
+			       ("Video:FrameRate"),
 			       ((extractor->video_fps_n + extractor->video_fps_d / 2) / extractor->video_fps_d));
 	}
 
 	if (extractor->tagcache) {
 		gint64 duration;
+		gint n;
+		gchar *s;
 
 		/* Audio */
-		add_string_gst_tag (metadata, "Audio:Album", extractor->tagcache, GST_TAG_ALBUM);
-		add_uint_gst_tag (metadata, "Audio:AlbumTrackCount", extractor->tagcache, GST_TAG_TRACK_COUNT);
-		add_uint_gst_tag (metadata, "Audio:TrackNo", extractor->tagcache, GST_TAG_TRACK_NUMBER);
-		add_uint_gst_tag (metadata, "Audio:DiscNo", extractor->tagcache, GST_TAG_ALBUM_VOLUME_NUMBER);
-		add_string_gst_tag (metadata, "Audio:Performer", extractor->tagcache, GST_TAG_PERFORMER);
-		add_double_gst_tag (metadata, "Audio:TrackGain", extractor->tagcache, GST_TAG_TRACK_GAIN);
-		add_double_gst_tag (metadata, "Audio:PeakTrackGain", extractor->tagcache, GST_TAG_TRACK_PEAK);
-		add_double_gst_tag (metadata, "Audio:AlbumGain", extractor->tagcache, GST_TAG_ALBUM_GAIN);
-		add_double_gst_tag (metadata, "Audio:AlbumPeakGain", extractor->tagcache, GST_TAG_ALBUM_PEAK);
-		add_year_of_gdate_gst_tag (metadata, "Audio:ReleaseDate", extractor->tagcache, GST_TAG_DATE);
-		add_string_gst_tag (metadata, "Audio:Genre", extractor->tagcache, GST_TAG_GENRE);
-		add_string_gst_tag (metadata, "Audio:Codec", extractor->tagcache, GST_TAG_AUDIO_CODEC);
+		add_string_gst_tag (metadata, uri, "Audio:Album", extractor->tagcache, GST_TAG_ALBUM);
+
+		if (gst_tag_list_get_string (extractor->tagcache, GST_TAG_ALBUM, &s)) {
+			*album = s;
+		}
+
+		add_uint_gst_tag (metadata, uri, "Audio:AlbumTrackCount", extractor->tagcache, GST_TAG_TRACK_COUNT);
+
+		if (gst_tag_list_get_uint (extractor->tagcache, GST_TAG_TRACK_COUNT, &n)) {
+			*scount = g_strdup_printf ("%d", n);
+		}
+
+		add_uint_gst_tag (metadata, uri, "Audio:TrackNo", extractor->tagcache, GST_TAG_TRACK_NUMBER);
+		add_uint_gst_tag (metadata, uri, "Audio:DiscNo", extractor->tagcache, GST_TAG_ALBUM_VOLUME_NUMBER);
+		add_string_gst_tag (metadata, uri, "Audio:Performer", extractor->tagcache, GST_TAG_PERFORMER);
+		add_double_gst_tag (metadata, uri, "Audio:TrackGain", extractor->tagcache, GST_TAG_TRACK_GAIN);
+		add_double_gst_tag (metadata, uri, "Audio:PeakTrackGain", extractor->tagcache, GST_TAG_TRACK_PEAK);
+		add_double_gst_tag (metadata,uri,  "Audio:AlbumGain", extractor->tagcache, GST_TAG_ALBUM_GAIN);
+		add_double_gst_tag (metadata, uri, "Audio:AlbumPeakGain", extractor->tagcache, GST_TAG_ALBUM_PEAK);
+		add_year_of_gdate_gst_tag (metadata, uri, "Audio:ReleaseDate", extractor->tagcache, GST_TAG_DATE);
+		add_string_gst_tag (metadata, uri, "Audio:Genre", extractor->tagcache, GST_TAG_GENRE);
+		add_string_gst_tag (metadata, uri, "Audio:Codec", extractor->tagcache, GST_TAG_AUDIO_CODEC);
 
 		/* Video */
-		add_string_gst_tag (metadata, "Video:Codec", extractor->tagcache, GST_TAG_VIDEO_CODEC);
+		add_string_gst_tag (metadata, uri, "Video:Codec", extractor->tagcache, GST_TAG_VIDEO_CODEC);
 
 		/* General */
-		add_string_gst_tag (metadata, "File:Copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
-		add_string_gst_tag (metadata, "File:License", extractor->tagcache, GST_TAG_LICENSE);
-		add_string_gst_tag (metadata, "DC:Coverage", extractor->tagcache, GST_TAG_LOCATION);
+		add_string_gst_tag (metadata, uri, "File:Copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
+		add_string_gst_tag (metadata, uri, "File:License", extractor->tagcache, GST_TAG_LICENSE);
+		add_string_gst_tag (metadata, uri, "DC:Coverage", extractor->tagcache, GST_TAG_LOCATION);
 
 		duration = get_media_duration (extractor);
 
 		/* FIXME Use the has_video and has_audio rather than mime type once dsp problems are solved */
 /* 		if (extractor->has_video) { */
 		if (extractor->mime == EXTRACT_MIME_VIDEO) {
-			add_string_gst_tag (metadata, "Video:Title", extractor->tagcache, GST_TAG_TITLE);
-			add_string_gst_tag (metadata, "Video:Comments", extractor->tagcache, GST_TAG_COMMENT);
+			add_string_gst_tag (metadata, uri, "Video:Title", extractor->tagcache, GST_TAG_TITLE);
+			add_string_gst_tag (metadata, uri, "Video:Comments", extractor->tagcache, GST_TAG_COMMENT);
 
 			/* FIXME: is it a good idea to use GST_TAG_ARTIST as author?! */
-			add_string_gst_tag (metadata, "Video:Author", extractor->tagcache, GST_TAG_ARTIST);
-			add_string_gst_tag (metadata, "File:Copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
+			add_string_gst_tag (metadata, uri, "Video:Author", extractor->tagcache, GST_TAG_ARTIST);
+			add_string_gst_tag (metadata, uri, "File:Copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
 
 			if (duration >= 0) {
-				add_int64_info (metadata, g_strdup ("Video:Duration"), duration);
+				add_int64_info (metadata, uri, ("Video:Duration"), duration);
 			}
 /* 		} else if (extractor->has_audio) { */
 		} else if (extractor->mime == EXTRACT_MIME_AUDIO) {
 			/* No video? So we assume we are treating a song */
-			add_string_gst_tag (metadata, "Audio:Title", extractor->tagcache, GST_TAG_TITLE);
-			add_string_gst_tag (metadata, "Audio:Artist", extractor->tagcache, GST_TAG_ARTIST);
-			add_string_gst_tag (metadata, "Audio:Comment", extractor->tagcache, GST_TAG_COMMENT);
+			add_string_gst_tag (metadata,uri,  "Audio:Title", extractor->tagcache, GST_TAG_TITLE);
+			add_string_gst_tag (metadata,uri,  "Audio:Artist", extractor->tagcache, GST_TAG_ARTIST);
+
+			if (gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s)) {
+				*artist = s;
+			}
+
+			add_string_gst_tag (metadata, uri, "Audio:Comment", extractor->tagcache, GST_TAG_COMMENT);
 
 			if (duration >= 0) {
-				add_int64_info (metadata, g_strdup ("Audio:Duration"), duration);
+				add_int64_info (metadata, uri,  ("Audio:Duration"), duration);
 			}
 
 			get_embedded_album_art (extractor);
@@ -626,11 +643,11 @@ extract_metadata (MetadataExtractor *extractor,
 	}
 
 	if (extractor->audiotags) {
-		add_uint_gst_tag (metadata, "Audio:Bitrate", extractor->tagcache, GST_TAG_BITRATE);
+		add_uint_gst_tag (metadata,uri,  "Audio:Bitrate", extractor->tagcache, GST_TAG_BITRATE);
 	}
 
 	if (extractor->videotags) {
-		add_uint_gst_tag (metadata, "Video:Bitrate", extractor->tagcache, GST_TAG_BITRATE);
+		add_uint_gst_tag (metadata,uri,  "Video:Bitrate", extractor->tagcache, GST_TAG_BITRATE);
 	}
 }
 
@@ -748,13 +765,13 @@ poll_for_state_change (MetadataExtractor *extractor,
 
 static void
 tracker_extract_gstreamer_helix (const gchar *uri,
-				 GHashTable  *metadata,
+				 GPtrArray  *metadata,
 				 ExtractMime	type)
 {
 	MetadataExtractor *extractor;
-	gchar		  *mrl;
 	GstElement	  *fakesink_video;
 	GstBus		  *bus;
+	gchar		  *artist, *album, *scount;
 
 	g_return_if_fail (uri);
 	g_return_if_fail (metadata);
@@ -791,11 +808,8 @@ tracker_extract_gstreamer_helix (const gchar *uri,
 	g_signal_connect (bus, "message", G_CALLBACK (gst_bus_cb), extractor);
 	gst_object_unref (bus);
 
-	mrl = g_strconcat ("file://", uri, NULL);
-
 	/* Set playbin object */
-	g_object_set (G_OBJECT (extractor->playbin), "uri", mrl, NULL);
-	g_free (mrl);
+	g_object_set (G_OBJECT (extractor->playbin), "uri", uri, NULL);
 
 	fakesink_video = gst_element_factory_make ("fakesink", "fakesink-video");
 	g_object_set (G_OBJECT (extractor->playbin), "video-sink", fakesink_video, NULL);
@@ -805,61 +819,34 @@ tracker_extract_gstreamer_helix (const gchar *uri,
 
 	poll_for_state_change (extractor, GST_STATE_PAUSED);
 
-	extract_metadata (extractor, metadata);
+	artist = NULL;
+	album = NULL;
+	scount = NULL;
+
+	extract_metadata (extractor, uri, metadata, &artist, &album, &scount);
 
 	/* Save embedded art */
 	if (extractor->album_art_data && extractor->album_art_size) {
+
 #ifdef HAVE_GDKPIXBUF
 		tracker_process_albumart (extractor->album_art_data, extractor->album_art_size,
-				       /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
-				       g_hash_table_lookup (metadata, "Audio:Album"),
-				       g_hash_table_lookup (metadata, "Audio:AlbumTrackCount"),
+				       /* artist */ NULL ,
+				       album,
+				       scount,
 				       uri);
 #else
 		tracker_process_albumart (NULL, 0,
-				       /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
-				       g_hash_table_lookup (metadata, "Audio:Album"),
-				       g_hash_table_lookup (metadata, "Audio:AlbumTrackCount"),
+				       /* artist */ NULL ,
+				       album,
+				       scount,
 				       uri);
 
 #endif /* HAVE_GDKPIXBUF */
+		g_free (album);
+		g_free (artist);
+		g_free (scount);
 	}
 
-	/* Check that we have the minimum data. FIXME We should not need to do this */
-
-	if (type == EXTRACT_MIME_VIDEO) {
-		if (!g_hash_table_lookup (metadata, "Video:Title")) {
-			gchar  *basename = g_filename_display_basename (uri);
-			gchar **parts    = g_strsplit (basename, ".", -1);
-			gchar  *title    = g_strdup (parts[0]);
-			
-			g_strfreev (parts);
-			g_free (basename);
-
-			title = g_strdelimit (title, "_", ' ');
-			
-			g_hash_table_insert (metadata,
-					     g_strdup ("Video:Title"),
-					     tracker_escape_metadata (title));
-			g_free (title);
-		}
-	} else if (type == EXTRACT_MIME_AUDIO) {
-		if (!g_hash_table_lookup (metadata, "Audio:Title")) {
-			gchar  *basename = g_filename_display_basename (uri);
-			gchar **parts    = g_strsplit (basename, ".", -1);
-			gchar  *title    = g_strdup (parts[0]);
-			
-			g_strfreev (parts);
-			g_free (basename);
-			
-			title = g_strdelimit (title, "_", ' ');
-			
-			g_hash_table_insert (metadata,
-					     g_strdup ("Audio:Title"),
-					     tracker_escape_metadata (title));
-			g_free (title);
-		}
-	}
 
 	/* Also clean up */
 	gst_element_set_state (extractor->playbin, GST_STATE_NULL);
@@ -870,13 +857,13 @@ tracker_extract_gstreamer_helix (const gchar *uri,
 }
 
 static void
-extract_gstreamer_helix_audio (const gchar *uri, GHashTable *metadata)
+extract_gstreamer_helix_audio (const gchar *uri, GPtrArray *metadata)
 {
 	tracker_extract_gstreamer_helix (uri, metadata, EXTRACT_MIME_AUDIO);
 }
 
 static void
-extract_gstreamer_helix_video (const gchar *uri, GHashTable *metadata)
+extract_gstreamer_helix_video (const gchar *uri, GPtrArray *metadata)
 {
 	tracker_extract_gstreamer_helix (uri, metadata, EXTRACT_MIME_VIDEO);
 }
diff --git a/src/tracker-extract/tracker-extract-gstreamer.c b/src/tracker-extract/tracker-extract-gstreamer.c
index 9e71d56..2cd7e8b 100644
--- a/src/tracker-extract/tracker-extract-gstreamer.c
+++ b/src/tracker-extract/tracker-extract-gstreamer.c
@@ -33,6 +33,9 @@
 #include <gst/tag/tag.h>
 
 #include <libtracker-common/tracker-type-utils.h>
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-utils.h>
 
 #include "tracker-main.h"
 #include "tracker-extract-albumart.h"
@@ -42,6 +45,15 @@
 #define GST_TAG_CLASSIFICATION "classification"
 #endif
 
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
 typedef enum {
 	EXTRACT_MIME_UNDEFINED,
 	EXTRACT_MIME_AUDIO,
@@ -89,11 +101,11 @@ typedef struct {
 const guint use_dbin  = 1;
 const guint use_cache = 0;
 
-static void extract_gstreamer_audio (const gchar *uri, GHashTable *metadata);
-static void extract_gstreamer_video (const gchar *uri, GHashTable *metadata);
-static void extract_gstreamer_image (const gchar *uri, GHashTable *metadata);
+static void extract_gstreamer_audio (const gchar *uri, GPtrArray *metadata);
+static void extract_gstreamer_video (const gchar *uri, GPtrArray *metadata);
+static void extract_gstreamer_image (const gchar *uri, GPtrArray *metadata);
 
-static TrackerExtractData data[] = {
+static TrackerExtractData gstreamer_data[] = {
 	{ "audio/*", extract_gstreamer_audio },
 	{ "video/*", extract_gstreamer_video },
 	{ "image/*", extract_gstreamer_image },
@@ -101,29 +113,26 @@ static TrackerExtractData data[] = {
 };
 
 static void
-add_int64_info (GHashTable *metadata,
-		gchar	   *key,
+add_int64_info (GPtrArray *metadata,
+		const gchar *uri,
+		const gchar	   *key,
 		gint64	    info)
 {
-	gchar *str_info;
-
-	str_info = tracker_escape_metadata_printf ("%" G_GINT64_FORMAT, info);
-	g_hash_table_insert (metadata, key, str_info);
+	tracker_statement_list_insert_with_int64 (metadata, uri, key, info);
 }
 
 static void
-add_uint_info (GHashTable *metadata,
-	       gchar	  *key,
+add_uint_info (GPtrArray *metadata,
+	       const gchar *uri,
+	       const gchar	  *key,
 	       guint	   info)
 {
-	gchar *str_info;
-
-	str_info = tracker_escape_metadata_printf ("%d", info);
-	g_hash_table_insert (metadata, key, str_info);
+	tracker_statement_list_insert_with_int (metadata, uri, key, info);
 }
 
 static void
-add_string_gst_tag (GHashTable	*metadata,
+add_string_gst_tag (GPtrArray	*metadata,
+		    const gchar *uri,
 		    const gchar *key,
 		    GstTagList	*tag_list,
 		    const gchar *tag)
@@ -136,9 +145,7 @@ add_string_gst_tag (GHashTable	*metadata,
 
 	if (s) {
 		if (ret && s[0] != '\0') {
-			g_hash_table_insert (metadata,
-					     g_strdup (key),
-					     tracker_escape_metadata (s));
+			tracker_statement_list_insert (metadata, uri, key, s);
 		}
 
 		g_free (s);
@@ -146,7 +153,8 @@ add_string_gst_tag (GHashTable	*metadata,
 }
 
 static void
-add_uint_gst_tag (GHashTable  *metadata,
+add_uint_gst_tag (GPtrArray  *metadata,
+		const gchar *uri,
 		  const gchar *key,
 		  GstTagList  *tag_list,
 		  const gchar *tag)
@@ -157,14 +165,13 @@ add_uint_gst_tag (GHashTable  *metadata,
 	ret = gst_tag_list_get_uint (tag_list, tag, &n);
 
 	if (ret) {
-		g_hash_table_insert (metadata,
-				     g_strdup (key),
-				     tracker_escape_metadata_printf ("%d", n));
+		tracker_statement_list_insert_with_int (metadata, uri, key, n);
 	}
 }
 
 static void
-add_double_gst_tag (GHashTable	*metadata,
+add_double_gst_tag (GPtrArray	*metadata,
+		const gchar *uri,
 		    const gchar *key,
 		    GstTagList	*tag_list,
 		    const gchar *tag)
@@ -175,17 +182,16 @@ add_double_gst_tag (GHashTable	*metadata,
 	ret = gst_tag_list_get_double (tag_list, tag, &n);
 
 	if (ret) {
-		g_hash_table_insert (metadata,
-				     g_strdup (key),
-				     tracker_escape_metadata_printf ("%f", n));
+		tracker_statement_list_insert_with_double (metadata, uri, key, n);
 	}
 }
 
 static void
-add_y_date_gst_tag (GHashTable  *metadata,
-		    const gchar *key,
-		    GstTagList  *tag_list,
-		    const gchar *tag)
+add_y_date_gst_tag (GPtrArray  *metadata,
+		const gchar *uri,
+			   const gchar *key,
+			   GstTagList  *tag_list,
+			   const gchar *tag)
 {
 	GDate	 *date;
 	gboolean  ret;
@@ -197,9 +203,8 @@ add_y_date_gst_tag (GHashTable  *metadata,
 		gchar buf[10];
 
 		if (g_date_strftime (buf, 10, "%Y", date)) {
-			g_hash_table_insert (metadata,
-					     g_strdup (key),
-					     tracker_escape_metadata (buf));
+			tracker_statement_list_insert (metadata, uri,
+						  key, buf);
 		}
 	}
 
@@ -233,117 +238,197 @@ get_media_duration (MetadataExtractor *extractor)
 
 static void
 extract_metadata (MetadataExtractor *extractor,
-		  GHashTable        *metadata)
+		  const gchar       *uri,
+		  GPtrArray         *metadata,
+		  gchar            **artist,
+		  gchar            **album,
+		  gchar            **scount)
 {
-	gchar *value;
+	gchar *s;
+	gint   n;
+
 	g_return_if_fail (extractor);
 	g_return_if_fail (metadata);
 
 	if (extractor->tagcache) {
 		/* General */
-		add_string_gst_tag (metadata, "File:Copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
-		add_string_gst_tag (metadata, "File:License", extractor->tagcache, GST_TAG_LICENSE);
-		add_string_gst_tag (metadata, "DC:Coverage", extractor->tagcache, GST_TAG_LOCATION);
+		add_string_gst_tag (metadata, uri, NIE_PREFIX "copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
+		add_string_gst_tag (metadata, uri, NIE_PREFIX "license", extractor->tagcache, GST_TAG_LICENSE);
+		add_string_gst_tag (metadata, uri, DC_PREFIX "coverage", extractor->tagcache, GST_TAG_LOCATION);
 
 		/* Audio */
- 		add_string_gst_tag (metadata, "Audio:Album", extractor->tagcache, GST_TAG_ALBUM);
-		add_uint_gst_tag   (metadata, "Audio:AlbumTrackCount", extractor->tagcache, GST_TAG_TRACK_COUNT);
-		add_uint_gst_tag   (metadata, "Audio:TrackNo", extractor->tagcache, GST_TAG_TRACK_NUMBER);
-		add_uint_gst_tag   (metadata, "Audio:DiscNo", extractor->tagcache, GST_TAG_ALBUM_VOLUME_NUMBER);
-		add_string_gst_tag (metadata, "Audio:Performer", extractor->tagcache, GST_TAG_PERFORMER);
-		add_double_gst_tag (metadata, "Audio:TrackGain", extractor->tagcache, GST_TAG_TRACK_GAIN);
-		add_double_gst_tag (metadata, "Audio:PeakTrackGain", extractor->tagcache, GST_TAG_TRACK_PEAK);
-		add_double_gst_tag (metadata, "Audio:AlbumGain", extractor->tagcache, GST_TAG_ALBUM_GAIN);
-		add_double_gst_tag (metadata, "Audio:AlbumPeakGain", extractor->tagcache, GST_TAG_ALBUM_PEAK);
-		add_y_date_gst_tag (metadata, "Audio:ReleaseDate", extractor->tagcache, GST_TAG_DATE);
-		add_string_gst_tag (metadata, "Audio:Genre", extractor->tagcache, GST_TAG_GENRE);
-		add_string_gst_tag (metadata, "Audio:Codec", extractor->tagcache, GST_TAG_AUDIO_CODEC);
+		gst_tag_list_get_string (extractor->tagcache, GST_TAG_ALBUM, &s);
+		if (s) {
+			gchar *canonical_uri = tracker_uri_printf_escaped ("urn:album:%s", s);
+			tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "MusicAlbum");
+			tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "albumTitle", s);
+			tracker_statement_list_insert (metadata, uri, NMM_PREFIX "musicAlbum", canonical_uri);
+			g_free (canonical_uri);
+			*album = s;
+		}
+
+		add_uint_gst_tag   (metadata, uri, NMM_PREFIX "albumTrackCount", extractor->tagcache, GST_TAG_TRACK_COUNT);
+
+
+		if (gst_tag_list_get_uint (extractor->tagcache, GST_TAG_TRACK_COUNT, &n)) {
+			*scount = g_strdup_printf ("%d", n);
+		}
+
+		add_uint_gst_tag   (metadata, uri, NMM_PREFIX "trackNumber", extractor->tagcache, GST_TAG_TRACK_NUMBER);
+
+		add_uint_gst_tag   (metadata, uri, NMM_PREFIX "setNumber", extractor->tagcache, GST_TAG_ALBUM_VOLUME_NUMBER);
+
+		gst_tag_list_get_string (extractor->tagcache, GST_TAG_PERFORMER, &s);
+		if (s) {
+			gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
+			tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "Artist");
+			tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "artistName", s);
+			tracker_statement_list_insert (metadata, uri, NMM_PREFIX "performer", canonical_uri);
+			g_free (canonical_uri);
+			g_free (s);
+		}
+	
+		add_double_gst_tag (metadata, uri, NFO_PREFIX "gain", extractor->tagcache, GST_TAG_TRACK_GAIN);
+
+		add_double_gst_tag (metadata, uri, NFO_PREFIX "peakGain", extractor->tagcache, GST_TAG_TRACK_PEAK);
+
+		add_double_gst_tag (metadata, uri, NMM_PREFIX "albumGain", extractor->tagcache, GST_TAG_ALBUM_GAIN);
+		add_double_gst_tag (metadata, uri, NMM_PREFIX "albumPeakGain", extractor->tagcache, GST_TAG_ALBUM_PEAK);
+		
+		
+		add_y_date_gst_tag (metadata, uri, NIE_PREFIX "contentCreated", extractor->tagcache, GST_TAG_DATE);
+		add_string_gst_tag (metadata, uri, NFO_PREFIX "genre", extractor->tagcache, GST_TAG_GENRE);
+		add_string_gst_tag (metadata, uri, NFO_PREFIX "codec", extractor->tagcache, GST_TAG_AUDIO_CODEC);
 
 		/* Video */
-		add_string_gst_tag (metadata, "Video:Codec", extractor->tagcache, GST_TAG_VIDEO_CODEC);
+		add_string_gst_tag (metadata, uri, NFO_PREFIX "codec", extractor->tagcache, GST_TAG_VIDEO_CODEC);
 
 		if (extractor->mime == EXTRACT_MIME_IMAGE) {
-			add_string_gst_tag (metadata, "Image:Title", extractor->tagcache, GST_TAG_TITLE);
-			add_string_gst_tag (metadata, "Image:Comments", extractor->tagcache, GST_TAG_COMMENT);
-			add_string_gst_tag (metadata, "Image:Creator", extractor->tagcache, GST_TAG_ARTIST);
+			add_string_gst_tag (metadata, uri, NIE_PREFIX "title", extractor->tagcache, GST_TAG_TITLE);
+			add_string_gst_tag (metadata, uri, NIE_PREFIX "comment", extractor->tagcache, GST_TAG_COMMENT);
+
+			gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s);
+			if (s) {
+				gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
+				tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "Artist");
+				tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "artistName", s);
+				tracker_statement_list_insert (metadata, uri, NMM_PREFIX "performer", canonical_uri);
+				g_free (canonical_uri);
+				g_free (s);
+			}
+
 		} else if (extractor->mime == EXTRACT_MIME_VIDEO) {
-			add_string_gst_tag (metadata, "Video:Title", extractor->tagcache, GST_TAG_TITLE);
-			add_string_gst_tag (metadata, "Video:Comments", extractor->tagcache, GST_TAG_COMMENT);
-			add_string_gst_tag (metadata, "Video:Author", extractor->tagcache, GST_TAG_ARTIST);
-			add_string_gst_tag (metadata, "Video:Source", extractor->tagcache, GST_TAG_CLASSIFICATION);
+			add_string_gst_tag (metadata, uri, NIE_PREFIX "title", extractor->tagcache, GST_TAG_TITLE);
+			add_string_gst_tag (metadata, uri, NIE_PREFIX "comment", extractor->tagcache, GST_TAG_COMMENT);
+
+			gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s);
+			if (s) {
+				gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
+				tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "Artist");
+				tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "artistName", s);
+				tracker_statement_list_insert (metadata, uri, NMM_PREFIX "performer", canonical_uri);
+				g_free (canonical_uri);
+				g_free (s);
+			}
+
+			add_string_gst_tag (metadata, uri, DC_PREFIX "source", extractor->tagcache, GST_TAG_CLASSIFICATION);
 		} else if (extractor->mime == EXTRACT_MIME_AUDIO) {
-			add_string_gst_tag (metadata, "Audio:Title", extractor->tagcache, GST_TAG_TITLE);
-			add_string_gst_tag (metadata, "Audio:Artist", extractor->tagcache, GST_TAG_ARTIST);
-			add_string_gst_tag (metadata, "Audio:Comment", extractor->tagcache, GST_TAG_COMMENT);
+			add_string_gst_tag (metadata, uri, NIE_PREFIX "title", extractor->tagcache, GST_TAG_TITLE);
+
+			gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s);
+			if (s) {
+				gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
+				tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "Artist");
+				tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "artistName", s);
+				tracker_statement_list_insert (metadata, uri, NMM_PREFIX "performer", canonical_uri);
+				g_free (canonical_uri);
+				g_free (s);
+			}
+
+			if (gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s)) {
+				*artist = s;
+			}
+
+			add_string_gst_tag (metadata, uri, NIE_PREFIX "comment", extractor->tagcache, GST_TAG_COMMENT);
 		}
  	}
 
 	if (extractor->audio_channels >= 0) {
-		add_uint_info (metadata,
-			       g_strdup ("Audio:Channels"),
-			       extractor->audio_channels);
+		add_uint_info (metadata, uri,
+			       NFO_PREFIX "channels",
+			       (guint) extractor->audio_channels);
 	}
 
 	if (extractor->audio_samplerate >= 0) {
-		add_uint_info (metadata,
-			       g_strdup ("Audio:Samplerate"),
-			       extractor->audio_samplerate);
+		add_uint_info (metadata, uri,
+			       NFO_PREFIX "sampleRate",
+			       (guint) extractor->audio_samplerate);
 	}
 
 	if (extractor->video_height >= 0) {
 		if (extractor->mime == EXTRACT_MIME_IMAGE) {
-			add_uint_info (metadata,
-				       g_strdup ("Image:Height"),
-				       extractor->video_height);
+			add_uint_info (metadata, uri,
+				       NFO_PREFIX "height",
+				       (guint) extractor->video_height);
 		} else {
-			add_uint_info (metadata,
-				       g_strdup ("Video:Height"),
-				       extractor->video_height);
+			add_uint_info (metadata, uri,
+				       NFO_PREFIX "height",
+				      (guint)  extractor->video_height);
 		}
 	}
 
 	if (extractor->video_width >= 0) {
 		if (extractor->mime == EXTRACT_MIME_IMAGE) {
-			add_uint_info (metadata,
-				       g_strdup ("Image:Width"),
-				       extractor->video_width);
+			add_uint_info (metadata, uri,
+				       NFO_PREFIX "width",
+				       (guint) extractor->video_width);
 		} else {
-			add_uint_info (metadata,
-				       g_strdup ("Video:Width"),
-				       extractor->video_width);
+			add_uint_info (metadata, uri,
+				       NFO_PREFIX "width",
+				       (guint) extractor->video_width);
 		}
 	}
 
  	if (extractor->mime == EXTRACT_MIME_VIDEO) {
+ 
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NMM_PREFIX "Video");
+
 		if (extractor->video_fps_n >= 0 && extractor->video_fps_d >= 0) {
-			add_uint_info (metadata,
-				       g_strdup ("Video:FrameRate"),
+			add_uint_info (metadata, uri,
+				       NFO_PREFIX "frameRate",
 				       ((extractor->video_fps_n + extractor->video_fps_d / 2) / 
 					extractor->video_fps_d));
 		}
  		if (extractor->duration >= 0) {
- 			add_int64_info (metadata, g_strdup ("Video:Duration"), extractor->duration);
+ 			add_int64_info (metadata, uri, NFO_PREFIX "duration", extractor->duration);
  		}
  	} else if (extractor->mime == EXTRACT_MIME_AUDIO) {
+
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NMM_PREFIX "MusicPiece");
+
  		if (extractor->duration >= 0) {
- 			add_int64_info (metadata, g_strdup ("Audio:Duration"), extractor->duration);
+ 			add_int64_info (metadata, uri, NMM_PREFIX "length", extractor->duration);
  		}
- 	}
+ 	} else if (extractor->mime == EXTRACT_MIME_IMAGE) {
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "Image");
+	} else {
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "FileDataObject");
+	}
 
 	if (extractor->audiotags) {
-		add_uint_gst_tag (metadata, "Audio:Bitrate", extractor->audiotags, GST_TAG_BITRATE);
+		add_uint_gst_tag (metadata, uri, NFO_PREFIX "averageBitrate", extractor->audiotags, GST_TAG_BITRATE);
 	}
 
 	if (extractor->videotags) {
-		add_uint_gst_tag (metadata, "Video:Bitrate", extractor->videotags, GST_TAG_BITRATE);
-	}
-
-	/* Do some postprocessing (FIXME, or fix gstreamer) */
-	if ( (value = g_hash_table_lookup (metadata, "Audio:Genre")) ) {
-		if (strcmp(value, "Unknown") == 0) {
-			g_hash_table_remove (metadata,
-					     "Audio:Genre");
-		}
+		add_uint_gst_tag (metadata, uri, NFO_PREFIX "averageBitrate", extractor->videotags, GST_TAG_BITRATE);
 	}
 
 }
@@ -443,6 +528,8 @@ add_stream_tags_tagreadbin_for_element (MetadataExtractor *extractor, GstElement
 		case GST_ITERATOR_DONE:
 			done = TRUE;
 			break;
+		default:
+			break;
 		}
 	}
 	gst_iterator_free (iter);
@@ -643,10 +730,11 @@ metadata_bus_async_cb (GstBus *bus, GstMessage *msg, gpointer data)
 
 static void
 tracker_extract_gstreamer (const gchar *uri,
-			   GHashTable  *metadata,
+			   GPtrArray   *metadata,
 			   ExtractMime	type)
 {
 	MetadataExtractor *extractor;
+	gchar		  *album = NULL, *artist = NULL, *scount = NULL;
 
 	g_return_if_fail (uri);
 	g_return_if_fail (metadata);
@@ -745,26 +833,31 @@ tracker_extract_gstreamer (const gchar *uri,
 
 	g_main_loop_run (extractor->loop);
 
-	extract_metadata (extractor, metadata);
+	extract_metadata (extractor, uri, metadata, 
+			  &artist, &album, &scount);
 
 	/* Save embedded art */
 	if (extractor->album_art_data && extractor->album_art_size) {
 #ifdef HAVE_GDKPIXBUF
 		tracker_process_albumart (extractor->album_art_data, extractor->album_art_size,
-					  /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
-					  g_hash_table_lookup (metadata, "Audio:Album"),
-					  g_hash_table_lookup (metadata, "Audio:AlbumTrackCount"),
+					  /* artist */ NULL,
+					  album,
+					  scount,
 					  uri);
 #else
 		tracker_process_albumart (NULL, 0,
-					  /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
-					  g_hash_table_lookup (metadata, "Audio:Album"),
-					  g_hash_table_lookup (metadata, "Audio:AlbumTrackCount"),
+					  /* artist */ NULL,
+					  album,
+					  scount,
 					  uri);
 		
 #endif /* HAVE_GDKPIXBUF */
 	}
 
+	g_free (album);
+	g_free (artist);
+	g_free (scount);
+
 	gst_element_set_state (extractor->pipeline, GST_STATE_NULL);
 	gst_object_unref (extractor->bus);
 
@@ -785,22 +878,23 @@ tracker_extract_gstreamer (const gchar *uri,
 	g_slice_free (MetadataExtractor, extractor);
 
 	if (type == EXTRACT_MIME_IMAGE) {
-		if (!g_hash_table_lookup (metadata, "Image:Date")) {
+		if (!tracker_statement_list_find (metadata, uri, "Image:Date")) {
 			struct stat st;
 			
 			if (g_lstat (uri, &st) >= 0) {
 				gchar *date;
-				
+
 				date = tracker_date_to_string (st.st_mtime);
-				
-				g_hash_table_insert (metadata,
-						     g_strdup ("Image:Date"),
-						     tracker_escape_metadata (date));
+
+				tracker_statement_list_insert (metadata, uri,
+							  "Image:Date",
+							  date);
+
 				g_free (date);
 			}
 		}
 	} else if (type == EXTRACT_MIME_VIDEO) {
-		if (!g_hash_table_lookup (metadata, "Video:Title")) {
+		if (!tracker_statement_list_find (metadata, uri, NIE_PREFIX "title")) {
 			gchar  *basename = g_filename_display_basename (uri);
 			gchar **parts    = g_strsplit (basename, ".", -1);
 			gchar  *title    = g_strdup (parts[0]);
@@ -809,14 +903,15 @@ tracker_extract_gstreamer (const gchar *uri,
 			g_free (basename);
 
 			title = g_strdelimit (title, "_", ' ');
-			
-			g_hash_table_insert (metadata,
-					     g_strdup ("Video:Title"),
-					     tracker_escape_metadata (title));
+
+			tracker_statement_list_insert (metadata, uri, 
+						  NIE_PREFIX "title", 
+						  title);
+
 			g_free (title);
 		}
 	} else if (type == EXTRACT_MIME_AUDIO) {
-		if (!g_hash_table_lookup (metadata, "Audio:Title")) {
+		if (!tracker_statement_list_find (metadata, uri, NIE_PREFIX "title")) {
 			gchar  *basename = g_filename_display_basename (uri);
 			gchar **parts    = g_strsplit (basename, ".", -1);
 			gchar  *title    = g_strdup (parts[0]);
@@ -825,10 +920,11 @@ tracker_extract_gstreamer (const gchar *uri,
 			g_free (basename);
 			
 			title = g_strdelimit (title, "_", ' ');
-			
-			g_hash_table_insert (metadata,
-					     g_strdup ("Audio:Title"),
-					     tracker_escape_metadata (title));
+
+			tracker_statement_list_insert (metadata, uri, 
+						  NIE_PREFIX "title", 
+						  title);
+
 			g_free (title);
 		}
 	}
@@ -837,19 +933,19 @@ tracker_extract_gstreamer (const gchar *uri,
 
 
 static void
-extract_gstreamer_audio (const gchar *uri, GHashTable *metadata)
+extract_gstreamer_audio (const gchar *uri, GPtrArray *metadata)
 {
 	tracker_extract_gstreamer (uri, metadata, EXTRACT_MIME_AUDIO);
 }
 
 static void
-extract_gstreamer_video (const gchar *uri, GHashTable *metadata)
+extract_gstreamer_video (const gchar *uri, GPtrArray *metadata)
 {
 	tracker_extract_gstreamer (uri, metadata, EXTRACT_MIME_VIDEO);
 }
 
 static void
-extract_gstreamer_image (const gchar *uri, GHashTable *metadata)
+extract_gstreamer_image (const gchar *uri, GPtrArray *metadata)
 {
 	tracker_extract_gstreamer (uri, metadata, EXTRACT_MIME_IMAGE);
 }
@@ -857,6 +953,6 @@ extract_gstreamer_image (const gchar *uri, GHashTable *metadata)
 TrackerExtractData *
 tracker_get_extract_data (void)
 {
-	return data;
+	return gstreamer_data;
 }
 
diff --git a/src/tracker-extract/tracker-extract-html.c b/src/tracker-extract/tracker-extract-html.c
index aece8f6..b091559 100644
--- a/src/tracker-extract/tracker-extract-html.c
+++ b/src/tracker-extract/tracker-extract-html.c
@@ -25,21 +25,31 @@
 #include <glib.h>
 
 #include <libxml/HTMLparser.h>
+#include <libtracker-common/tracker-statement-list.h>
 
 #include "tracker-main.h"
-#include "tracker-escape.h"
+
+#include <libtracker-common/tracker-ontology.h>
+
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
 
 typedef enum {
 	READ_TITLE,
 } tag_type;
 
 typedef struct {
-	GHashTable *metadata;
+	GPtrArray *metadata;
 	tag_type current;
+	const gchar *uri;
 } HTMLParseInfo;
 
 static void extract_html (const gchar *filename,
-			  GHashTable  *metadata);
+			  GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 	{ "text/html",		   extract_html },
@@ -89,10 +99,12 @@ lookup_attribute (const xmlChar **atts,
 }
 
 void
-startElement (void	     *info,
+startElement (void	     *info_,
 	      const xmlChar  *name,
 	      const xmlChar **atts)
 {
+	HTMLParseInfo* info = info_;
+
 	if (!(info && name)) {
 		return;
 	}
@@ -109,13 +121,13 @@ startElement (void	     *info,
 			href = lookup_attribute (atts, "href");
 
 			if (href) {
-				g_hash_table_insert (((HTMLParseInfo*) info)->metadata,
-						     g_strdup ("File:License"),
-						     tracker_escape_metadata ((gchar*)  href));
+				tracker_statement_list_insert (info->metadata,
+							  info->uri, NIE_PREFIX "license", 
+							  (const gchar *)  href);
 			}
 		}
 	} else if (strcasecmp ((gchar*)name, "title") == 0) {
-		((HTMLParseInfo*) info)->current = READ_TITLE;
+		info->current = READ_TITLE;
 	} else if (strcasecmp ((gchar*)name, "meta") == 0) {
 		if (has_attribute (atts, "name", "Author")) {
 			const xmlChar *author;
@@ -123,9 +135,9 @@ startElement (void	     *info,
 			author = lookup_attribute (atts, "content");
 
 			if (author) {
-				g_hash_table_insert (((HTMLParseInfo*) info)->metadata,
-						     g_strdup ("Doc:Author"),
-						     tracker_escape_metadata ((gchar*) author));
+				tracker_statement_list_insert (info->metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+				tracker_statement_list_insert (info->metadata, ":", NCO_PREFIX "fullname", author);
+				tracker_statement_list_insert (info->metadata, info->uri, NCO_PREFIX "creator", ":");
 			}
 		}
 
@@ -135,49 +147,58 @@ startElement (void	     *info,
 			desc = lookup_attribute (atts,"content");
 
 			if (desc) {
-				g_hash_table_insert (((HTMLParseInfo*) info)->metadata,
-						     g_strdup ("Doc:Comments"),
-						     tracker_escape_metadata ((gchar*) desc));
+				tracker_statement_list_insert (info->metadata,
+							  info->uri, NIE_PREFIX "comment",
+							  (const gchar *) desc);
 			}
 		}
 
 		if (has_attribute (atts, "name", "KEYWORDS") ||
 		    has_attribute (atts, "name", "keywords")) {
-			const xmlChar *keywords;
+			const xmlChar* k = lookup_attribute (atts, "content");
+
+			if (k) {
+				gchar *keywords = g_strdup (k);
+				char *lasts, *keyw;
 
-			keywords = lookup_attribute (atts, "content");
+				for (keyw = strtok_r (keywords, ",;", &lasts); keyw; 
+				     keyw = strtok_r (NULL, ",;", &lasts)) {
+					tracker_statement_list_insert (info->metadata,
+							  info->uri, NIE_PREFIX "keyword",
+							  (const gchar*) keyw);
+				}
 
-			if (keywords) {
-				g_hash_table_insert (((HTMLParseInfo*) info)->metadata,
-						     g_strdup ("Doc:Keywords"),
-						     tracker_escape_metadata ((gchar*) keywords));
+				g_free (keywords);
 			}
 		}
 	}
 }
 
 void
-characters (void	  *info,
+characters (void	  *info_,
 	    const xmlChar *ch,
 	    int		   len)
 {
-	switch (((HTMLParseInfo*) info)->current) {
+	HTMLParseInfo* info = info_;
+
+	switch (info->current) {
 	case READ_TITLE:
-		g_hash_table_insert (((HTMLParseInfo*) info)->metadata,
-				     g_strdup ("Doc:Title"),
-				     tracker_escape_metadata ((gchar*) ch));
+		tracker_statement_list_insert (info->metadata,
+					  info->uri, NIE_PREFIX "title",
+					  (const gchar*) ch);
 		break;
 	default:
 		break;
 	}
 
-	((HTMLParseInfo*) info)->current = -1;
+	info->current = -1;
 }
 
 static void
-extract_html (const gchar *filename,
-	      GHashTable  *metadata)
+extract_html (const gchar *uri,
+	      GPtrArray   *metadata)
 {
+	gchar *filename = g_filename_from_uri (uri, NULL, NULL);
 	xmlSAXHandler SAXHandlerStruct = {
 			NULL, /* internalSubset */
 			NULL, /* isStandalone */
@@ -213,13 +234,20 @@ extract_html (const gchar *filename,
 			NULL  /* xmlStructuredErrorFunc */
 	};
 
-	HTMLParseInfo	info = { metadata, -1 };
+	HTMLParseInfo	info = { metadata, -1, uri };
 
 	htmlDocPtr doc;
 	doc = htmlSAXParseFile (filename, NULL, &SAXHandlerStruct, &info);
 	if (doc) {
+
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "Document");
+
 		xmlFreeDoc (doc);
 	}
+
+	g_free (filename);
 }
 
 TrackerExtractData *
diff --git a/src/tracker-extract/tracker-extract-imagemagick.c b/src/tracker-extract/tracker-extract-imagemagick.c
index 76391eb..fc25e7b 100644
--- a/src/tracker-extract/tracker-extract-imagemagick.c
+++ b/src/tracker-extract/tracker-extract-imagemagick.c
@@ -27,13 +27,24 @@
 
 #include <glib.h>
 
+#include <libtracker-common/tracker-ontology.h>
 #include <libtracker-common/tracker-os-dependant.h>
+#include <libtracker-common/tracker-statement.h>
 
 #include "tracker-main.h"
 #include "tracker-xmp.h"
 
-static void extract_imagemagick (const gchar *filename, 
-				 GHashTable  *metadata);
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+static void extract_imagemagick (const gchar *uri, 
+				 GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 	{ "image/*", extract_imagemagick },
@@ -41,18 +52,22 @@ static TrackerExtractData data[] = {
 };
 
 static void
-extract_imagemagick (const gchar *filename, 
-		     GHashTable  *metadata)
+extract_imagemagick (const gchar *uri, 
+		     GPtrArray   *metadata)
 {
 	gchar *argv[6];
 	gchar *identify;
 	gchar **lines;
 	gint  exit_status;
+	gchar *filename;
+
+	filename = g_filename_from_uri (uri, NULL, NULL);
 
 	g_return_if_fail (filename != NULL);
 
 	/* Imagemagick crashes trying to extract from xcf files */
 	if (g_str_has_suffix (filename, ".xcf")) {
+		g_free (filename);
 		return;
 	}
 
@@ -72,27 +87,33 @@ extract_imagemagick (const gchar *filename,
 
 	if (tracker_spawn (argv, 10, &identify, &exit_status)) {
 		if (exit_status == EXIT_SUCCESS) {
+
+
+			tracker_insert_statement (metadata, uri, 
+			                          RDF_TYPE, 
+			                          NFO_PREFIX "Document");
+
 			lines = g_strsplit (identify, ";\n", 4);
 
-			g_hash_table_insert (metadata, 
-					     g_strdup ("Image:Width"), 
-					     g_strdup (lines[0]));
-			g_hash_table_insert (metadata, 
-					     g_strdup ("Image:Height"), 
-					     g_strdup (lines[1]));
-
-			/* FIXME: Should we use METADATA_UNKNOWN
-			 * (tracker:unknown) here? -mr
-			 */
-			g_hash_table_insert (metadata, 
-					     g_strdup ("Image:Comments"), 
-					     g_strdup (g_strescape (lines[2], "")));
+			tracker_insert_statement (metadata, uri,
+						  NFO_PREFIX "width", 
+						  lines[0]);
+
+			tracker_insert_statement (metadata, uri,
+						  NFO_PREFIX "height", 
+						  lines[1]);
+
+			tracker_insert_statement (metadata, uri,
+						  NIE_PREFIX "comment", 
+						  lines[2]);
+
+			g_strfreev (lines);
 		}
 	}
 
 #ifdef HAVE_EXEMPI
 	/* FIXME: Convert is buggy atm so disable temporarily */
-	return;
+	g_free (filename); return;
 
 	gchar *xmp;
 
@@ -103,10 +124,13 @@ extract_imagemagick (const gchar *filename,
 
 	if (tracker_spawn (argv, 10, &xmp, &exit_status)) {
 		if (exit_status == EXIT_SUCCESS && xmp) {
-			tracker_read_xmp (xmp, strlen (xmp), metadata);
+			tracker_read_xmp (xmp, strlen (xmp), uri, metadata);
 		}
 	}
 #endif /* HAVE_EXEMPI */
+
+	g_free (filename);
+
 }
 
 TrackerExtractData *
diff --git a/src/tracker-extract/tracker-extract-jpeg.c b/src/tracker-extract/tracker-extract-jpeg.c
index dc6b340..4a1383d 100644
--- a/src/tracker-extract/tracker-extract-jpeg.c
+++ b/src/tracker-extract/tracker-extract-jpeg.c
@@ -39,13 +39,25 @@
 
 #include <jpeglib.h>
 
-#include <libtracker-common/tracker-type-utils.h>
 #include <libtracker-common/tracker-file-utils.h>
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-type-utils.h>
+#include <libtracker-common/tracker-utils.h>
 
 #include "tracker-main.h"
 #include "tracker-xmp.h"
 #include "tracker-iptc.h"
 
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
 #ifdef HAVE_EXEMPI
 #define XMP_NAMESPACE	     "http://ns.adobe.com/xap/1.0/\x00";
 #define XMP_NAMESPACE_LENGTH 29
@@ -63,7 +75,7 @@
 #endif /* HAVE_LIBIPTCDATA */
 
 static void extract_jpeg (const gchar *filename,
-			  GHashTable  *metadata);
+			  GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 	{ "image/jpeg", extract_jpeg },
@@ -101,17 +113,17 @@ static gchar *fix_exposure_time (const gchar *et);
 static gchar *fix_orientation   (const gchar *orientation);
 
 static TagType tags[] = {
-	{ EXIF_TAG_PIXEL_Y_DIMENSION, "Image:Height", NULL },
-	{ EXIF_TAG_PIXEL_X_DIMENSION, "Image:Width", NULL },
-	{ EXIF_TAG_RELATED_IMAGE_WIDTH, "Image:Width", NULL },
-	{ EXIF_TAG_DOCUMENT_NAME, "Image:Title", NULL },
+	{ EXIF_TAG_PIXEL_Y_DIMENSION, NFO_PREFIX "height", NULL },
+	{ EXIF_TAG_PIXEL_X_DIMENSION, NFO_PREFIX "width", NULL },
+	{ EXIF_TAG_RELATED_IMAGE_WIDTH, NFO_PREFIX "width", NULL },
+	{ EXIF_TAG_DOCUMENT_NAME, NIE_PREFIX "title", NULL },
 	/* { -1, "Image:Album", NULL }, */
-	{ EXIF_TAG_DATE_TIME, "Image:Date", date_to_iso8601 },
-	{ EXIF_TAG_DATE_TIME_ORIGINAL, "Image:Date", date_to_iso8601 },
+	{ EXIF_TAG_DATE_TIME, NIE_PREFIX "contentCreated", date_to_iso8601 },
+	{ EXIF_TAG_DATE_TIME_ORIGINAL, NIE_PREFIX "contentCreated", date_to_iso8601 },
 	/* { -1, "Image:Keywords", NULL }, */
-	{ EXIF_TAG_ARTIST, "Image:Creator", NULL },
-	{ EXIF_TAG_USER_COMMENT, "Image:Comments", NULL },
-	{ EXIF_TAG_IMAGE_DESCRIPTION, "Image:Description", NULL },
+	{ EXIF_TAG_ARTIST, NCO_PREFIX "creator", NULL },
+	{ EXIF_TAG_USER_COMMENT, NIE_PREFIX "comment", NULL },
+	{ EXIF_TAG_IMAGE_DESCRIPTION, NIE_PREFIX "description", NULL },
 	{ EXIF_TAG_SOFTWARE, "Image:Software", NULL },
 	{ EXIF_TAG_MAKE, "Image:CameraMake", NULL },
 	{ EXIF_TAG_MODEL, "Image:CameraModel", NULL },
@@ -124,7 +136,7 @@ static TagType tags[] = {
 	{ EXIF_TAG_ISO_SPEED_RATINGS, "Image:ISOSpeed", NULL },
 	{ EXIF_TAG_METERING_MODE, "Image:MeteringMode", NULL },
 	{ EXIF_TAG_WHITE_BALANCE, "Image:WhiteBalance", NULL },
-	{ EXIF_TAG_COPYRIGHT, "File:Copyright", NULL },
+	{ EXIF_TAG_COPYRIGHT, NIE_PREFIX "copyright", NULL },
 	{ -1, NULL, NULL }
 };
 
@@ -232,7 +244,8 @@ fix_orientation (const gchar *orientation)
 static void
 read_exif (const unsigned char *buffer,
 	   size_t		len,
-	   GHashTable	       *metadata)
+	   const gchar         *uri,
+	   GPtrArray	       *metadata)
 {
 	ExifData *exif;
 	TagType  *p;
@@ -240,29 +253,32 @@ read_exif (const unsigned char *buffer,
 	exif = exif_data_new_from_data ((unsigned char *) buffer, len);
 
 	for (p = tags; p->name; ++p) {
-		ExifEntry *entry;
-
-		entry = exif_data_get_entry (exif, p->tag);
+		ExifEntry *entry = exif_data_get_entry (exif, p->tag);
 
 		if (entry) {
 			gchar buffer[1024];
+			gchar *what_i_need;
 
 			exif_entry_get_value (entry, buffer, 1024);
 
 			if (p->post) {
-				gchar *str;
-
-				str = (*p->post) (buffer);
+				what_i_need = (*p->post) (buffer);
+			} else {
+				what_i_need = buffer;
+			}
 
-				g_hash_table_insert (metadata,
-						     g_strdup (p->name),
-						     tracker_escape_metadata (str));
-				g_free (str);
+			if (p->tag == EXIF_TAG_ARTIST) {
+				gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", what_i_need);
+				tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NCO_PREFIX "Contact");
+				tracker_statement_list_insert (metadata, canonical_uri, NCO_PREFIX "fullname", what_i_need);
+				tracker_statement_list_insert (metadata, uri, p->name, canonical_uri);
+				g_free (canonical_uri);
 			} else {
-				g_hash_table_insert (metadata,
-						     g_strdup (p->name),
-						     tracker_escape_metadata (buffer));
+				tracker_statement_list_insert (metadata, uri, p->name, what_i_need);
 			}
+
+			if (p->post)
+				g_free (what_i_need);
 		}
 	}
 	
@@ -273,14 +289,17 @@ read_exif (const unsigned char *buffer,
 
 
 static void
-extract_jpeg (const gchar *filename,
-	      GHashTable  *metadata)
+extract_jpeg (const gchar *uri,
+	      GPtrArray   *metadata)
 {
 	struct jpeg_decompress_struct  cinfo;
 	struct tej_error_mgr	       tejerr;
 	struct jpeg_marker_struct     *marker;
 	FILE			      *f;
 	goffset                        size;
+	gchar                         *filename;
+
+	filename = g_filename_from_uri (uri, NULL, NULL);
 
 	size = tracker_file_get_size (filename);
 
@@ -298,6 +317,10 @@ extract_jpeg (const gchar *filename,
 		gsize  sublen;
 #endif /* HAVE_LIBEXIF */
 
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "Image");
+
 		cinfo.err = jpeg_std_error (&tejerr.jpeg);
 		tejerr.jpeg.error_exit = tracker_extract_jpeg_error_exit;
 		if (setjmp(tejerr.setjmp_buffer)) {
@@ -330,10 +353,10 @@ extract_jpeg (const gchar *filename,
 			case JPEG_COM:
 				len = marker->data_length;
 				str = g_strndup ((gchar*) marker->data, len);
-				
-				g_hash_table_insert (metadata,
-						     g_strdup ("Image:Comments"),
-						     tracker_escape_metadata (str));
+
+				tracker_statement_list_insert (metadata, uri,
+							  NIE_PREFIX "comment",
+							  str);
 				g_free (str);
 				break;
 				
@@ -344,7 +367,7 @@ extract_jpeg (const gchar *filename,
 #ifdef HAVE_LIBEXIF
 				if (strncmp ("Exif", (gchar*) (marker->data), 5) == 0) {
 					read_exif ((unsigned char*) marker->data,
-						   marker->data_length,
+						   marker->data_length, uri,
 						   metadata);
 				}
 #endif /* HAVE_LIBEXIF */
@@ -354,7 +377,7 @@ extract_jpeg (const gchar *filename,
 				if (strncmp (XMP_NAMESPACE, str, XMP_NAMESPACE_LENGTH) == 0) {
 					tracker_read_xmp (str + XMP_NAMESPACE_LENGTH,
 							  len - XMP_NAMESPACE_LENGTH,
-							  metadata);
+							  uri, metadata);
 				}
 #endif /* HAVE_EXEMPI */
 				break;
@@ -367,7 +390,7 @@ extract_jpeg (const gchar *filename,
 					if (offset>0) {
 						tracker_read_iptc (str + offset,
 								   sublen,
-								   metadata);
+								   uri, metadata);
 					}
 				}
 #endif /* HAVE_LIBIPTCDATA */
@@ -381,32 +404,18 @@ extract_jpeg (const gchar *filename,
 		}
 
 		/* We want native size to have priority over EXIF, XMP etc */
-		g_hash_table_insert (metadata,
-				     g_strdup ("Image:Width"),
-				     tracker_escape_metadata_printf ("%u", cinfo.image_width));
-		g_hash_table_insert (metadata,
-				     g_strdup ("Image:Height"),
-				     tracker_escape_metadata_printf ("%u", cinfo.image_height));
-
-		/* Check that we have the minimum data. FIXME We should not need to do this */
-
-		if (!g_hash_table_lookup (metadata, "Image:Date")) {
-			gchar *date;
-			guint64 mtime;
-
-			mtime = tracker_file_get_mtime (filename);
-			date = tracker_date_to_string ((time_t) mtime);
-
-			g_hash_table_insert (metadata,
-					     g_strdup ("Image:Date"),
-					     tracker_escape_metadata (date));
-			g_free (date);
-		}
-
-		jpeg_destroy_decompress (&cinfo);
-	fail:
+		tracker_statement_list_insert_with_int (metadata, uri,
+						   NFO_PREFIX "width",
+						   cinfo.image_width);
+		tracker_statement_list_insert_with_int (metadata, uri,
+						   NFO_PREFIX "height",
+						    cinfo.image_height);
+
+fail:
 		tracker_file_close (f, FALSE);
 	}
+
+	g_free (filename);
 }
 
 TrackerExtractData *
diff --git a/src/tracker-extract/tracker-extract-libxine.c b/src/tracker-extract/tracker-extract-libxine.c
index 75683d3..7e3b01d 100644
--- a/src/tracker-extract/tracker-extract-libxine.c
+++ b/src/tracker-extract/tracker-extract-libxine.c
@@ -22,22 +22,25 @@
 #include <xine.h>
 #include <glib.h>
 
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-utils.h>
+
 #include "tracker-main.h"
 
-static void
-add_uint32_info (GHashTable *metadata, char *key, uint32_t info)
-{
-	char *str_info;
-
-	str_info = tracker_escape_metadata_printf ("%d", info);
-	g_hash_table_insert (metadata, key, str_info);
-}
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
 
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
 
 /* Take an absolute path to a file and fill a hashtable with metadata.
  */
 void
-tracker_extract_xine (gchar *uri, GHashTable *metadata)
+tracker_extract_xine (gchar *uri, GPtrArray *metadata)
 {
 	xine_t		  *xine_base;
 	xine_audio_port_t *audio_port;
@@ -62,7 +65,6 @@ tracker_extract_xine (gchar *uri, GHashTable *metadata)
 
 	g_return_if_fail (uri && metadata);
 
-
 	xine_base = xine_new ();
 
 	if (!xine_base) {
@@ -88,7 +90,7 @@ tracker_extract_xine (gchar *uri, GHashTable *metadata)
 		return;
 	}
 
-	mrl = g_strconcat ("file://", uri, NULL);
+	mrl = g_filename_from_uri (uri, NULL, NULL);
 
 	if (!xine_open (stream, mrl)) {
 		g_free (mrl);
@@ -101,21 +103,20 @@ tracker_extract_xine (gchar *uri, GHashTable *metadata)
 
 	g_free (mrl);
 
-
 	has_audio = xine_get_stream_info (stream, XINE_STREAM_INFO_HAS_AUDIO);
 	has_video = xine_get_stream_info (stream, XINE_STREAM_INFO_HAS_VIDEO);
 
 
 	if (xine_get_pos_length (stream, &pos_stream, &pos_time, &length_time)) {
 		if (length_time >= 0) {
-			uint32_t duration;
+			guint32 duration;
 
-			duration = (uint32_t) length_time / 1000; /* from miliseconds to seconds */
+			duration = (guint32) length_time / 1000; /* from miliseconds to seconds */
 
 			if (has_video) {
-				add_uint32_info (metadata, g_strdup ("Video:Duration"), duration);
+				tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "duration", duration);
 			} else if (has_audio) {
-				add_uint32_info (metadata, g_strdup ("Audio:Duration"), duration);
+				tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "duration", duration);
 			}
 		}
 	}
@@ -124,60 +125,70 @@ tracker_extract_xine (gchar *uri, GHashTable *metadata)
 	/* Video */
 
 	if (has_video) {
-		uint32_t   n, n0;
+		guint32 n, n0;
 		const char *video_codec;
 
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NMM_PREFIX "Video");
+
 		n  = xine_get_stream_info (stream, XINE_STREAM_INFO_VIDEO_HEIGHT);
 		n0 = xine_get_stream_info (stream, XINE_STREAM_INFO_VIDEO_WIDTH);
 		if (n > 0 && n0 > 0) {
-			add_uint32_info (metadata, g_strdup ("Video:Height"), n);
-			add_uint32_info (metadata, g_strdup ("Video:Width"), n0);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "height", n);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "width", n0);
 		}
 
 		n = xine_get_stream_info (stream, XINE_STREAM_INFO_FRAME_DURATION);
 		if (n > 0) {
 			/* 90000 because it is how is done in Xine! */
-			add_uint32_info (metadata, g_strdup ("Video:FrameRate"), 90000 / n);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "frameRate", 90000 / n);
 		}
 
 		n = xine_get_stream_info (stream, XINE_STREAM_INFO_VIDEO_BITRATE);
 		if (n > 0) {
-			add_uint32_info (metadata, g_strdup ("Video:Bitrate"), n);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "averageBitrate", n);
 		}
 
 		video_codec = xine_get_meta_info (stream, XINE_META_INFO_VIDEOCODEC);
 		if (video_codec) {
-			g_hash_table_insert (metadata, g_strdup ("Video:Codec"),
-                                             tracker_escape_metadata (video_codec));
+			tracker_statement_list_insert (metadata, uri, NFO_PREFIX "codec", video_codec);
 		}
+	} else if (has_audio) {
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NMM_PREFIX "MusicPiece");
+	} else {
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "FileDataObject");
 	}
 
 
 	/* Audio */
 
 	if (has_audio) {
-		uint32_t   n;
+		guint32   n;
 		const char *audio_codec;
 
 		n = xine_get_stream_info (stream, XINE_STREAM_INFO_AUDIO_BITRATE);
 		if (n > 0) {
-			add_uint32_info (metadata, g_strdup ("Audio:Bitrate"), n);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "averageBitrate", n);
 		}
 
 		n = xine_get_stream_info (stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE);
 		if (n > 0) {
-			add_uint32_info (metadata, g_strdup ("Audio:Samplerate"), n);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "samplerate", n);
 		}
 
 		n = xine_get_stream_info (stream, XINE_STREAM_INFO_AUDIO_CHANNELS);
 		if (n > 0) {
-			add_uint32_info (metadata, g_strdup ("Audio:Channels"), n);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "channels", n);
 		}
 
 		audio_codec = xine_get_meta_info (stream, XINE_META_INFO_AUDIOCODEC);
 		if (audio_codec) {
-			g_hash_table_insert (metadata, g_strdup ("Audio:Codec"),
-                                             tracker_escape_metadata (audio_codec));
+			tracker_statement_list_insert (metadata, uri, NFO_PREFIX "codec", audio_codec);
 		}
 	}
 
@@ -187,62 +198,52 @@ tracker_extract_xine (gchar *uri, GHashTable *metadata)
 	comment = xine_get_meta_info (stream, XINE_META_INFO_COMMENT);
 	if (comment) {
 		if (has_video) {
-			g_hash_table_insert (metadata, g_strdup ("Video:Comment"),
-                                             tracker_escape_metadata (comment));
+			tracker_statement_list_insert (metadata, uri, NIE_PREFIX "comment", comment);
 		} else if (has_audio) {
-			g_hash_table_insert (metadata, g_strdup ("Audio:Comment"),
-                                             tracker_escape_metadata (comment));
+			tracker_statement_list_insert (metadata, uri, NIE_PREFIX "comment", comment);
 		}
 	}
 
 	title = xine_get_meta_info (stream, XINE_META_INFO_TITLE);
 	if (title) {
 		if (has_video) {
-			g_hash_table_insert (metadata, g_strdup ("Video:Title"),
-                                             tracker_escape_metadata (title));
+			tracker_statement_list_insert (metadata, uri, NIE_PREFIX "title", title);
 		} else if (has_audio) {
-			g_hash_table_insert (metadata, g_strdup ("Audio:Title"),
-                                             tracker_escape_metadata (title));
+			tracker_statement_list_insert (metadata, uri, NIE_PREFIX "title", title);
 		}
 	}
 
 	author = xine_get_meta_info (stream, XINE_META_INFO_ARTIST);
 	if (author) {
-		if (has_video) {
-			g_hash_table_insert (metadata, g_strdup ("Video:Author"),
-                                             tracker_escape_metadata (author));
-		} else if (has_audio) {
-			g_hash_table_insert (metadata, g_strdup ("Audio:Author"),
-                                             tracker_escape_metadata (author));
-		}
+		gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
+		tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NCO_PREFIX "Contact");
+		tracker_statement_list_insert (metadata, canonical_uri, NCO_PREFIX "fullname", s);
+		tracker_statement_list_insert (metadata, uri, NCO_PREFIX "creator", canonical_uri);
+		g_free (canonical_uri);
 	}
 
 	album = xine_get_meta_info (stream, XINE_META_INFO_ALBUM);
 	if (album) {
-		g_hash_table_insert (metadata, g_strdup ("Audio:Album"),
-                                     tracker_escape_metadata (album));
+		tracker_statement_list_insert (metadata, uri, NIE_PREFIX "title", album);
 	}
 
 	year = xine_get_meta_info (stream, XINE_META_INFO_YEAR);
 	if (year) {
-		g_hash_table_insert (metadata, g_strdup ("Audio:Year"),
-                                     tracker_escape_metadata (year));
+		tracker_statement_list_insert (metadata, uri, "Audio:Year"), year);
 	}
 
 	genre = xine_get_meta_info (stream, XINE_META_INFO_GENRE);
 	if (genre) {
-		g_hash_table_insert (metadata, g_strdup ("Audio:Genre"),
-                                     tracker_escape_metadata (genre));
+		tracker_statement_list_insert (metadata, uri, NFO_PREFIX "genre" , genre);
 	}
 
 	track = xine_get_meta_info (stream, XINE_META_INFO_TRACK_NUMBER);
 	if (track) {
-		g_hash_table_insert (metadata, g_strdup ("Audio:Track"),
-                                     tracker_escape_metadata (track));
+		tracker_statement_list_insert (metadata, uri, NMM_PREFIX "trackNumber", track);
 	}
 
 	/* FIXME: "Video.Copyright" seems missing */
-	/* g_hash_table_insert (metadata, g_strdup ("Video.Copyright"), NULL); */
+	/* tracker_statement_list_insert (metadata, uri, "Video.Copyright", NULL); */
 
 
 	xine_dispose (stream);
diff --git a/src/tracker-extract/tracker-extract-mp3.c b/src/tracker-extract/tracker-extract-mp3.c
index fa6425e..d3cb7c3 100644
--- a/src/tracker-extract/tracker-extract-mp3.c
+++ b/src/tracker-extract/tracker-extract-mp3.c
@@ -40,11 +40,12 @@
 #endif /* G_OS_WIN32 */
 
 #include <libtracker-common/tracker-file-utils.h>
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
 #include <libtracker-common/tracker-utils.h>
 
 #include "tracker-main.h"
 #include "tracker-extract-albumart.h"
-#include "tracker-escape.h"
 
 /* FIXME The max file read is not a good idea as basic 
  * id3 are the _last_ 128 bits of the file. We should
@@ -56,9 +57,21 @@
 #define MAX_FRAMES_SCAN   1024 * 3
 #define VBR_THRESHOLD     64
 
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
 typedef struct {
 	const gchar *text;
 	const gchar *type;
+	const gchar *urn;
+	const gchar *rdf_type;
+	const gchar *predicate;
 } Matches;
 
 typedef struct {
@@ -93,7 +106,7 @@ enum {
 };
 
 static void extract_mp3 (const gchar *filename,
-			 GHashTable  *metadata);
+			 GPtrArray  *metadata);
 
 static const char *const genre_names[] = {
 	"Blues",
@@ -287,12 +300,12 @@ static TrackerExtractData extract_data[] = {
 
 /* Convert from UCS-2 to UTF-8 checking the BOM.*/
 static gchar *
-ucs2_to_utf8 (const gchar *data, guint len) 
+ucs2_to_utf8(const gchar *data, guint len)
 {
-        gchar    *encoding = NULL;
-        guint16   c;
-	gboolean  be;
-        gchar    *utf8 = NULL;
+        const gchar   *encoding = NULL;
+        guint16  c;
+	gboolean be;
+        gchar   *utf8 = NULL;
 
         memcpy (&c, data, 2);
 
@@ -460,7 +473,8 @@ static gboolean
 mp3_parse_header (const gchar *data,
 		  size_t       size,
 		  size_t       seek_pos,
-		  GHashTable  *metadata)
+		  const gchar *uri,
+		  GPtrArray  *metadata)
 {
 	guint header;
 	gchar mpeg_ver = 0;
@@ -487,32 +501,32 @@ mp3_parse_header (const gchar *data,
 		    mpeg_ver = MPEG_ERR;
 		    break;
 	    case 0x1000:
-		    g_hash_table_insert (metadata,
-					 g_strdup ("Audio:Codec"),
-					 g_strdup ("MPEG"));
-		    g_hash_table_insert (metadata,
-					 g_strdup ("Audio:CodecVersion"),
-					 g_strdup ("2"));
+		    tracker_statement_list_insert (metadata, uri,
+					 NFO_PREFIX "codec",
+					 "MPEG");
+		    tracker_statement_list_insert (metadata, uri,
+					 "Audio:CodecVersion",
+					 "2");
 		    mpeg_ver = MPEG_V2;
 		    spfp8 = 72;
 		    break;
 	    case 0x1800:
-		    g_hash_table_insert (metadata,
-					 g_strdup ("Audio:Codec"),
-					 g_strdup ("MPEG"));
-		    g_hash_table_insert (metadata,
-					 g_strdup ("Audio:CodecVersion"),
-					 g_strdup ("1"));
+		    tracker_statement_list_insert (metadata, uri,
+					 NFO_PREFIX "codec",
+					 "MPEG");
+		    tracker_statement_list_insert (metadata, uri,
+					 "Audio:CodecVersion",
+					 "1");
 		    mpeg_ver = MPEG_V1;
 		    spfp8 = 144;
 		    break;
 	    case 0:
-		    g_hash_table_insert (metadata,
-					 g_strdup ("Audio:Codec"),
-					 g_strdup ("MPEG"));
-		    g_hash_table_insert (metadata,
-					 g_strdup ("Audio:CodecVersion"),
-					 g_strdup ("2.5"));
+		    tracker_statement_list_insert (metadata, uri,
+					 NFO_PREFIX "codec",
+					 "MPEG");
+		    tracker_statement_list_insert (metadata, uri,
+					 "Audio:CodecVersion",
+					 "2.5");
 		    mpeg_ver = MPEG_V25;
 		    spfp8 = 72;
 		    break;
@@ -553,14 +567,14 @@ mp3_parse_header (const gchar *data,
 	
 	if ((header & ch_mask) == ch_mask) {
 		ch = 1;
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:Channels"),
-				     g_strdup ("1"));
+		tracker_statement_list_insert (metadata, uri,
+				     NFO_PREFIX "channels",
+				     "1");
 	} else {
-		ch = 2; /* stereo non stereo select */
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:Channels"),
-				     g_strdup ("2"));
+		ch=2; /*stereo non stereo select*/
+		tracker_statement_list_insert (metadata, uri,
+				     NFO_PREFIX "channels",
+				     "2");
 	}
 	
 	/* We assume mpeg version, layer and channels are constant in frames */
@@ -574,11 +588,13 @@ mp3_parse_header (const gchar *data,
 		}
 
 		sample_rate = freq_table[(header & freq_mask) >> 18][mpeg_ver - 1];
-		if (sample_rate < 0) {
-			/* Error in header */
+		/* Whoever wrote this check: it's pointless, sample_rate is a uint,
+		 so it can't ever be < 0. Hence commenting it out (pvanhoof)
+		 if (sample_rate < 0) {
+			* Error in header *
 			frames--;
 			return FALSE;
-		}
+		}*/
 
 		frame_size = spfp8 * bitrate / (sample_rate ? sample_rate : 1) + padsize*((header & pad_mask) >> 17);
 		avg_bps += bitrate / 1000;
@@ -620,15 +636,15 @@ mp3_parse_header (const gchar *data,
 		length = 1152 * frames / (sample_rate ? sample_rate : 0xFFFFFFFF);
 	}
 
-	g_hash_table_insert (metadata,
-			     g_strdup ("Audio:Duration"),
-			     tracker_escape_metadata_printf ("%d", length));
-	g_hash_table_insert (metadata,
-			     g_strdup ("Audio:Samplerate"),
-			     tracker_escape_metadata_printf ("%d", sample_rate));
-	g_hash_table_insert (metadata,
-			     g_strdup ("Audio:Bitrate"),
-			     tracker_escape_metadata_printf ("%d", avg_bps*1000));
+	tracker_statement_list_insert_with_int (metadata, uri,
+			     NMM_PREFIX "length",
+			     length);
+	tracker_statement_list_insert_with_int (metadata, uri,
+			     NFO_PREFIX "sampleRate",
+			     sample_rate);
+	tracker_statement_list_insert_with_int (metadata, uri,
+			     NFO_PREFIX "averageBitrate",
+			     avg_bps*1000);
 
 	return TRUE;
 }
@@ -636,7 +652,8 @@ mp3_parse_header (const gchar *data,
 static void
 mp3_parse (const gchar *data,
 	   size_t       size,
-	   GHashTable  *metadata,
+	   const gchar *uri,
+	   GPtrArray  *metadata,
 	   file_data   *filedata)
 {
 	guint header;
@@ -653,7 +670,7 @@ mp3_parse (const gchar *data,
 
 		if ((header & sync_mask) == sync_mask) {
 			/* Found header sync */
-			if (mp3_parse_header (data, size, pos, metadata)) {
+			if (mp3_parse_header (data,size,pos,uri,metadata)) {
 				return;
 			}
 		}
@@ -666,31 +683,32 @@ mp3_parse (const gchar *data,
 static void
 get_id3v24_tags (const gchar *data,
 		 size_t       size,
-		 GHashTable  *metadata,
+		 const gchar *uri,
+		 GPtrArray  *metadata,
 		 file_data   *filedata)
 {
 	guint pos = 0;
 	Matches tmap[] = {
-		{"TCOP", "File:Copyright"},
-		{"TDRC", "Audio:ReleaseDate"},
-		{"TCON", "Audio:Genre"},
-		{"TIT1", "Audio:Genre"},
-		{"TENC", "DC:Publishers"},
-		{"TEXT", "Audio:Lyrics"},
-		{"TPE1", "Audio:Artist"},
-		{"TPE2", "Audio:Artist"},
-		{"TPE3", "Audio:Performer"},
-		/*	{"TOPE", "Audio:Artist"}, We dont' want the original artist for now */
-		{"TPUB", "DC:Publishers"},
-		{"TOAL", "Audio:Album"},
-		{"TALB", "Audio:Album"},
-		{"TLAN", "File:Language"},
-		{"TIT2", "Audio:Title"},
-		{"TIT3", "Audio:Comment"},
-		{"TDRL", "Audio:ReleaseDate"},
-		{"TRCK", "Audio:TrackNo"},
-		{"PCNT", "Audio:PlayCount"},
-		{NULL, 0},
+		{"TCOP", NIE_PREFIX "copyright", NULL, NULL, NULL},
+		{"TDRC", NIE_PREFIX "contentCreated", NULL, NULL, NULL},
+		{"TCON", NFO_PREFIX "genre", NULL, NULL, NULL},
+		{"TIT1", NFO_PREFIX "genre", NULL, NULL, NULL},
+		{"TENC", NCO_PREFIX "publisher", "publisher", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TEXT", NIE_PREFIX "plainTextContent", FALSE},
+		{"TPE1", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TPE2", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TPE3", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		/*	{"TOPE", NID3_LEAD_ARTIST}, We dont' want the original artist for now */
+		{"TPUB", NCO_PREFIX "publisher", "publisher", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TOAL", NIE_PREFIX "title", NULL, NULL, NULL},
+		{"TALB", NIE_PREFIX "title" , NULL, NULL, NULL},
+		{"TLAN", NIE_PREFIX "language", NULL, NULL, NULL},
+		{"TIT2", NIE_PREFIX "title", NULL, NULL, NULL},
+		{"TIT3", NIE_PREFIX "comment", NULL, NULL, NULL},
+		{"TDRL", NIE_PREFIX "contentCreated", NULL, NULL, NULL},
+		{"TRCK", NMM_PREFIX "trackNumber", NULL, NULL, NULL},
+		/* TODO Nepomukify {"PCNT", "Audio:PlayCount"}, */
+		{NULL, 0, NULL, NULL, NULL},
 	};
 
 	while (pos < size) {
@@ -800,11 +818,19 @@ get_id3v24_tags (const gchar *data,
 						if (strcasecmp (word, "unknown") == 0) {
 							break;
 						}
-					}					
+					}
 
-					g_hash_table_insert (metadata,
-							     g_strdup (tmap[i].type),
-							     tracker_escape_metadata (word));
+					if (tmap[i].urn) {
+						gchar *canonical_uri = tmap[i].urn[0]!=':'?tracker_uri_printf_escaped ("urn:%s:%s", tmap[i].urn, word):g_strdup(tmap[i].urn);
+						tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, tmap[i].rdf_type);
+						tracker_statement_list_insert (metadata, canonical_uri, tmap[i].predicate, word);
+						tracker_statement_list_insert (metadata, uri, tmap[i].type, canonical_uri);
+						g_free (canonical_uri);
+					} else {
+						tracker_statement_list_insert (metadata, uri,
+									  tmap[i].type,
+									  word);
+					}
 				}
 
 				g_free (word);
@@ -872,9 +898,9 @@ get_id3v24_tags (const gchar *data,
 			}
 
 			if (!tracker_is_empty_string (word)) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Audio:Comment"),
-						     tracker_escape_metadata (word));
+				tracker_statement_list_insert (metadata, uri,
+						     NIE_PREFIX "comment",
+						     word);
 			}
 
 			g_free (word);
@@ -912,30 +938,31 @@ get_id3v24_tags (const gchar *data,
 static void
 get_id3v23_tags (const gchar *data,
 		 size_t       size,
-		 GHashTable  *metadata,
+		 const gchar *uri,
+		 GPtrArray  *metadata,
 		 file_data   *filedata)
 {
 	guint	pos = 0;
 	Matches tmap[] = {
-		{"TCOP", "File:Copyright"},
-		{"TDAT", "Audio:ReleaseDate"},
-		{"TCON", "Audio:Genre"},
-		{"TIT1", "Audio:Genre"},
-		{"TENC", "DC:Publishers"},
-		{"TEXT", "Audio:Lyrics"},
-		{"TPE1", "Audio:Artist"},
-		{"TPE2", "Audio:Artist"},
-		{"TPE3", "Audio:Performer"},
-		/*	{"TOPE", "Audio:Artist"}, We don't want the original artist for now */
-		{"TPUB", "DC:Publishers"},
-		{"TOAL", "Audio:Album"},
-		{"TALB", "Audio:Album"},
-		{"TLAN", "File:Language"},
-		{"TIT2", "Audio:Title"},
-		{"TYER", "Audio:ReleaseDate"},
-		{"TRCK", "Audio:TrackNo"},
-		{"PCNT", "Audio:PlayCount"},
-		{NULL, 0},
+		{"TCOP", NIE_PREFIX "copyright", NULL, NULL, NULL},
+		{"TDAT", NIE_PREFIX "contentCreated", NULL, NULL, NULL},
+		{"TCON", NFO_PREFIX "genre", NULL, NULL, NULL},
+		{"TIT1", NFO_PREFIX "genre", NULL, NULL, NULL},
+		{"TENC", NCO_PREFIX "publisher", "publisher", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TEXT", NIE_PREFIX "plainTextContent", NULL, NULL, NULL},
+		{"TPE1", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TPE2", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TPE3", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		/*	{"TOPE", NID3_LEAD_ARTIST}, We don't want the original artist for now */
+		{"TPUB", NCO_PREFIX "publisher", "publisher", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TOAL", NIE_PREFIX "title", NULL, NULL, NULL},
+		{"TALB", NIE_PREFIX "title", NULL, NULL, NULL},
+		{"TLAN", NIE_PREFIX "language", NULL, NULL, NULL},
+		{"TIT2", NIE_PREFIX "title", NULL, NULL, NULL},
+		{"TYER", NIE_PREFIX "contentCreated", NULL, NULL, NULL},
+		{"TRCK", NMM_PREFIX "trackNumber", NULL, NULL, NULL},
+		/* TODO Nepomukify {"PCNT", "Audio:PlayCount"}, */
+		{NULL, 0, NULL, NULL, NULL},
 	};
 
 	while (pos < size) {
@@ -1038,9 +1065,17 @@ get_id3v23_tags (const gchar *data,
 						}
 					}
 
-					g_hash_table_insert (metadata,
-							     g_strdup (tmap[i].type),
-							     tracker_escape_metadata (word));
+					if (tmap[i].urn) {
+						gchar *canonical_uri = tmap[i].urn[0]!=':'?tracker_uri_printf_escaped ("urn:%s:%s", tmap[i].urn, word):g_strdup(tmap[i].urn);
+						tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, tmap[i].rdf_type);
+						tracker_statement_list_insert (metadata, canonical_uri, tmap[i].predicate, word);
+						tracker_statement_list_insert (metadata, uri, tmap[i].type, canonical_uri);
+						g_free (canonical_uri);
+					} else {
+						tracker_statement_list_insert (metadata, uri,
+									  tmap[i].type,
+									  word);
+					}
 				}
 
 				g_free (word);
@@ -1099,9 +1134,9 @@ get_id3v23_tags (const gchar *data,
 			}
 
 			if (!tracker_is_empty_string (word)) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Audio:Comment"),
-						     tracker_escape_metadata (word));
+				tracker_statement_list_insert (metadata, uri,
+						     NIE_PREFIX "comment",
+						     word);
 			}
 
 			g_free (word);
@@ -1137,37 +1172,38 @@ get_id3v23_tags (const gchar *data,
 
 static void
 get_id3v20_tags (const gchar *data,
-		 size_t	      size,
-		 GHashTable  *metadata,
+		size_t	     size,
+		const gchar *uri,
+		GPtrArray  *metadata,
 		 file_data   *filedata)
 {
 	guint	pos = 0;
 	Matches tmap[] = {
-		{"TAL", "Audio:Album"},
-		{"TT1", "Audio:Artist"},
-		{"TT2", "Audio:Title"},
-		{"TT3", "Audio:Title"},
-		{"TXT", "Audio:Comment"},
-		{"TPB", "DC:Publishers"},
-		{"WAF", "DC:Location"},
-		{"WAR", "DC:Location"},
-		{"WAS", "DC:Location"},
-		{"WAF", "DC:Location"},
-		{"WCM", "File:License"},
-		{"TYE", "Audio:ReleaseDate"},
-		{"TLA", "File:Lanuguage"},
-		{"TP1", "Audio:Artist"},
-		{"TP2", "Audio:Artist"},
-		{"TP3", "Audio:Performer"},
-		{"TEN", "Audio:Performer"},
-		{"TCO", "Audio:Genre"},
-		{"TCR", "File:Copyright"},
-		{"SLT", "Audio:Lyrics"},
-		{"TOA", "Audio:Artist"},
-		{"TOT", "Audio:Album"},
-		{"TOL", "Audio:Artist"},
-		{"COM", "Audio:Comment"},
-		{ NULL, 0},
+		{"TAL", NIE_PREFIX "musicAlbum", "album", NMM_PREFIX "MusicAlbum", NMM_PREFIX "albumTitle"},
+		{"TT1", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TT2", NIE_PREFIX "title", NULL, NULL, NULL},
+		{"TT3", NIE_PREFIX "title", NULL, NULL, NULL},
+		{"TXT", NIE_PREFIX "comment", NULL, NULL, NULL},
+		{"TPB", NCO_PREFIX "publisher", "publisher", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		/* TODO {"WAF", "DC:Location", NULL, NULL, NULL},
+		   TODO {"WAR", "DC:Location", NULL, NULL, NULL},
+		   TODO {"WAS", "DC:Location", NULL, NULL, NULL},
+		   TODO {"WAF", "DC:Location", NULL, NULL, NULL}, */
+		{"WCM", NIE_PREFIX "license", NULL, NULL, NULL},
+		{"TYE", NIE_PREFIX "contentCreated"},
+		{"TLA", NIE_PREFIX "language", NULL, NULL, NULL},
+		{"TP1", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TP2", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TP3", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TEN", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TCO", NMM_PREFIX "genre", NULL, NULL, NULL},
+		{"TCR", NIE_PREFIX "copyright", NULL, NULL, NULL},
+		{"SLT", NIE_PREFIX "plainTextContent"}, /* Lyrics */
+		{"TOA", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"TOT", NIE_PREFIX "title", NULL, NULL, NULL},
+		{"TOL", NMM_PREFIX "performer", "artist", NMM_PREFIX "Artist", NMM_PREFIX "artistName"},
+		{"COM", NIE_PREFIX "comment", NULL, NULL, NULL},
+		{ NULL, 0, NULL, NULL, NULL},
 	};
 
 	while (pos < size) {
@@ -1245,15 +1281,23 @@ get_id3v20_tags (const gchar *data,
 							g_free (word);
 							word = g_strdup (genre_names[genre]);
 						}
-						
-						if (strcasecmp (word, "unknown") == 0) {
+
+						if (strcasecmp (word, "unknown")==0) {
 							break;
 						}
-					}	
-					
-					g_hash_table_insert (metadata,
-							     g_strdup (tmap[i].type),
-							     tracker_escape_metadata (word));
+					}
+
+					if (tmap[i].urn) {
+						gchar *canonical_uri = tmap[i].urn[0]!=':'?tracker_uri_printf_escaped ("urn:%s:%s", tmap[i].urn, word):g_strdup(tmap[i].urn);
+						tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, tmap[i].rdf_type);
+						tracker_statement_list_insert (metadata, canonical_uri, tmap[i].predicate, word);
+						tracker_statement_list_insert (metadata, uri, tmap[i].type, canonical_uri);
+						g_free (canonical_uri);
+					} else {
+						tracker_statement_list_insert (metadata, uri,
+									  tmap[i].type,
+									  word);
+					}
 				} else {
 					g_free (word);
 				}
@@ -1289,7 +1333,8 @@ get_id3v20_tags (const gchar *data,
 static void
 parse_id3v24 (const gchar *data,
 	      size_t       size,
-	      GHashTable  *metadata,
+	      const gchar *uri,
+	      GPtrArray  *metadata,
 	      file_data   *filedata,
 	      size_t      *offset_delta)
 {
@@ -1340,10 +1385,10 @@ parse_id3v24 (const gchar *data,
 		gchar  *body;
 
 		un_unsync (&data[pos], tsize, (unsigned char **)&body, &unsync_size);
-		get_id3v24_tags (body, unsync_size, metadata, filedata);
+		get_id3v24_tags (body, unsync_size, uri, metadata, filedata);
 		g_free (body);
 	} else {
-		get_id3v24_tags (&data[pos], tsize, metadata, filedata);
+		get_id3v24_tags (&data[pos], tsize, uri, metadata, filedata);
 	}
 
 	*offset_delta = tsize + 10;
@@ -1352,7 +1397,8 @@ parse_id3v24 (const gchar *data,
 static void
 parse_id3v23 (const gchar *data,
 	      size_t       size,
-	      GHashTable  *metadata,
+	      const gchar *uri,
+	      GPtrArray  *metadata,
 	      file_data   *filedata,
 	      size_t      *offset_delta)
 {
@@ -1413,10 +1459,10 @@ parse_id3v23 (const gchar *data,
 		gchar  *body;
 
 		un_unsync (&data[pos], tsize, (unsigned char **)&body, &unsync_size);
-		get_id3v23_tags (body, unsync_size, metadata, filedata);
+		get_id3v23_tags (body, unsync_size, uri, metadata, filedata);
 		g_free (body);
 	} else {
-		get_id3v23_tags (&data[pos], tsize, metadata, filedata);
+		get_id3v23_tags (&data[pos], tsize, uri, metadata, filedata);
 	}
 
 	*offset_delta = tsize + 10;
@@ -1425,7 +1471,8 @@ parse_id3v23 (const gchar *data,
 static void
 parse_id3v20 (const gchar *data,
 	      size_t	      size,
-	      GHashTable  *metadata,
+	      const gchar *uri,
+	      GPtrArray  *metadata,
 	      file_data   *filedata,
 	      size_t      *offset_delta)
 {
@@ -1458,10 +1505,10 @@ parse_id3v20 (const gchar *data,
 		gchar  *body;
 
 		un_unsync (&data[pos], tsize, (unsigned char **)&body, &unsync_size);
-		get_id3v20_tags (body, unsync_size, metadata, filedata);
+		get_id3v20_tags (body, unsync_size, uri, metadata, filedata);
 		g_free (body);
 	} else {
-		get_id3v20_tags (&data[pos], tsize, metadata, filedata);
+		get_id3v20_tags (&data[pos], tsize, uri, metadata, filedata);
 	}
 
 	*offset_delta = tsize + 10;
@@ -1470,7 +1517,8 @@ parse_id3v20 (const gchar *data,
 static void
 parse_id3v2 (const gchar *data,
 	     size_t	     size,
-	     GHashTable  *metadata,
+	     const gchar *uri,
+	     GPtrArray  *metadata,
 	     file_data   *filedata)
 {
 	gboolean done = FALSE;
@@ -1478,9 +1526,9 @@ parse_id3v2 (const gchar *data,
 
 	do {
 		size_t offset_delta = 0;
-		parse_id3v24 (data+offset, size-offset, metadata, filedata, &offset_delta);
-		parse_id3v23 (data+offset, size-offset, metadata, filedata, &offset_delta);
-		parse_id3v20 (data+offset, size-offset, metadata, filedata, &offset_delta);		
+		parse_id3v24 (data+offset, size-offset, uri, metadata, filedata, &offset_delta);
+		parse_id3v23 (data+offset, size-offset, uri, metadata, filedata, &offset_delta);
+		parse_id3v20 (data+offset, size-offset, uri, metadata, filedata, &offset_delta);		
 
 		if (offset_delta == 0) {
 			done = TRUE;
@@ -1493,9 +1541,10 @@ parse_id3v2 (const gchar *data,
 }
 
 static void
-extract_mp3 (const gchar *filename,
-	     GHashTable  *metadata)
+extract_mp3 (const gchar *uri,
+	     GPtrArray  *metadata)
 {
+	gchar       *filename;
 	int	     fd;
 	void	    *buffer;
 	goffset      size;
@@ -1514,9 +1563,12 @@ extract_mp3 (const gchar *filename,
 	filedata.albumartdata = NULL;
 	filedata.albumartsize = 0;
 
+	filename = g_filename_from_uri (uri, NULL, NULL);
+
 	size = tracker_file_get_size (filename);
 
 	if (size == 0 || size > MAX_FILE_READ) {
+		g_free (filename);
 		return;
 	}
 
@@ -1553,6 +1605,7 @@ extract_mp3 (const gchar *filename,
 	close (fd);
 
 	if (buffer == NULL || buffer == (void*) -1) {
+		g_free (filename);
 		return;
 	}
 
@@ -1560,46 +1613,54 @@ extract_mp3 (const gchar *filename,
 		/* Do nothing? */
 	}
 
+	tracker_statement_list_insert (metadata, uri, 
+	                          RDF_TYPE, 
+	                          NMM_PREFIX "MusicPiece");
+
 	if (!tracker_is_empty_string (info.title)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:Title"),
-				     tracker_escape_metadata (info.title));
+		tracker_statement_list_insert (metadata, uri,
+				     NIE_PREFIX "title",
+				     info.title);
 	}
 
 	if (!tracker_is_empty_string (info.artist)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:Artist"),
-				     tracker_escape_metadata (info.artist));
+		gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", info.artist);
+		tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "Artist");
+		tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "artistName", info.artist);
+		tracker_statement_list_insert (metadata, uri, NMM_PREFIX "performer", canonical_uri);
+		g_free (canonical_uri);
 	}
 
 	if (!tracker_is_empty_string (info.album)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:Album"),
-				     tracker_escape_metadata (info.album));
+		gchar *canonical_uri = tracker_uri_printf_escaped ("urn:album:%s", info.album);
+		tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "MusicAlbum");
+		tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "albumTitle", info.album);
+		tracker_statement_list_insert (metadata, uri, NMM_PREFIX "musicAlbum", canonical_uri);
+		g_free (canonical_uri);
 	}
 
 	if (!tracker_is_empty_string (info.year)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:ReleaseDate"),
-				     tracker_escape_metadata (info.year));
+		tracker_statement_list_insert (metadata, uri,
+				     NIE_PREFIX "contentCreated",
+				     info.year);
 	}
 
 	if (!tracker_is_empty_string (info.genre)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:Genre"),
-				     tracker_escape_metadata (info.genre));
+		tracker_statement_list_insert (metadata, uri,
+				     NFO_PREFIX "genre",
+				     info.genre);
 	}
 
 	if (!tracker_is_empty_string (info.comment)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:Comment"),
-				     tracker_escape_metadata (info.comment));
+		tracker_statement_list_insert (metadata, uri,
+				     NIE_PREFIX "comment",
+				     info.comment);
 	}
 
 	if (!tracker_is_empty_string (info.trackno)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:TrackNo"),
-				     tracker_escape_metadata (info.trackno));		
+		tracker_statement_list_insert (metadata, uri,
+				     NMM_PREFIX "trackNumber",
+				     info.trackno);
 	}
 
 	g_free (info.title);
@@ -1611,22 +1672,21 @@ extract_mp3 (const gchar *filename,
 	g_free (info.genre);
 
 	/* Get other embedded tags */
-	parse_id3v2 (buffer, size, metadata, &filedata);
+	parse_id3v2 (buffer, size, uri, metadata, &filedata);
 
 	/* Get mp3 stream info */
-	mp3_parse (buffer, size, metadata, &filedata);
+	mp3_parse (buffer, size, uri, metadata, &filedata);
 
+	/* TODO */
 #ifdef HAVE_GDKPIXBUF
 	tracker_process_albumart (filedata.albumartdata, filedata.albumartsize,
-				  /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
-				  g_hash_table_lookup (metadata, "Audio:Album"),
-				  g_hash_table_lookup (metadata, "Audio:AlbumTrackCount"),
+				  /* tracker_statement_list_find (metadata, NMM_PREFIX "performer") */ NULL,
+				  tracker_statement_list_find (metadata, uri, NIE_PREFIX "title"), "-1",
 				  filename);
 #else
 	tracker_process_albumart (NULL, 0,
-				  /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
-				  g_hash_table_lookup (metadata, "Audio:Album"),
-				  g_hash_table_lookup (metadata, "Audio:AlbumTrackCount"),
+				  /* tracker_statement_list_find (metadata, NMM_PREFIX "performer") */ NULL,
+				  tracker_statement_list_find (metadata, uri, NIE_PREFIX "title"), "-1",
 				  filename);
 
 #endif /* HAVE_GDKPIXBUF */
@@ -1635,27 +1695,10 @@ extract_mp3 (const gchar *filename,
 		g_free (filedata.albumartdata);
 	}
 
-	/* Check that we have the minimum data. FIXME We should not need to do this */
-	if (!g_hash_table_lookup (metadata, "Audio:Title")) {
-		gchar  *basename = g_filename_display_basename (filename);
-		gchar **parts    = g_strsplit (basename, ".", -1);
-		gchar  *title    = g_strdup (parts[0]);
-		
-		g_strfreev (parts);
-		g_free (basename);
-		
-		title = g_strdelimit (title, "_", ' ');
-		
-		g_hash_table_insert (metadata,
-				     g_strdup ("Audio:Title"),
-				     tracker_escape_metadata (title));
-
-		g_free (title);
-	}
-
 #ifndef G_OS_WIN32
 	munmap (buffer, size);
 #endif
+	g_free (filename);
 }
 
 TrackerExtractData *
diff --git a/src/tracker-extract/tracker-extract-mplayer.c b/src/tracker-extract/tracker-extract-mplayer.c
index 7b657f8..a017dcf 100644
--- a/src/tracker-extract/tracker-extract-mplayer.c
+++ b/src/tracker-extract/tracker-extract-mplayer.c
@@ -26,34 +26,44 @@
 
 #include <glib.h>
 
+#include <libtracker-common/tracker-ontology.h>
 #include <libtracker-common/tracker-os-dependant.h>
+#include <libtracker-common/tracker-statement-list.h>
 
 #include "tracker-main.h"
-#include "tracker-escape.h"
 
-static void extract_mplayer (const gchar *filename,
-			     GHashTable  *metadata);
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
 
-static TrackerExtractData data[] = {
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+static void extract_mplayer (const gchar *uri,
+			     GPtrArray   *metadata);
+
+static TrackerExtractData extract_data[] = {
 	{ "audio/*", extract_mplayer },
 	{ "video/*", extract_mplayer },
 	{ NULL, NULL }
 };
 
-static gchar *video_tags[][2] = {
-	{ "ID_VIDEO_HEIGHT",	"Video:Height"		},
-	{ "ID_VIDEO_WIDTH",	"Video:Width"		},
-	{ "ID_VIDEO_FPS",	"Video:FrameRate"	},
-	{ "ID_VIDEO_CODEC",	"Video:Codec"		},
-	{ "ID_VIDEO_BITRATE",	"Video:Bitrate"		},
+static const gchar *video_tags[][2] = {
+	{ "ID_VIDEO_HEIGHT",	NFO_PREFIX "height"	},
+	{ "ID_VIDEO_WIDTH",	NFO_PREFIX "width"	},
+	{ "ID_VIDEO_FPS",	NFO_PREFIX "frameRate"	},
+	{ "ID_VIDEO_CODEC",	NFO_PREFIX "codec"	},
+	{ "ID_VIDEO_BITRATE",	NFO_PREFIX "averageBitrate" },
 	{ NULL,			NULL			}
 };
 
-static gchar *audio_tags[][2] = {
-	{ "ID_AUDIO_BITRATE",	"Audio:Bitrate"		},
-	{ "ID_AUDIO_RATE",	"Audio:Samplerate"	},
-	{ "ID_AUDIO_CODEC",	"Audio:Codec"		},
-	{ "ID_AUDIO_NCH",	"Audio:Channels"	},
+static const gchar *audio_tags[][2] = {
+	{ "ID_AUDIO_BITRATE",	NFO_PREFIX "averageBitrate" },
+	{ "ID_AUDIO_RATE",	NFO_PREFIX "sampleRate"	},
+	{ "ID_AUDIO_CODEC",	NFO_PREFIX "codec"	},
+	{ "ID_AUDIO_NCH",	NFO_PREFIX "channels"	},
 	{ NULL,			NULL			}
 };
 
@@ -63,31 +73,44 @@ static gchar *audio_tags[][2] = {
  * 3/ tag can belong to audio and video. If current media has video we will associate
  *    tag to Video, otherwise to Audio if it has audio.
  */
-static gchar *info_tags[][3] = {
-	{ "Comment",		"Audio:Comment",	"Video:Comment"	},
-	{ "Title",		"Audio:Title",		"Video:Title"	},
-	{ "Genre",		"Audio:Genre",		NULL		},
-	{ "Track",		"Audio:TrackNo",	NULL		},
-	{ "Artist",		"Audio:Performer",	"Video:Author"	},
-	{ "Album",		"Audio:Album",		NULL		},
-	{ "Year",		"Audio:ReleaseDate",	NULL		},
-	{ "copyright",		"File:Copyright",	NULL		},
+static const gchar *info_tags[][3] = {
+	{ "Comment",		NIE_PREFIX "comment",	NIE_PREFIX "comment"	},
+	{ "Title",		NIE_PREFIX "title",	NIE_PREFIX "title"	},
+	{ "Genre",		NFO_PREFIX "genre",	NFO_PREFIX "genre"	},
+	{ "Track",		NMM_PREFIX "trackNumber", NMM_PREFIX "trackNumber" },
+	{ "Artist",		NMM_PREFIX "performer",	NMM_PREFIX "performer"	},
+	{ "Album",		NIE_PREFIX "title",	NIE_PREFIX "title"	},
+	{ "Year",		NIE_PREFIX "contentCreated", NIE_PREFIX "contentCreated" },
+	{ "copyright",		NIE_PREFIX "copyright", NIE_PREFIX "copyright"	},
 	{ NULL,			NULL,			NULL		}
 };
 
+typedef struct {
+	GPtrArray *metadata;
+	const gchar *uri;
+} ForeachCopyInfo;
+
 static void
 copy_hash_table_entry (gpointer key,
 		       gpointer value,
 		       gpointer user_data)
 {
-	g_hash_table_insert (user_data,
-			     g_strdup (key),
-			     tracker_escape_metadata (value));
+	ForeachCopyInfo *info = user_data;
+
+	if (g_strcmp0 (key, NMM_PREFIX "performer") == 0) {
+		gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", value);
+		tracker_statement_list_insert (info->metadata, canonical_uri, RDF_TYPE, NCO_PREFIX "Contact");
+		tracker_statement_list_insert (info->metadata, canonical_uri, NCO_PREFIX "fullname", value);
+		tracker_statement_list_insert (info->metadata, info->uri, key, canonical_uri);
+		g_free (canonical_uri);
+	} else {
+		tracker_statement_list_insert (info->metadata, info->uri, key, value);
+	}
 }
 
 static void
-extract_mplayer (const gchar *filename,
-		 GHashTable  *metadata)
+extract_mplayer (const gchar *uri,
+		 GPtrArray  *metadata)
 {
 	gchar *argv[10];
 	gchar *mplayer;
@@ -100,7 +123,7 @@ extract_mplayer (const gchar *filename,
 	argv[5] = g_strdup ("null");
 	argv[6] = g_strdup ("-ao");
 	argv[7] = g_strdup ("null");
-	argv[8] = g_strdup (filename);
+	argv[8] = g_filename_from_uri (uri, NULL, NULL);
 	argv[9] = NULL;
 
 	if (tracker_spawn (argv, 10, &mplayer, NULL)) {
@@ -148,9 +171,9 @@ extract_mplayer (const gchar *filename,
 
 				for (i = 0; audio_tags[i][0]; i++) {
 					if (g_str_has_prefix (*line, audio_tags[i][0])) {
-						g_hash_table_insert (metadata,
-								     g_strdup (audio_tags[i][1]),
-								     tracker_escape_metadata ((*line) + strlen (audio_tags[i][0]) + 1));
+						tracker_statement_list_insert (metadata, uri,
+								     audio_tags[i][1],
+								     (*line) + strlen (audio_tags[i][0]) + 1);
 						break;
 					}
 				}
@@ -161,9 +184,9 @@ extract_mplayer (const gchar *filename,
 
 				for (i = 0; video_tags[i][0]; i++) {
 					if (g_str_has_prefix (*line, video_tags[i][0])) {
-						g_hash_table_insert (metadata,
-								     g_strdup (video_tags[i][1]),
-								     tracker_escape_metadata ((*line) + strlen (video_tags[i][0]) + 1));
+						tracker_statement_list_insert (metadata, uri,
+								     video_tags[i][1],
+								     (*line) + strlen (video_tags[i][0]) + 1);
 						break;
 					}
 				}
@@ -229,33 +252,52 @@ extract_mplayer (const gchar *filename,
 		g_pattern_spec_free (pattern_ID_LENGTH);
 
 		if (has_video) {
+
+			tracker_statement_list_insert (metadata, uri, 
+			                          RDF_TYPE, 
+			                          NMM_PREFIX "Video");
+
 			if (tmp_metadata_video) {
+				ForeachCopyInfo info = { metadata, uri };
 				g_hash_table_foreach (tmp_metadata_video, 
 						      copy_hash_table_entry, 
-						      metadata);
+						      &info);
 				g_hash_table_destroy (tmp_metadata_video);
 			}
 
 			if (duration) {
-				g_hash_table_insert (metadata, g_strdup ("Video:Duration"), duration);
+				tracker_statement_list_insert (metadata, uri, NFO_PREFIX "duration", duration);
+				g_free (duration);
 			}
 		} else if (has_audio) {
+
+			tracker_statement_list_insert (metadata, uri, 
+			                          RDF_TYPE, 
+			                          NMM_PREFIX "MusicPiece");
+
 			if (tmp_metadata_video) {
+				ForeachCopyInfo info = { metadata, uri };
 				g_hash_table_foreach (tmp_metadata_audio, 
 						      copy_hash_table_entry, 
-						      metadata);
+						      &info);
 				g_hash_table_destroy (tmp_metadata_audio);
 			}
 
 			if (duration) {
-				g_hash_table_insert (metadata, g_strdup ("Audio:Duration"), duration);
+				tracker_statement_list_insert (metadata, uri, NFO_PREFIX "duration", duration);
+				g_free (duration);
 			}
+		} else {
+			tracker_statement_list_insert (metadata, uri, 
+			                          RDF_TYPE, 
+			                          NFO_PREFIX "FileDataObject");
 		}
+
 	}
 }
 
 TrackerExtractData *
 tracker_get_extract_data (void)
 {
-	return data;
+	return extract_data;
 }
diff --git a/src/tracker-extract/tracker-extract-msoffice.c b/src/tracker-extract/tracker-extract-msoffice.c
index 62d92cd..79ef38d 100644
--- a/src/tracker-extract/tracker-extract-msoffice.c
+++ b/src/tracker-extract/tracker-extract-msoffice.c
@@ -36,10 +36,20 @@
 
 #include <libtracker-common/tracker-utils.h>
 
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
+
 #include "tracker-main.h"
 
-static void extract_msoffice (const gchar *filename,
-			      GHashTable  *metadata);
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+static void extract_msoffice (const gchar *uri,
+			      GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 	{ "application/msword",	  extract_msoffice },
@@ -47,10 +57,19 @@ static TrackerExtractData data[] = {
 	{ NULL, NULL }
 };
 
+typedef struct {
+	GPtrArray *metadata;
+	const gchar *uri;
+} ForeachInfo;
+
 static void
-add_gvalue_in_hash_table (GHashTable   *table,
-			  const gchar  *key,
-			  GValue const *val)
+add_gvalue_in_metadata (GPtrArray    *table,
+			const gchar  *uri,
+			const gchar  *key,
+			GValue const *val,
+			const gchar *urn,
+			const gchar *type,
+			const gchar *predicate)
 {
 	g_return_if_fail (table != NULL);
 	g_return_if_fail (key != NULL);
@@ -91,8 +110,13 @@ add_gvalue_in_hash_table (GHashTable   *table,
 				}
 
 				if (str_val) {
-					g_hash_table_insert (table, g_strdup (key),
-							     tracker_escape_metadata (str_val));
+					if (urn) {
+						tracker_statement_list_insert (table, urn, RDF_TYPE, type);
+						tracker_statement_list_insert (table, urn, predicate, str_val);
+						tracker_statement_list_insert (table, uri, key, urn);
+					} else {
+						tracker_statement_list_insert (table, uri, key, str_val);
+					}
 					g_free (str_val);
 				}
 			}
@@ -107,10 +131,12 @@ metadata_cb (gpointer key,
 	     gpointer value,
 	     gpointer user_data)
 {
+	ForeachInfo  *info = user_data;
 	gchar	     *name;
 	GsfDocProp   *property;
-	GHashTable   *metadata;
+	GPtrArray    *metadata = info->metadata;
 	GValue const *val;
+	const gchar  *uri = info->uri;
 
 	name = key;
 	property = value;
@@ -118,23 +144,41 @@ metadata_cb (gpointer key,
 	val = gsf_doc_prop_get_val (property);
 
 	if (strcmp (name, "dc:title") == 0) {
-		add_gvalue_in_hash_table (metadata, "Doc:Title", val);
+		add_gvalue_in_metadata (metadata, uri, NIE_PREFIX "title", val, NULL, NULL, NULL);
 	} else if (strcmp (name, "dc:subject") == 0) {
-		add_gvalue_in_hash_table (metadata, "Doc:Subject", val);
+		add_gvalue_in_metadata (metadata, uri, NIE_PREFIX "subject", val, NULL, NULL, NULL);
 	} else if (strcmp (name, "dc:creator") == 0) {
-		add_gvalue_in_hash_table (metadata, "Doc:Author", val);
+		add_gvalue_in_metadata (metadata, uri, NCO_PREFIX "creator", val, ":", NCO_PREFIX "Contact", NCO_PREFIX "fullname");
 	} else if (strcmp (name, "dc:keywords") == 0) {
-		add_gvalue_in_hash_table (metadata, "Doc:Keywords", val);
+		gchar *keywords = g_strdup_value_contents (val);
+		char *lasts, *keyw;
+		size_t len;
+
+		keywords = strchr (keywords, '"');
+		if (keywords)
+			keywords++;
+		len = strlen (keywords);
+		if (keywords[len - 1] == '"')
+			keywords[len - 1] = '\0';
+
+		for (keyw = strtok_r (keywords, ",; ", &lasts); keyw; 
+		     keyw = strtok_r (NULL, ",; ", &lasts)) {
+			tracker_statement_list_insert (metadata,
+					  uri, NIE_PREFIX "keyword",
+					  (const gchar*) keyw);
+		}
+
+		g_free (keywords);
 	} else if (strcmp (name, "dc:description") == 0) {
-		add_gvalue_in_hash_table (metadata, "Doc:Comments", val);
+		add_gvalue_in_metadata (metadata, uri, NIE_PREFIX "comment", val, NULL, NULL, NULL);
 	} else if (strcmp (name, "gsf:page-count") == 0) {
-		add_gvalue_in_hash_table (metadata, "Doc:PageCount", val);
+		add_gvalue_in_metadata (metadata, uri, NFO_PREFIX "pageCount", val, NULL, NULL, NULL);
 	} else if (strcmp (name, "gsf:word-count") == 0) {
-		add_gvalue_in_hash_table (metadata, "Doc:WordCount", val);
+		add_gvalue_in_metadata (metadata, uri, NFO_PREFIX "wordCount", val, NULL, NULL, NULL);
 	} else if (strcmp (name, "meta:creation-date") == 0) {
-		add_gvalue_in_hash_table (metadata, "Doc:Created", val);
+		add_gvalue_in_metadata (metadata, uri, NIE_PREFIX "contentCreated", val, NULL, NULL, NULL);
 	} else if (strcmp (name, "meta:generator") == 0) {
-		add_gvalue_in_hash_table (metadata, "File:Other", val);
+		add_gvalue_in_metadata (metadata, uri, NIE_PREFIX "generator", val, NULL, NULL, NULL);
 	}
 }
 
@@ -143,10 +187,12 @@ doc_metadata_cb (gpointer key,
 		 gpointer value,
 		 gpointer user_data)
 {
+	ForeachInfo  *info = user_data;
 	gchar	     *name;
 	GsfDocProp   *property;
-	GHashTable   *metadata;
+	GPtrArray    *metadata = info->metadata;
 	GValue const *val;
+	const gchar  *uri = info->uri;
 
 	name = key;
 	property = value;
@@ -154,23 +200,28 @@ doc_metadata_cb (gpointer key,
 	val = gsf_doc_prop_get_val (property);
 
 	if (strcmp (name, "CreativeCommons_LicenseURL") == 0) {
-		add_gvalue_in_hash_table (metadata, "File:License", val);
+		add_gvalue_in_metadata (metadata, uri, NIE_PREFIX "license", val, NULL, NULL, NULL);
 	}
 }
 
 static void
-extract_msoffice (const gchar *filename,
-		  GHashTable  *metadata)
+extract_msoffice (const gchar *uri,
+		  GPtrArray   *metadata)
 {
 	GsfInput  *input;
 	GsfInfile *infile;
 	GsfInput  *stream;
+	gchar     *filename;
+	gboolean   rdf_type_added = FALSE;
 
 	gsf_init ();
 
+	filename = g_filename_from_uri (uri, NULL, NULL);
+
 	input = gsf_input_stdio_new (filename, NULL);
 
 	if (!input) {
+		g_free (filename);
 		gsf_shutdown ();
 		return;
 	}
@@ -179,6 +230,7 @@ extract_msoffice (const gchar *filename,
 	g_object_unref (G_OBJECT (input));
 
 	if (!infile) {
+		g_free (filename);
 		gsf_shutdown ();
 		return;
 	}
@@ -186,38 +238,59 @@ extract_msoffice (const gchar *filename,
 	stream = gsf_infile_child_by_name (infile, "\05SummaryInformation");
 	if (stream) {
 		GsfDocMetaData *md;
+		ForeachInfo info = { metadata, uri };
 
 		md = gsf_doc_meta_data_new ();
 
 		if (gsf_msole_metadata_read (stream, md)) {
+			g_object_unref (md);
+			g_object_unref (stream);
+			g_free (filename);
 			gsf_shutdown ();
 			return;
 		}
 
-		gsf_doc_meta_data_foreach (md, metadata_cb, metadata);
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "Document");
+
+		rdf_type_added = TRUE;
 
-		g_object_unref (G_OBJECT (md));
-		g_object_unref (G_OBJECT (stream));
+		gsf_doc_meta_data_foreach (md, metadata_cb, &info);
+
+		g_object_unref (md);
+		g_object_unref (stream);
 	}
 
 	stream = gsf_infile_child_by_name (infile, "\05DocumentSummaryInformation");
 	if (stream) {
 		GsfDocMetaData *md;
+		ForeachInfo info = { metadata, uri };
 
 		md = gsf_doc_meta_data_new ();
 
 		if (gsf_msole_metadata_read (stream, md)) {
+			g_object_unref (md);
+			g_object_unref (stream);
 			gsf_shutdown ();
+			g_free (filename);
 			return;
 		}
 
-		gsf_doc_meta_data_foreach (md, doc_metadata_cb, metadata);
+		if (!rdf_type_added) {
+			tracker_statement_list_insert (metadata, uri, 
+			                          RDF_TYPE, 
+			                          NFO_PREFIX "Document");
+			rdf_type_added = TRUE;
+		}
+
+		gsf_doc_meta_data_foreach (md, doc_metadata_cb, &info);
 
-		g_object_unref (G_OBJECT (md));
-		g_object_unref (G_OBJECT (stream));
+		g_object_unref (md);
+		g_object_unref (stream);
 	}
 
-	g_object_unref (G_OBJECT (infile));
+	g_object_unref (infile);
 
 	gsf_shutdown ();
 }
diff --git a/src/tracker-extract/tracker-extract-oasis.c b/src/tracker-extract/tracker-extract-oasis.c
index eb157db..0e5b72e 100644
--- a/src/tracker-extract/tracker-extract-oasis.c
+++ b/src/tracker-extract/tracker-extract-oasis.c
@@ -25,9 +25,17 @@
 #include <glib.h>
 
 #include <libtracker-common/tracker-os-dependant.h>
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
 
 #include "tracker-main.h"
-#include "tracker-escape.h"
+
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
 
 typedef enum {
 	READ_TITLE,
@@ -37,12 +45,13 @@ typedef enum {
 	READ_COMMENTS,
 	READ_STATS,
 	READ_CREATED,
-	READ_FILE_OTHER
+	READ_GENERATOR
 } tag_type;
 
 typedef struct {
-	GHashTable *metadata;
+	GPtrArray *metadata;
 	tag_type current;
+	const gchar *uri;
 } ODTParseInfo;
 
 static void start_element_handler (GMarkupParseContext	*context,
@@ -61,7 +70,7 @@ static void text_handler	  (GMarkupParseContext	*context,
 				   gpointer		 user_data,
 				   GError	       **error);
 static void extract_oasis	  (const gchar		*filename,
-				   GHashTable		*metadata);
+				   GPtrArray		*metadata);
 
 static TrackerExtractData extract_data[] = {
 	{ "application/vnd.oasis.opendocument.*", extract_oasis },
@@ -69,19 +78,21 @@ static TrackerExtractData extract_data[] = {
 };
 
 static void
-extract_oasis (const gchar *filename,
-	       GHashTable  *metadata)
+extract_oasis (const gchar *uri,
+	       GPtrArray   *metadata)
 {
 	gchar	      *argv[5];
 	gchar	      *xml;
+	gchar *filename = g_filename_from_uri (uri, NULL, NULL);
 	ODTParseInfo   info = {
 		metadata,
-		-1
+		-1,
+		uri
 	};
 
 	argv[0] = g_strdup ("unzip");
 	argv[1] = g_strdup ("-p");
-	argv[2] = g_strdup (filename);
+	argv[2] = filename;
 	argv[3] = g_strdup ("meta.xml");
 	argv[4] = NULL;
 
@@ -95,6 +106,10 @@ extract_oasis (const gchar *filename,
 			NULL
 		};
 
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "Document");
+
 		context = g_markup_parse_context_new (&parser, 0, &info, NULL);
 		g_markup_parse_context_parse (context, xml, -1, NULL);
 
@@ -103,9 +118,10 @@ extract_oasis (const gchar *filename,
 	}
 
 	g_free (argv[3]);
-	g_free (argv[2]);
 	g_free (argv[1]);
 	g_free (argv[0]);
+
+	g_free (filename);
 }
 
 void
@@ -134,21 +150,23 @@ start_element_handler (GMarkupParseContext  *context,
 		data->current = READ_COMMENTS;
 	}
 	else if (strcmp (element_name, "meta:document-statistic") == 0) {
-		GHashTable *metadata;
+		GPtrArray *metadata;
+		const gchar *uri;
 		const gchar **a, **v;
 
 		metadata = data->metadata;
+		uri = data->uri;
 
 		for (a = attribute_names, v = attribute_values; *a; ++a, ++v) {
 			if (strcmp (*a, "meta:word-count") == 0) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:WordCount"),
-						     tracker_escape_metadata (*v));
+				tracker_statement_list_insert (metadata, uri,
+							  NFO_PREFIX "wordCount",
+							  *v);
 			}
 			else if (strcmp (*a, "meta:page-count") == 0) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:PageCount"),
-						     tracker_escape_metadata (*v));
+				tracker_statement_list_insert (metadata, uri,
+							  NFO_PREFIX "pageCount",
+							  *v);
 			}
 		}
 
@@ -158,7 +176,7 @@ start_element_handler (GMarkupParseContext  *context,
 		data->current = READ_CREATED;
 	}
 	else if (strcmp (element_name, "meta:generator") == 0) {
-		data->current = READ_FILE_OTHER;
+		data->current = READ_GENERATOR;
 	}
 	else {
 		data->current = -1;
@@ -182,59 +200,55 @@ text_handler (GMarkupParseContext  *context,
 	      GError		  **error)
 {
 	ODTParseInfo *data;
-	GHashTable   *metadata;
+	GPtrArray    *metadata;
+	const gchar        *uri;
 
 	data = user_data;
 	metadata = data->metadata;
+	uri = data->uri;
 
 	switch (data->current) {
 	case READ_TITLE:
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Title"),
-				     tracker_escape_metadata (text));
+		tracker_statement_list_insert (metadata, uri,
+					  NIE_PREFIX "title",
+					  text);
 		break;
 	case READ_SUBJECT:
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Subject"),
-				     tracker_escape_metadata (text));
+		tracker_statement_list_insert (metadata, uri,
+					  NIE_PREFIX "subject",
+					  text);
 		break;
 	case READ_AUTHOR:
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Author"),
-				     tracker_escape_metadata (text));
+		tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+		tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", text);
+		tracker_statement_list_insert (metadata, uri, NCO_PREFIX "creator", ":");
 		break;
 	case READ_KEYWORDS: {
-		gchar *keywords;
-
-		if ((keywords = g_hash_table_lookup (metadata, "Doc:Keywords"))) {
-			gchar *escaped;
-
-			escaped = tracker_escape_metadata (text);
-			g_hash_table_replace (metadata,
-					      g_strdup ("Doc:Keywords"),
-					      g_strconcat (keywords, ",", escaped, NULL));
-			g_free (escaped);
-		} else {
-			g_hash_table_insert (metadata,
-					     g_strdup ("Doc:Keywords"),
-					     tracker_escape_metadata (text));
+		gchar *keywords = g_strdup (text);
+		char *lasts, *keyw;
+		for (keyw = strtok_r (keywords, ",; ", &lasts); keyw; 
+		     keyw = strtok_r (NULL, ",; ", &lasts)) {
+			tracker_statement_list_insert (metadata,
+					  uri, NIE_PREFIX "keyword",
+					  (const gchar*) keyw);
 		}
+		g_free (keywords);
 	}
 		break;
 	case READ_COMMENTS:
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Comments"),
-				     tracker_escape_metadata (text));
+		tracker_statement_list_insert (metadata, uri,
+					  NIE_PREFIX "comment",
+					  text);
 		break;
 	case READ_CREATED:
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Created"),
-				     tracker_escape_metadata (text));
+		tracker_statement_list_insert (metadata, uri,
+					  NIE_PREFIX "contentCreated",
+					  text);
 		break;
-	case READ_FILE_OTHER:
-		g_hash_table_insert (metadata,
-				     g_strdup ("File:Other"),
-				     tracker_escape_metadata (text));
+	case READ_GENERATOR:
+		tracker_statement_list_insert (metadata, uri,
+					  NIE_PREFIX "generator",
+					  text);
 		break;
 
 	default:
diff --git a/src/tracker-extract/tracker-extract-pdf.c b/src/tracker-extract/tracker-extract-pdf.c
index 099cabf..dae5061 100644
--- a/src/tracker-extract/tracker-extract-pdf.c
+++ b/src/tracker-extract/tracker-extract-pdf.c
@@ -26,14 +26,25 @@
 
 #include <glib.h>
 
+#include <libtracker-common/tracker-statement-list.h>
+
 #include "tracker-main.h"
 #include "tracker-xmp.h"
 
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-type-utils.h>
 #include <libtracker-common/tracker-utils.h>
 #include <libtracker-common/tracker-type-utils.h>
 
-static void extract_pdf (const gchar *filename,
-			 GHashTable  *metadata);
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+static void extract_pdf (const gchar *uri,
+			 GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 	{ "application/pdf", extract_pdf },
@@ -41,11 +52,10 @@ static TrackerExtractData data[] = {
 };
 
 static void
-extract_pdf (const gchar *filename,
-	     GHashTable  *metadata)
+extract_pdf (const gchar *uri,
+	     GPtrArray  *metadata)
 {
 	PopplerDocument *document;
-	gchar		*tmp;
 	gchar		*title		= NULL;
 	gchar		*author		= NULL;
 	gchar		*subject	= NULL;
@@ -53,17 +63,21 @@ extract_pdf (const gchar *filename,
 	gchar		*metadata_xml	= NULL;
 	GTime		 creation_date;
 	GError		*error		= NULL;
+	gchar           *filename = g_filename_from_uri (uri, NULL, NULL);
 
 	g_type_init ();
 
-	tmp = g_strconcat ("file://", filename, NULL);
-	document = poppler_document_new_from_file (tmp, NULL, &error);
-	g_free (tmp);
+	document = poppler_document_new_from_file (filename, NULL, &error);
 
 	if (document == NULL || error) {
+		g_free (filename);
 		return;
 	}
 
+	tracker_statement_list_insert (metadata, uri, 
+	                          RDF_TYPE, 
+	                          NFO_PREFIX "Document");
+
 	g_object_get (document,
 		      "title", &title,
 		      "author", &author,
@@ -78,38 +92,48 @@ extract_pdf (const gchar *filename,
 	}
 
 	if (!tracker_is_empty_string (title)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Title"),
-				     tracker_escape_metadata (title));
+		tracker_statement_list_insert (metadata, uri,
+					  NIE_PREFIX "title",
+					  title);
 	}
 	if (!tracker_is_empty_string (author)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Author"),
-				     tracker_escape_metadata (author));
+
+		tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+		tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", author);
+		tracker_statement_list_insert (metadata, uri, NCO_PREFIX "creator", ":");
+
 	}
 	if (!tracker_is_empty_string (subject)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Subject"),
-				     tracker_escape_metadata (subject));
+		tracker_statement_list_insert (metadata, uri,
+					  NIE_PREFIX "subject",
+					  subject);
 	}
+
 	if (!tracker_is_empty_string (keywords)) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Keywords"),
-				     tracker_escape_metadata (keywords));
+		char *lasts, *keyw;
+
+		for (keyw = strtok_r (keywords, ",;", &lasts); keyw; 
+		     keyw = strtok_r (NULL, ",;", &lasts)) {
+			tracker_statement_list_insert (metadata,
+					  uri, NIE_PREFIX "keyword",
+					  (const gchar*) keyw);
+		}
 	}
 
 	if (creation_date > 0) {
-		g_hash_table_insert (metadata,
-				     g_strdup ("Doc:Created"),
-				     tracker_date_to_string ((time_t) creation_date));
+		gchar *date_string = tracker_date_to_string ((time_t) creation_date);
+		tracker_statement_list_insert (metadata, uri,
+				          NIE_PREFIX "created",
+				          date_string);
+		g_free (date_string);
 	}
 
-	g_hash_table_insert (metadata,
-			     g_strdup ("Doc:PageCount"),
-			     tracker_escape_metadata_printf ("%d", poppler_document_get_n_pages (document)));
+	tracker_statement_list_insert_with_int (metadata, uri,
+					   NFO_PREFIX "pageCount",
+					   poppler_document_get_n_pages (document));
 
 	if ( metadata_xml ) {
-		tracker_read_xmp (metadata_xml, strlen (metadata_xml), metadata);
+		tracker_read_xmp (metadata_xml, strlen (metadata_xml), uri, metadata);
 	}
 
 	g_free (title);
@@ -119,6 +143,7 @@ extract_pdf (const gchar *filename,
 	g_free (metadata_xml);
 
 	g_object_unref (document);
+	g_free (filename);
 }
 
 TrackerExtractData *
diff --git a/src/tracker-extract/tracker-extract-playlist.c b/src/tracker-extract/tracker-extract-playlist.c
index 3ec6792..2ceb702 100644
--- a/src/tracker-extract/tracker-extract-playlist.c
+++ b/src/tracker-extract/tracker-extract-playlist.c
@@ -32,6 +32,9 @@
 #include <gio/gio.h>
 
 #include <totem-pl-parser.h>
+#include <libtracker-common/tracker-statement-list.h>
+
+#include <libtracker-common/tracker-ontology.h>
 
 #include "tracker-main.h"
 
@@ -42,16 +45,23 @@
 #define PLAYLIST_DEFAULT_NO_TRACKS 0
 #define PLAYLIST_DEFAULT_DURATION 0 
 
+
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
 typedef struct {
-	gint        track_counter;
-	gint        total_time;
+	gint         track_counter;
+	gint         total_time;
+	GPtrArray   *metadata;
+	const gchar *uri;
 } PlaylistMetadata;
 
-static void extract_playlist (const gchar *filename,
-			      GHashTable  *metadata);
+static void extract_playlist (const gchar *uri,
+			      GPtrArray   *metadata);
 
 
-static TrackerExtractData data[] = {
+static TrackerExtractData playlist_data[] = {
 	{ "audio/x-mpegurl", extract_playlist },
 	{ "audio/mpegurl", extract_playlist },
 	{ "audio/x-scpls", extract_playlist },
@@ -64,19 +74,23 @@ static TrackerExtractData data[] = {
 };
 
 static void
-entry_parsed (TotemPlParser *parser, const gchar *uri, GHashTable *metadata, gpointer user_data)
+entry_parsed (TotemPlParser *parser, const gchar *to_uri, GHashTable *to_metadata, gpointer user_data)
 {
 	gchar *duration;
 	PlaylistMetadata *data;
 
 	data = (PlaylistMetadata *)user_data;
 
+	tracker_statement_list_insert (data->metadata, data->uri,
+				  NFO_PREFIX "hasMediaFileListEntry", 
+				  to_uri);
+
 	data->track_counter += 1;
 
-	duration = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_DURATION);
+	duration = g_hash_table_lookup (to_metadata, TOTEM_PL_PARSER_FIELD_DURATION);
 
 	if (duration == NULL) {
-		duration = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_DURATION_MS);
+		duration = g_hash_table_lookup (to_metadata, TOTEM_PL_PARSER_FIELD_DURATION_MS);
 	}
 
 	if (duration != NULL) {
@@ -88,58 +102,60 @@ entry_parsed (TotemPlParser *parser, const gchar *uri, GHashTable *metadata, gpo
 }
 
 static void
-extract_playlist (const gchar *filename,
-		  GHashTable  *metadata)
+extract_playlist (const gchar *uri,
+		  GPtrArray   *metadata)
 {
 	TotemPlParser       *pl;
 	TotemPlParserResult  result;
-	PlaylistMetadata     data = {0, 0};
+	PlaylistMetadata     data = { 0, 0, metadata, uri };
 	gchar               *proper_filename;
 
 	pl = totem_pl_parser_new ();
 
-        g_object_set (pl, "recurse", FALSE, "disable-unsafe", TRUE, NULL);
+	g_object_set (pl, "recurse", FALSE, "disable-unsafe", TRUE, NULL);
 
-        g_signal_connect (G_OBJECT (pl), "entry-parsed", 
-                          G_CALLBACK (entry_parsed), &data);
+	g_signal_connect (G_OBJECT (pl), "entry-parsed", 
+			  G_CALLBACK (entry_parsed), &data);
 
-	if (g_str_has_prefix (filename, "file://")) {
-		proper_filename = g_strdup (filename);
-	} else {
-		proper_filename = g_strconcat ("file://", filename, NULL);
-	}
+	tracker_statement_list_insert (metadata, uri, 
+	                          RDF_TYPE, 
+	                          NFO_PREFIX "MediaList");
 
-        result = totem_pl_parser_parse (pl, proper_filename, FALSE);
+	result = totem_pl_parser_parse (pl, uri, FALSE);
 
-        switch (result) {
-        case TOTEM_PL_PARSER_RESULT_SUCCESS:
-                break;
-        case TOTEM_PL_PARSER_RESULT_IGNORED:
-        case TOTEM_PL_PARSER_RESULT_ERROR:
-        case TOTEM_PL_PARSER_RESULT_UNHANDLED:
+	switch (result) {
+	case TOTEM_PL_PARSER_RESULT_SUCCESS:
+		break;
+	case TOTEM_PL_PARSER_RESULT_IGNORED:
+	case TOTEM_PL_PARSER_RESULT_ERROR:
+	case TOTEM_PL_PARSER_RESULT_UNHANDLED:
 		data.total_time = PLAYLIST_DEFAULT_NO_TRACKS;
 		data.track_counter = PLAYLIST_DEFAULT_DURATION;
-                break;
-        default:
-                g_warning ("Undefined result in totem-plparser");
-        }
-
-	g_hash_table_insert (metadata, 
-			     g_strdup (PLAYLIST_PROPERTY_DURATION), 
-			     tracker_escape_metadata_printf ("%d", data.total_time));
-
-	g_hash_table_insert (metadata, 
-			     g_strdup (PLAYLIST_PROPERTY_NO_TRACKS), 
-			     tracker_escape_metadata_printf ("%d", data.track_counter));
-	g_hash_table_insert (metadata,
-			     g_strdup (PLAYLIST_PROPERTY_CALCULATED),
-			     g_strdup (data.total_time == 0 ? "0" : "1"));
+		break;
+	default:
+		g_warning ("Undefined result in totem-plparser");
+	}
+
+	/* TODO
+	tracker_statement_list_insert_with_int (metadata, uri,
+					   PLAYLIST_PROPERTY_DURATION, 
+					   data.total_time);
+
+	tracker_statement_list_insert_with_int (metadata, uri,
+					   PLAYLIST_PROPERTY_NO_TRACKS, 
+					   data.track_counter);
+
+	tracker_statement_list_insert_with_int (metadata, uri,
+					   PLAYLIST_PROPERTY_CALCULATED,
+					   data.total_time);
+	*/
+
 	g_free (proper_filename);
-        g_object_unref (pl);
+	g_object_unref (pl);
 }
 
 TrackerExtractData *
 tracker_get_extract_data (void)
 {
-	return data;
+	return playlist_data;
 }
diff --git a/src/tracker-extract/tracker-extract-png.c b/src/tracker-extract/tracker-extract-png.c
index 8727fc7..8052a0d 100644
--- a/src/tracker-extract/tracker-extract-png.c
+++ b/src/tracker-extract/tracker-extract-png.c
@@ -37,38 +37,49 @@
 #include <glib.h>
 #include <glib/gstdio.h>
 
+#include <libtracker-common/tracker-ontology.h>
 #include <libtracker-common/tracker-type-utils.h>
+#include <libtracker-common/tracker-statement-list.h>
 #include <libtracker-common/tracker-file-utils.h>
 
 #include "tracker-main.h"
 #include "tracker-xmp.h"
-#include "tracker-escape.h"
 
 #define RFC1123_DATE_FORMAT "%d %B %Y %H:%M:%S %z"
 
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
 typedef gchar * (*PostProcessor) (gchar *);
 
 typedef struct {
 	const gchar   *name;
 	const gchar   *type;
 	PostProcessor  post;
+	gboolean       anon;
 } TagProcessors;
 
 static gchar *rfc1123_to_iso8601_date (gchar	   *rfc_date);
 static void   extract_png	      (const gchar *filename,
-				       GHashTable  *metadata);
+				       GPtrArray   *metadata);
 
 static TagProcessors tag_processors[] = {
-	{ "Author",		"Image:Creator",      NULL},
-	{ "Creator",		"Image:Creator",      NULL},
-	{ "Description",	"Image:Description",  NULL},
-	{ "Comment",		"Image:Comments",     NULL},
-	{ "Copyright",		"File:Copyright",     NULL},
-	{ "Creation Time",	"Image:Date",	      rfc1123_to_iso8601_date},
-	{ "Title",		"Image:Title",	      NULL},
-	{ "Software",		"Image:Software",     NULL},
-	{ "Disclaimer",		"File:License",       NULL},
-	{ NULL,			NULL,		      NULL},
+	{ "Author",		NCO_PREFIX "creator",      NULL, TRUE},
+	{ "Creator",		NCO_PREFIX "creator",      NULL, TRUE},
+	{ "Description",	NIE_PREFIX "description",  NULL, FALSE},
+	{ "Comment",		NIE_PREFIX "comment",      NULL, FALSE},
+	{ "Copyright",		NIE_PREFIX "copyright",    NULL, FALSE},
+	{ "Creation Time",	NIE_PREFIX "contentCreated", rfc1123_to_iso8601_date, FALSE},
+	{ "Title",		NIE_PREFIX "title",	    NULL, FALSE},
+	{ "Software",		"Image:Software",           NULL, FALSE},
+	{ "Disclaimer",		NIE_PREFIX "license",       NULL, FALSE},
+	{ NULL,			NULL,		            NULL, FALSE},
 };
 
 static TrackerExtractData data[] = {
@@ -87,7 +98,7 @@ rfc1123_to_iso8601_date (gchar *date)
 }
 
 static void
-read_metadata (png_structp png_ptr, png_infop info_ptr, GHashTable *metadata)
+read_metadata (png_structp png_ptr, png_infop info_ptr, const gchar *uri, GPtrArray *metadata)
 {
 	gint	     num_text;
 	png_textp    text_ptr;
@@ -105,6 +116,7 @@ read_metadata (png_structp png_ptr, png_infop info_ptr, GHashTable *metadata)
 			if (strcmp ("XML:com.adobe.xmp", text_ptr[i].key) == 0) {
 				tracker_read_xmp (text_ptr[i].text,
 						  text_ptr[i].itxt_length,
+						  uri,
 						  metadata);
 				continue;
 			}
@@ -121,15 +133,27 @@ read_metadata (png_structp png_ptr, png_infop info_ptr, GHashTable *metadata)
 						
 						str = (*tag_processors[j].post) (text_ptr[i].text);
 						if (str) {
-							g_hash_table_insert (metadata,
-									     g_strdup (tag_processors[j].type),
-									     tracker_escape_metadata (str));
+							if (tag_processors[j].anon) {
+								tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+								tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", str);
+								tracker_statement_list_insert (metadata, uri, tag_processors[j].type, ":");
+							} else {
+								tracker_statement_list_insert (metadata, uri,
+											  tag_processors[j].type,
+											  str);
+							}
 							g_free (str);
 						}
 					} else {
-						g_hash_table_insert (metadata,
-								     g_strdup (tag_processors[j].type),
-								     tracker_escape_metadata (text_ptr[i].text));
+						if (tag_processors[j].anon) {
+							tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+							tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", text_ptr[i].text);
+							tracker_statement_list_insert (metadata, uri, tag_processors[j].type, ":");
+						} else {
+							tracker_statement_list_insert (metadata, uri,
+										  tag_processors[j].type,
+										  text_ptr[i].text);
+						}
 					}
 					
 					break;
@@ -140,8 +164,8 @@ read_metadata (png_structp png_ptr, png_infop info_ptr, GHashTable *metadata)
 }
 
 static void
-extract_png (const gchar *filename,
-	     GHashTable  *metadata)
+extract_png (const gchar *uri,
+	     GPtrArray   *metadata)
 {
 	goffset      size;
 	FILE	    *f;
@@ -150,10 +174,10 @@ extract_png (const gchar *filename,
 	png_infop    end_ptr;
 	png_bytepp   row_pointers;
 	guint        row;
-
 	png_uint_32  width, height;
 	gint	     bit_depth, color_type;
 	gint	     interlace_type, compression_type, filter_type;
+	gchar       *filename = g_filename_from_uri (uri, NULL, NULL);
 
 	size = tracker_file_get_size (filename);
 
@@ -170,6 +194,7 @@ extract_png (const gchar *filename,
 						  NULL);
 		if (!png_ptr) {
 			tracker_file_close (f, FALSE);
+			g_free (filename);
 			return;
 		}
 
@@ -177,6 +202,7 @@ extract_png (const gchar *filename,
 		if (!info_ptr) {
 			png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
 			tracker_file_close (f, FALSE);
+			g_free (filename);
 			return;
 		}
 
@@ -184,6 +210,7 @@ extract_png (const gchar *filename,
 		if (!end_ptr) {
 			png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
 			tracker_file_close (f, FALSE);
+			g_free (filename);
 			return;
 		}
 
@@ -207,6 +234,7 @@ extract_png (const gchar *filename,
 				   &filter_type)) {
 			png_destroy_read_struct (&png_ptr, &info_ptr, &end_ptr);
 			tracker_file_close (f, FALSE);
+			g_free (filename);
 			return;
 		}
 		
@@ -230,35 +258,28 @@ extract_png (const gchar *filename,
 
 		png_read_end (png_ptr, end_ptr);
 
- 		read_metadata (png_ptr, info_ptr, metadata);
- 		read_metadata (png_ptr, end_ptr, metadata);
-		
+ 		read_metadata (png_ptr, info_ptr, uri, metadata);
+ 		read_metadata (png_ptr, end_ptr, uri, metadata);
+
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "Image");
+
 		/* We want native have higher priority than XMP etc.
 		 */
-		g_hash_table_insert (metadata,
-				     g_strdup ("Image:Width"),
-				     tracker_escape_metadata_printf ("%ld", width));
-		g_hash_table_insert (metadata,
-				     g_strdup ("Image:Height"),
-				     tracker_escape_metadata_printf ("%ld", height));
-		
-		/* Check that we have the minimum data. FIXME We should not need to do this */
-		if (!g_hash_table_lookup (metadata, "Image:Date")) {
-			gchar *date;
-			guint64 mtime;
+		tracker_statement_list_insert_with_int (metadata, uri,
+						  NFO_PREFIX "width",
+						  width);
 
-			mtime = tracker_file_get_mtime (filename);
-			date = tracker_date_to_string ((time_t) mtime);
-			
-			g_hash_table_insert (metadata,
-					     g_strdup ("Image:Date"),
-					     tracker_escape_metadata (date));
-			g_free (date);
-		}
+		tracker_statement_list_insert_with_int (metadata, uri,
+						   NFO_PREFIX "height",
+						   height);
 
 		png_destroy_read_struct (&png_ptr, &info_ptr, &end_ptr);
 		tracker_file_close (f, FALSE);
 	}
+
+	g_free (filename);
 }
 
 TrackerExtractData *
diff --git a/src/tracker-extract/tracker-extract-ps.c b/src/tracker-extract/tracker-extract-ps.c
index 8862bb8..2ba8e8a 100644
--- a/src/tracker-extract/tracker-extract-ps.c
+++ b/src/tracker-extract/tracker-extract-ps.c
@@ -37,9 +37,17 @@
 #include <libtracker-common/tracker-file-utils.h>
 #include <libtracker-common/tracker-type-utils.h>
 #include <libtracker-common/tracker-os-dependant.h>
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
 
 #include "tracker-main.h"
-#include "tracker-escape.h"
+
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
 
 #ifndef HAVE_GETLINE
 
@@ -56,12 +64,11 @@
 #endif /* HAVE_GETLINE */
 
 #ifdef USING_UNZIPPSFILES
-static void extract_ps_gz (const gchar *filename,
-			   GHashTable  *metadata);
+static void extract_ps_gz (const gchar *uri,
+			   GPtrArray  *metadata);
 #endif
-
-static void extract_ps	  (const gchar *filename,
-			   GHashTable  *metadata);
+static void extract_ps	  (const gchar *uri,
+			   GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 #ifdef USING_UNZIPPSFILES
@@ -202,10 +209,11 @@ date_to_iso8601 (const gchar *date)
 }
 
 static void
-extract_ps (const gchar *filename,
-	    GHashTable	*metadata)
+extract_ps (const gchar *uri,
+	    GPtrArray	*metadata)
 {
 	FILE *f;
+	gchar *filename = g_filename_from_uri (uri, NULL, NULL);
 
 	f = tracker_file_open (filename, "r", TRUE);
 
@@ -217,6 +225,10 @@ extract_ps (const gchar *filename,
 		line = NULL;
 		length = 0;
 
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NFO_PREFIX "Document");
+
 		while ((read_char = getline (&line, &length, f)) != -1) {
 			gboolean pageno_atend	 = FALSE;
 			gboolean header_finished = FALSE;
@@ -224,19 +236,20 @@ extract_ps (const gchar *filename,
 			line[read_char - 1] = '\0';  /* overwrite '\n' char */
 
 			if (!header_finished && strncmp (line, "%%Copyright:", 12) == 0) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("File:Other"),
-						     tracker_escape_metadata (line + 13));
+				tracker_statement_list_insert (metadata, uri,
+							  NIE_PREFIX "copyright",
+							  line + 13);
 
 			} else if (!header_finished && strncmp (line, "%%Title:", 8) == 0) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:Title"),
-						     tracker_escape_metadata (line + 9));
+				tracker_statement_list_insert (metadata, uri,
+							  NIE_PREFIX "title",
+							  line + 9);
 
 			} else if (!header_finished && strncmp (line, "%%Creator:", 10) == 0) {
-				g_hash_table_insert (metadata,
-						     g_strdup ("Doc:Author"),
-						     tracker_escape_metadata (line + 11));
+
+				tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+				tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", line + 11);
+				tracker_statement_list_insert (metadata, uri, NCO_PREFIX "creator", ":");
 
 			} else if (!header_finished && strncmp (line, "%%CreationDate:", 15) == 0) {
 				gchar *date;
@@ -244,9 +257,9 @@ extract_ps (const gchar *filename,
 				date = date_to_iso8601 (line + 16);
 
 				if (date) {
-					g_hash_table_insert (metadata,
-							     g_strdup ("Doc:Created"),
-							     tracker_escape_metadata (date));
+					tracker_statement_list_insert (metadata, uri,
+								  NIE_PREFIX "contentCreated",
+								  date);
 
 					g_free (date);
 				}
@@ -254,9 +267,9 @@ extract_ps (const gchar *filename,
 				if (strcmp (line + 9, "(atend)") == 0) {
 					pageno_atend = TRUE;
 				} else {
-					g_hash_table_insert (metadata,
-							     g_strdup ("Doc:PageCount"),
-							     tracker_escape_metadata (line + 9));
+					tracker_statement_list_insert (metadata, uri,
+								  NFO_PREFIX "pageCount",
+								  line + 9);
 				}
 			} else if (strncmp (line, "%%EndComments", 14) == 0) {
 				header_finished = TRUE;
@@ -277,12 +290,14 @@ extract_ps (const gchar *filename,
 
 		tracker_file_close (f, FALSE);
 	}
+
+	g_free (filename);
 }
 
 #ifdef USING_UNZIPPSFILES
 static void
-extract_ps_gz (const gchar *filename,
-	       GHashTable  *metadata)
+extract_ps_gz (const gchar *uri,
+	       GPtrArray   *metadata)
 {
 	FILE	    *fz, *f;
 	GError	    *error = NULL;
@@ -291,7 +306,8 @@ extract_ps_gz (const gchar *filename,
 	gint	     fd;
 	gboolean     ptat;
 	const gchar *argv[4];
-
+	gchar *filename;
+	
 	fd = g_file_open_tmp ("tracker-extract-ps-gunzipped.XXXXXX",
 			      &gunzipped,
 			      &error);
@@ -301,6 +317,10 @@ extract_ps_gz (const gchar *filename,
 		return;
 	}
 
+	filename = g_filename_from_uri (uri, NULL, NULL);
+
+	/* TODO: we should be using libz for this instead */
+
 	argv[0] = "gunzip";
 	argv[1] = "-c";
 	argv[2] = filename;
@@ -319,6 +339,7 @@ extract_ps_gz (const gchar *filename,
 					 &error);
 
 	if (!ptat) {
+		g_free (filename);
 		g_unlink (gunzipped);
 		g_clear_error (&error);
 		close (fd);
@@ -367,6 +388,7 @@ extract_ps_gz (const gchar *filename,
 
 	extract_ps (gunzipped, metadata);
 	g_unlink (gunzipped);
+	g_free (filename);
 }
 #endif
 
diff --git a/src/tracker-extract/tracker-extract-tiff.c b/src/tracker-extract/tracker-extract-tiff.c
index 65bba39..821cd22 100644
--- a/src/tracker-extract/tracker-extract-tiff.c
+++ b/src/tracker-extract/tracker-extract-tiff.c
@@ -27,7 +27,9 @@
 #include <tiff.h>
 #include <tiffio.h>
 
+#include <libtracker-common/tracker-ontology.h>
 #include <libtracker-common/tracker-type-utils.h>
+#include <libtracker-common/tracker-statement-list.h>
 #include <libtracker-common/tracker-file-utils.h>
 
 #include "tracker-main.h"
@@ -36,6 +38,15 @@
 
 #define EXIF_DATE_FORMAT     "%Y:%m:%d %H:%M:%S"
 
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
 typedef gchar * (*PostProcessor) (gchar *);
 
 typedef enum {
@@ -48,30 +59,30 @@ typedef enum {
 } TagType;
 
 typedef struct {
-	guint	       tag;
-	gchar	      *name;
+	guint          tag;
+	const gchar   *name;
 	TagType        type;
 	PostProcessor  post;
 } TiffTag;
  
 static void   extract_tiff    (const gchar *filename,
-			       GHashTable  *metadata);
+			       GPtrArray   *metadata);
 static gchar *date_to_iso8601 (gchar       *date);
 
-static TrackerExtractData data[] = {
+static TrackerExtractData extract_data[] = {
 	{ "image/tiff", extract_tiff },
 	{ NULL, NULL }
 };
 
 /* FIXME: We are missing some */
 static TiffTag tags[] = {
-	{ TIFFTAG_ARTIST, "Image:Creator", TIFF_TAGTYPE_STRING, NULL },
-	{ TIFFTAG_COPYRIGHT, "File:Copyright", TIFF_TAGTYPE_STRING, NULL },
-	{ TIFFTAG_DATETIME, "Image:Date", TIFF_TAGTYPE_STRING, NULL },
-	{ TIFFTAG_DOCUMENTNAME, "Image:Title", TIFF_TAGTYPE_STRING, NULL },
-	{ TIFFTAG_IMAGEDESCRIPTION, "Image:Comments", TIFF_TAGTYPE_STRING, NULL },
-	{ TIFFTAG_IMAGEWIDTH, "Image:Width", TIFF_TAGTYPE_UINT32, NULL },
-	{ TIFFTAG_IMAGELENGTH, "Image:Height", TIFF_TAGTYPE_UINT32, NULL },
+	{ TIFFTAG_ARTIST, NCO_PREFIX "creator", TIFF_TAGTYPE_STRING, NULL },
+	{ TIFFTAG_COPYRIGHT, NIE_PREFIX "copyright", TIFF_TAGTYPE_STRING, NULL },
+	{ TIFFTAG_DATETIME, NIE_PREFIX "contentCreated", TIFF_TAGTYPE_STRING, NULL },
+	{ TIFFTAG_DOCUMENTNAME, NIE_PREFIX "title", TIFF_TAGTYPE_STRING, NULL },
+	{ TIFFTAG_IMAGEDESCRIPTION, NIE_PREFIX "comment", TIFF_TAGTYPE_STRING, NULL },
+	{ TIFFTAG_IMAGEWIDTH, NFO_PREFIX "width", TIFF_TAGTYPE_UINT32, NULL },
+	{ TIFFTAG_IMAGELENGTH, NFO_PREFIX "height", TIFF_TAGTYPE_UINT32, NULL },
 	{ TIFFTAG_MAKE, "Image:CameraMake", TIFF_TAGTYPE_STRING, NULL },
 	{ TIFFTAG_MODEL, "Image:CameraModel", TIFF_TAGTYPE_STRING, NULL },
 	{ TIFFTAG_ORIENTATION, "Image:Orientation", TIFF_TAGTYPE_UINT16, NULL },
@@ -84,12 +95,12 @@ static TiffTag exiftags[] = {
 	{ EXIFTAG_FNUMBER, "Image:FNumber", TIFF_TAGTYPE_DOUBLE, NULL},
 	{ EXIFTAG_EXPOSUREPROGRAM, "Image:ExposureProgram", TIFF_TAGTYPE_UINT16, NULL },
 	{ EXIFTAG_ISOSPEEDRATINGS, "Image:ISOSpeed", TIFF_TAGTYPE_C16_UINT16, NULL},
-	{ EXIFTAG_DATETIMEORIGINAL, "Image:Date", TIFF_TAGTYPE_STRING, date_to_iso8601 },
+	{ EXIFTAG_DATETIMEORIGINAL, NIE_PREFIX "contentCreated", TIFF_TAGTYPE_STRING, date_to_iso8601 },
 	{ EXIFTAG_METERINGMODE, "Image:MeteringMode", TIFF_TAGTYPE_UINT16, NULL},
 	{ EXIFTAG_FLASH, "Image:Flash", TIFF_TAGTYPE_UINT16, NULL},
 	{ EXIFTAG_FOCALLENGTH, "Image:FocalLength", TIFF_TAGTYPE_DOUBLE, NULL},
-	{ EXIFTAG_PIXELXDIMENSION, "Image:Width", TIFF_TAGTYPE_UINT32, NULL},
-	{ EXIFTAG_PIXELYDIMENSION, "Image:Height", TIFF_TAGTYPE_UINT32, NULL},
+	{ EXIFTAG_PIXELXDIMENSION, NFO_PREFIX "width", TIFF_TAGTYPE_UINT32, NULL},
+	{ EXIFTAG_PIXELYDIMENSION, NFO_PREFIX "height", TIFF_TAGTYPE_UINT32, NULL},
 	{ EXIFTAG_WHITEBALANCE, "Image:WhiteBalance", TIFF_TAGTYPE_UINT16, NULL},
 	{ -1, NULL, TIFF_TAGTYPE_UNDEFINED, NULL }
 };
@@ -105,19 +116,18 @@ date_to_iso8601 (gchar *date)
 }
 
 static void
-extract_tiff (const gchar *filename, 
-	      GHashTable  *metadata)
+extract_tiff (const gchar *uri, 
+	      GPtrArray   *metadata)
 {
 	TIFF *image;
 	glong exifOffset;
-
+	gchar *filename = g_filename_from_uri (uri, NULL, NULL);
 	TiffTag *tag;
 
 	gchar buffer[1024];
 	gchar *text;
 	guint16 varui16 = 0;
 	guint32 varui32 = 0;
-	
 	void *data;
 	guint16 count16;
 
@@ -135,16 +145,21 @@ extract_tiff (const gchar *filename,
 
 	if ((image = TIFFOpen (filename, "r")) == NULL){
 		g_critical ("Could not open image:'%s'\n", filename);
+		g_free (filename);
 		return;
 	}
 
+	tracker_statement_list_insert (metadata, uri, 
+	                          RDF_TYPE, 
+	                          NFO_PREFIX "Image");
+
 #ifdef HAVE_LIBIPTCDATA
 	if (TIFFGetField (image, TIFFTAG_RICHTIFFIPTC, &iptcSize, &iptcOffset)) {
 		if (TIFFIsByteSwapped(image) != 0) 
 			TIFFSwabArrayOfLong((uint32 *) iptcOffset,(unsigned long) iptcSize);
 		tracker_read_iptc (iptcOffset,
 				   4*iptcSize,
-				   metadata);
+				   uri, metadata);
 	}
 #endif /* HAVE_LIBIPTCDATA */
 
@@ -154,6 +169,7 @@ extract_tiff (const gchar *filename,
 	if (TIFFGetField (image, TIFFTAG_XMLPACKET, &size, &xmpOffset)) {
 		tracker_read_xmp (xmpOffset,
 				  size,
+				  uri,
 				  metadata);
 	}
 #endif /* HAVE_EXEMPI */
@@ -205,13 +221,13 @@ extract_tiff (const gchar *filename,
 				}
 
 				if (tag->post) {
-					g_hash_table_insert (metadata,
-							     g_strdup (tag->name),
-							     tracker_escape_metadata ((*tag->post) (buffer)));
+					tracker_statement_list_insert (metadata, uri,
+								  tag->name,
+								  (*tag->post) (buffer));
 				} else {
-					g_hash_table_insert (metadata, 
-							     g_strdup (tag->name),
-							     tracker_escape_metadata (buffer));
+					tracker_statement_list_insert (metadata, uri,
+								  tag->name,
+							 	  buffer);
 				}
 			}
 		}
@@ -219,6 +235,8 @@ extract_tiff (const gchar *filename,
 
 	/* We want to give native tags priority over XMP/Exif */
 	for (tag = tags; tag->name; ++tag) {
+		gchar *what_i_need;
+
 		switch (tag->type) {
 			case TIFF_TAGTYPE_STRING:
 				if (!TIFFGetField (image, tag->tag, &text)) {
@@ -254,36 +272,30 @@ extract_tiff (const gchar *filename,
 			}
 
 		if (tag->post) {
-			g_hash_table_insert (metadata, 
-					     g_strdup (tag->name),
-					     tracker_escape_metadata ((*tag->post) (buffer)));
+			what_i_need = (*tag->post) (buffer);
 		} else {
-			g_hash_table_insert (metadata, 
-					     g_strdup (tag->name),
-					     tracker_escape_metadata (buffer));
+			what_i_need = buffer;
 		}
-	}
 
-	/* Check that we have the minimum data. FIXME We should not need to do this */
-	
-	if (!g_hash_table_lookup (metadata, "Image:Date")) {
-		gchar *date;
-		guint64 mtime;
-		
-		mtime = tracker_file_get_mtime (filename);
-		date = tracker_date_to_string ((time_t) mtime);
-		
-		g_hash_table_insert (metadata,
-				     g_strdup ("Image:Date"),
-				     tracker_escape_metadata (date));
-		g_free (date);
+		if (tag->tag == TIFFTAG_ARTIST) {
+			tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+			tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", what_i_need);
+			tracker_statement_list_insert (metadata, uri, tag->name, ":");
+		} else {
+			tracker_statement_list_insert (metadata, uri, tag->name, what_i_need);
+		}
+
+		if (tag->post) 
+			g_free (what_i_need);
 	}
 
 	TIFFClose (image);
+
+	g_free (filename);
 }
 
 TrackerExtractData *
 tracker_get_extract_data (void)
 {
-	return data;
+	return extract_data;
 }
diff --git a/src/tracker-extract/tracker-extract-totem.c b/src/tracker-extract/tracker-extract-totem.c
index e3da6ca..0481506 100644
--- a/src/tracker-extract/tracker-extract-totem.c
+++ b/src/tracker-extract/tracker-extract-totem.c
@@ -24,27 +24,37 @@
 #include <glib.h>
 
 #include <libtracker-common/tracker-os-dependant.h>
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
 
 #include "tracker-main.h"
-#include "tracker-escape.h"
-
-static gchar *tags[][2] = {
-	{ "TOTEM_INFO_VIDEO_HEIGHT",		"Video:Height"		},
-	{ "TOTEM_INFO_VIDEO_WIDTH",		"Video:Width"		},
-	{ "TOTEM_INFO_FPS",			"Video:FrameRate"	},
-	{ "TOTEM_INFO_VIDEO_CODEC",		"Video:Codec"		},
-	{ "TOTEM_INFO_VIDEO_BITRATE",		"Video:Bitrate"		},
-	{ "TOTEM_INFO_TITLE",			"Video:Title"		},
-	{ "TOTEM_INFO_AUTHOR",			"Video:Author"		},
-	{ "TOTEM_INFO_AUDIO_BITRATE",		"Audio:Bitrate"		},
-	{ "TOTEM_INFO_AUDIO_SAMPLE_RATE",	"Audio:Samplerate"	},
-	{ "TOTEM_INFO_AUDIO_CODEC",		"Audio:Codec"		},
-	{ "TOTEM_INFO_AUDIO_CHANNELS",		"Audio:Channels"	},
+
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+static const gchar *tags[][2] = {
+	{ "TOTEM_INFO_VIDEO_HEIGHT",		NFO_PREFIX "height"	},
+	{ "TOTEM_INFO_VIDEO_WIDTH",		NFO_PREFIX "width"	},
+	{ "TOTEM_INFO_FPS",			NFO_PREFIX "frameRate"	},
+	{ "TOTEM_INFO_VIDEO_CODEC",		NFO_PREFIX "codec"	},
+	{ "TOTEM_INFO_VIDEO_BITRATE",		NFO_PREFIX "averageBitrate"	},
+	{ "TOTEM_INFO_TITLE",			NIE_PREFIX "title"	},
+	{ "TOTEM_INFO_AUTHOR",			NCO_PREFIX "creator"	},
+	{ "TOTEM_INFO_AUDIO_BITRATE",		NMM_PREFIX "averageBitrate"	},
+	{ "TOTEM_INFO_AUDIO_SAMPLE_RATE",	NFO_PREFIX "sampleRate"		},
+	{ "TOTEM_INFO_AUDIO_CODEC",		NFO_PREFIX "codec"		},
+	{ "TOTEM_INFO_AUDIO_CHANNELS",		NFO_PREFIX "channels"		},
 	{ NULL,					NULL			}
 };
 
-static void extract_totem (const gchar *filename,
-			   GHashTable  *metadata);
+static void extract_totem (const gchar *uri,
+			   GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 	{ "audio/*", extract_totem },
@@ -53,14 +63,15 @@ static TrackerExtractData data[] = {
 };
 
 static void
-extract_totem (const gchar *filename,
-	       GHashTable  *metadata)
+extract_totem (const gchar *uri,
+	       GPtrArray   *metadata)
 {
 	gchar *argv[3];
 	gchar *totem;
+	gboolean has_video = FALSE;
 
 	argv[0] = g_strdup ("totem-video-indexer");
-	argv[1] = g_strdup (filename);
+	argv[1] = g_filename_from_uri (uri, NULL, NULL);
 	argv[2] = NULL;
 
 	if (tracker_spawn (argv, 10, &totem, NULL)) {
@@ -72,14 +83,38 @@ extract_totem (const gchar *filename,
 			gint i;
 
 			for (i = 0; tags[i][0]; i++) {
+				if (g_strcmp0 (*line, "TOTEM_INFO_HAS_VIDEO=True")) {
+					has_video = TRUE;
+				}
+
 				if (g_str_has_prefix (*line, tags[i][0])) {
-					g_hash_table_insert (metadata,
-							     g_strdup (tags[i][1]),
-							     tracker_escape_metadata ((*line) + strlen (tags[i][0]) + 1));
+					gchar *value = (*line) + strlen (tags[i][0]) + 1;
+
+					if (g_strcmp0 (tags[i][0], "TOTEM_INFO_AUTHOR")) {
+						gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", value);
+						tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NCO_PREFIX "Contact");
+						tracker_statement_list_insert (metadata, canonical_uri, NCO_PREFIX "fullname", value);
+						tracker_statement_list_insert (metadata, uri, tags[i][1], canonical_uri);
+						g_free (canonical_uri);
+					} else {
+						tracker_statement_list_insert (metadata, uri,
+									  tags[i][1],
+									  value);
+					}
 					break;
 				}
 			}
 		}
+
+		if (has_video) {
+			tracker_statement_list_insert (metadata, uri, 
+			                          RDF_TYPE, 
+			                          NMM_PREFIX "Video");
+		} else {
+			tracker_statement_list_insert (metadata, uri, 
+			                          RDF_TYPE, 
+			                          NMM_PREFIX "MusicPiece");
+		}
 	}
 }
 
diff --git a/src/tracker-extract/tracker-extract-vorbis.c b/src/tracker-extract/tracker-extract-vorbis.c
index f873850..c97a78d 100644
--- a/src/tracker-extract/tracker-extract-vorbis.c
+++ b/src/tracker-extract/tracker-extract-vorbis.c
@@ -28,47 +28,62 @@
 #include <vorbis/vorbisfile.h>
 
 #include <libtracker-common/tracker-file-utils.h>
+#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-utils.h>
 
 #include "tracker-main.h"
 
-static void extract_vorbis (const char *filename, 
-                            GHashTable *metadata);
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+#define NMM_PREFIX TRACKER_NMM_PREFIX
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+static void extract_vorbis (const char *uri, 
+                            GPtrArray  *metadata);
 
 static struct {
 	gchar *name;
 	gchar *meta_name;
 	gboolean writable;
+	const gchar *urn;
+	const gchar *rdf_type;
+	const gchar *predicate;
 } tags[] = {
-	 { "title", "Audio.Title", FALSE },
-	 { "artist", "Audio.Artist", FALSE },
-	 { "album", "Audio.Album", FALSE },
-	 { "albumartist", "Audio.AlbumArtist", FALSE },
-	 { "trackcount", "Audio.AlbumTrackCount", FALSE },
-	 { "tracknumber", "Audio.TrackNo", FALSE },
-	 { "DiscNo", "Audio.DiscNo", FALSE },
-	 { "Performer", "Audio.Performer", FALSE },
-	 { "TrackGain", "Audio.TrackGain", FALSE },
-	 { "TrackPeakGain", "Audio.TrackPeakGain", FALSE },
-	 { "AlbumGain", "Audio.AlbumGain", FALSE },
-	 { "AlbumPeakGain", "Audio.AlbumPeakGain", FALSE },
-	 { "date", "Audio.ReleaseDate", FALSE },
-	 { "comment", "Audio.Comment", FALSE },
-	 { "genre", "Audio.Genre", FALSE },
-	 { "Codec", "Audio.Codec", FALSE },
-	 { "CodecVersion", "Audio.CodecVersion", FALSE },
-	 { "Samplerate", "Audio.Samplerate", FALSE },
-	 { "Channels", "Audio.Channels", FALSE },
-	 { "MBAlbumID", "Audio.MBAlbumID", FALSE },
-	 { "MBArtistID", "Audio.MBArtistID", FALSE },
-	 { "MBAlbumArtistID", "Audio.MBAlbumArtistID", FALSE },
-	 { "MBTrackID", "Audio.MBTrackID", FALSE },
-	 { "Lyrics", "Audio.Lyrics", FALSE },
-	 { "Copyright", "File.Copyright", FALSE },
-	 { "License", "File.License", FALSE },
-	 { "Organization", "File.Organization", FALSE },
-	 { "Location", "File.Location", FALSE },
-	 { "Publisher", "File.Publisher", FALSE },
-	 { NULL, NULL, FALSE },
+	 {"title", NIE_PREFIX "title", FALSE, NULL, NULL, NULL},
+	 {"artist", NMM_PREFIX "performer", FALSE, "artist", NCO_PREFIX "Contact", NCO_PREFIX "fullname" },
+	 {"album", NIE_PREFIX "title", FALSE, NULL, NULL, NULL},
+	 {"albumartist", NMM_PREFIX "performer", FALSE, "artist", NCO_PREFIX "Contact", NCO_PREFIX "fullname" },
+	 {"trackcount", NMM_PREFIX "albumTrackCount", FALSE, NULL, NULL, NULL},
+	 {"tracknumber", NMM_PREFIX "trackNumber", FALSE, NULL, NULL, NULL},
+	 {"DiscNo", NMM_PREFIX "setNumber", FALSE, NULL, NULL, NULL},
+	 {"Performer", NMM_PREFIX "performer", FALSE, "artist", NCO_PREFIX "Contact", NCO_PREFIX "fullname" },
+	 {"TrackGain", "Audio.TrackGain", FALSE, NULL, NULL, NULL},
+	 {"TrackPeakGain", "Audio.TrackPeakGain", FALSE, NULL, NULL, NULL},
+	 {"AlbumGain", NMM_PREFIX "albumGain", FALSE, NULL, NULL, NULL},
+	 {"AlbumPeakGain", NMM_PREFIX "albumPeakGain", FALSE, NULL, NULL, NULL},
+	 {"date", NIE_PREFIX "contentCreated", FALSE, NULL, NULL, NULL},
+	 {"comment", NIE_PREFIX "comment", FALSE, NULL, NULL, NULL},
+	 {"genre", NFO_PREFIX "genre", FALSE, NULL, NULL, NULL},
+	 {"Codec", NFO_PREFIX "codec", FALSE, NULL, NULL, NULL},
+	 {"CodecVersion", "Audio.CodecVersion", FALSE, NULL, NULL, NULL},
+	 {"Samplerate", NFO_PREFIX "sampleRate", FALSE, NULL, NULL, NULL},
+	 {"Channels", NFO_PREFIX "channels", FALSE, NULL, NULL, NULL},
+	 {"MBAlbumID", "Audio.MBAlbumID", FALSE, NULL, NULL, NULL},
+	 {"MBArtistID", "Audio.MBArtistID", FALSE, NULL, NULL, NULL},
+	 {"MBAlbumArtistID", "Audio.MBAlbumArtistID", FALSE, NULL, NULL, NULL},
+	 {"MBTrackID", "Audio.MBTrackID", FALSE, NULL, NULL, NULL},
+	 {"Lyrics", NIE_PREFIX "plainTextContent", FALSE, NULL, NULL, NULL},
+	 {"Copyright", NIE_PREFIX "copyright", FALSE, NULL, NULL, NULL},
+	 {"License", NIE_PREFIX "license", FALSE, NULL, NULL, NULL},
+	 {"Organization", "File.Organization", FALSE, NULL, NULL, NULL},
+	 {"Location", "File.Location", FALSE, NULL, NULL, NULL},
+	 {"Publisher", DC_PREFIX "publisher", FALSE, "publisher", NCO_PREFIX "Contact", NCO_PREFIX "fullname" },
+	 {NULL, NULL, FALSE, NULL, NULL, NULL},
 };
 
 static TrackerExtractData extract_data[] = {
@@ -121,8 +136,8 @@ ogg_write (const char *meta_name,
 #endif
 
 static void
-extract_vorbis (const char *filename, 
-                GHashTable *metadata)
+extract_vorbis (const char *uri,
+                GPtrArray *metadata)
 {
 	FILE	       *f;
 	OggVorbis_File  vf;
@@ -130,11 +145,12 @@ extract_vorbis (const char *filename,
 	vorbis_comment *comment;
 	vorbis_info    *vi;
 	unsigned int    bitrate;
-	gchar          *str_bitrate;
 	gint            time;
-	gchar          *str_time;
+	gchar *filename;
 
+	filename = g_filename_from_uri (uri, NULL, NULL);
 	f = tracker_file_open (filename, "r", FALSE);
+	g_free (filename);
 
 	if (!f) {
                 return;
@@ -146,13 +162,26 @@ extract_vorbis (const char *filename,
 	}
 
 	if ((comment = ov_comment (&vf, -1)) != NULL) {
+		tracker_statement_list_insert (metadata, uri, 
+		                          RDF_TYPE, 
+		                          NMM_PREFIX "MusicPiece");
+
                 for (i = 0; tags[i].name != NULL; i++) {
                         gchar *str;
                         
                         str = ogg_get_comment (comment, tags[i].name);
                         
                         if (str) {
-                                g_hash_table_insert (metadata, g_strdup (tags[i].meta_name), str);
+				if (tags[i].urn) {
+					gchar *canonical_uri = tags[i].urn[0]!=':'?tracker_uri_printf_escaped ("urn:%s:%s", tags[i].urn, str):g_strdup(tags[i].urn);
+					tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, tags[i].rdf_type);
+					tracker_statement_list_insert (metadata, canonical_uri, tags[i].predicate, str);
+					tracker_statement_list_insert (metadata, uri, tags[i].meta_name, canonical_uri);
+					g_free (canonical_uri);
+				} else {
+					tracker_statement_list_insert (metadata, uri, tags[i].meta_name, str);
+				}
+				g_free (str);
                         }
                 }
                 
@@ -160,21 +189,19 @@ extract_vorbis (const char *filename,
                 
                 if ((vi = ov_info (&vf, 0)) != NULL ) {
                         bitrate = vi->bitrate_nominal / 1000;
-                        str_bitrate = g_strdup_printf ("%d", bitrate);
 
-                        g_hash_table_insert (metadata, g_strdup ("Audio.Bitrate"), str_bitrate);
-                        g_hash_table_insert (metadata, g_strdup ("Audio.CodecVersion"), g_strdup_printf ("%d", vi->version));
-                        g_hash_table_insert (metadata, g_strdup ("Audio.Channels"), g_strdup_printf ("%d", vi->channels));
-                        g_hash_table_insert (metadata, g_strdup ("Audio.Samplerate"), g_strdup_printf ("%ld", vi->rate));
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "averageBitrate", bitrate);
+			tracker_statement_list_insert_with_int (metadata, uri, "Audio.CodecVersion", vi->version);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "channels", vi->channels);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "sampleRate", vi->rate);
                 }
                 
                 /* Duration */
                 if ((time = ov_time_total (&vf, -1)) != OV_EINVAL) {
-                        str_time = g_strdup_printf ("%d", time);
-                        g_hash_table_insert (metadata, g_strdup ("Audio.Duration"), str_time);
+			tracker_statement_list_insert_with_int (metadata, uri, NFO_PREFIX "duration", time);
                 }
                 
-                g_hash_table_insert (metadata, g_strdup ("Audio.Codec"), g_strdup ("vorbis"));
+		tracker_statement_list_insert (metadata, uri, NFO_PREFIX "codec", "vorbis");
         }
 
         /* NOTE: This calls fclose on the file */
diff --git a/src/tracker-extract/tracker-extract-xmp.c b/src/tracker-extract/tracker-extract-xmp.c
index 487c272..e5fcc78 100644
--- a/src/tracker-extract/tracker-extract-xmp.c
+++ b/src/tracker-extract/tracker-extract-xmp.c
@@ -21,12 +21,13 @@
 
 #include <glib.h>
 
+#include <libtracker-common/tracker-statement-list.h>
+
 #include "tracker-main.h"
 #include "tracker-xmp.h"
-#include "tracker-escape.h"
 
 static void extract_xmp (const gchar *filename, 
-                         GHashTable  *metadata);
+                         GPtrArray   *metadata);
 
 static TrackerExtractData data[] = {
 	{ "application/rdf+xml", extract_xmp },
@@ -34,16 +35,23 @@ static TrackerExtractData data[] = {
 };
 
 static void
-extract_xmp (const gchar *filename, 
-             GHashTable  *metadata)
+extract_xmp (const gchar *uri, 
+             GPtrArray   *metadata)
 {
 	gchar *contents;
 	gsize length;
 	GError *error;
+	gchar *filename = g_filename_from_uri (uri, NULL, NULL);
 
 	if (g_file_get_contents (filename, &contents, &length, &error)) {
-		tracker_read_xmp (contents, length, metadata);
-        }
+		/* URI is very very wrong here. The URI is location://filename.xmp whereas
+		 * the metadata is about location://filename.jpeg (in case it's a sidecar
+		 * for filename.jpeg) */
+		tracker_read_xmp (contents, length, uri, metadata);
+	}
+
+	g_free (filename);
+
 }
 
 TrackerExtractData *
diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c
index 648ed8b..e588817 100644
--- a/src/tracker-extract/tracker-extract.c
+++ b/src/tracker-extract/tracker-extract.c
@@ -72,6 +72,17 @@ tracker_extract_finalize (GObject *object)
 	G_OBJECT_CLASS (tracker_extract_parent_class)->finalize (object);
 }
 
+static void
+statements_free (GPtrArray *statements)
+{
+	guint i;
+
+	for (i = 0; i < statements->len; i++) {
+		g_value_array_free (statements->pdata[i]);
+	}
+	g_ptr_array_free (statements, TRUE);
+}
+
 TrackerExtract *
 tracker_extract_new (void)
 {
@@ -190,52 +201,48 @@ print_file_metadata_item (gpointer key,
 	}
 }
 
-static GHashTable *
+static GPtrArray *
 get_file_metadata (TrackerExtract *extract,
 		   guint           request_id,
-		   const gchar    *path,
-		   const gchar    *mime)
+		   const gchar    *uri,
+		   const gchar    *mime_)
 {
-	GHashTable *values;
+	GPtrArray *statements;
 	GFile *file;
 	GFileInfo *info;
 	GError *error = NULL;
 	const gchar *attributes = NULL;
-	gchar *path_in_locale;
-	gchar *path_used;
 	gchar *mime_used = NULL;
 	goffset size = 0;
-		
-	path_used = g_strdup (path);
-	g_strstrip (path_used);
+	gchar *content_type = NULL;
+	gchar *mime = mime_;
 
-	path_in_locale = g_filename_from_utf8 (path_used, -1, NULL, NULL, NULL);
-	g_free (path_used);
+	/* Create hash table to send back */
+	statements = g_ptr_array_new ();
 
-	if (!path_in_locale) {
-		g_warning ("Could not convert path from UTF-8 to locale");
-		g_free (path_used);
-		return NULL;
-	}
+	if ((!mime || mime[0]=='\0') && content_type)
+		mime = content_type;
 
-	file = g_file_new_for_path (path_in_locale);
+	file = g_file_new_for_uri (uri);
 	if (!file) {
-		g_warning ("Could not create GFile for path:'%s'",
-			   path_in_locale);
-		g_free (path_in_locale);
+		g_warning ("Could not create GFile for uri:'%s'",
+			   uri);
+		g_free (content_type);
+		statements_free (statements);
 		return NULL;
 	}
-		
+
 	/* Blocks */
 	if (!g_file_query_exists (file, NULL)) {
-		g_warning ("File does not exist '%s'", path_in_locale);
+		g_warning ("File does not exist '%s'", uri);
 		g_object_unref (file);
-		g_free (path_in_locale);
+		g_free (content_type);
+		statements_free (statements);
 		return NULL;
 	}
 
 	/* Do we get size and mime? or just size? */
-	if (mime && *mime) {	
+	if (mime && *mime) {
 		attributes = 
 			G_FILE_ATTRIBUTE_STANDARD_SIZE;
 	} else {
@@ -258,19 +265,13 @@ get_file_metadata (TrackerExtract *extract,
 		
 		if (info) {
 			g_object_unref (info);
-		}	
+		}
 		
 		g_object_unref (file);
-		g_free (path_in_locale);
-		
+		g_free (content_type);
+		statements_free (statements);
 		return NULL;
 	}
-	
-	/* Create hash table to send back */
-	values = g_hash_table_new_full (g_str_hash,
-					g_str_equal,
-					g_free,
-					g_free);
 
 	/* Check the size is actually non-zero */
 	size = g_file_info_get_size (info);
@@ -281,9 +282,10 @@ get_file_metadata (TrackerExtract *extract,
 		
 		g_object_unref (info);
 		g_object_unref (file);
-		g_free (path_in_locale);
 
-		return values;
+		g_free (content_type);
+		statements_free (statements);
+		return statements;
 	}
 
 	/* We know the mime */
@@ -294,9 +296,9 @@ get_file_metadata (TrackerExtract *extract,
 		mime_used = g_strdup (g_file_info_get_content_type (info));
 
 		tracker_dbus_request_comment (request_id,
-					      "  Guessing mime type as '%s' for path:'%s'",
+					      "  Guessing mime type as '%s' for uri:'%s'",
 					      mime_used,
-					      path_in_locale);
+					      uri);
 	}
 
 	g_object_unref (info);
@@ -316,20 +318,20 @@ get_file_metadata (TrackerExtract *extract,
 			data = &g_array_index (priv->extractors, TrackerExtractData, i);
 
 			if (g_pattern_match_simple (data->mime, mime_used)) {
-				(*data->extract) (path_in_locale, values);
+				(*data->extract) (uri, statements);
 
-				if (g_hash_table_size (values) == 0) {
+				if (statements->len == 0) {
 					continue;
 				}
 
 				tracker_dbus_request_comment (request_id,
 							      "  Found %d metadata items",
-							      g_hash_table_size (values));
+							      statements->len);
 
-				g_free (path_in_locale);
 				g_free (mime_used);
+				g_free (content_type);
 
-				return values;
+				return statements;
 			}
 		}
 
@@ -342,31 +344,29 @@ get_file_metadata (TrackerExtract *extract,
 					      "  No mime available, not extracting data");
 	}
 
-	g_free (path_in_locale);
+	g_free (content_type);
 
-	return values;
+	return statements;
 }
 
 void
 tracker_extract_get_metadata_by_cmdline (TrackerExtract *object,
-					 const gchar    *path,
+					 const gchar    *uri,
 					 const gchar    *mime)
 {
 	guint       request_id;
-	GHashTable *values = NULL;
+	gint        i;
+	GPtrArray   *statements = NULL;
 
 	request_id = tracker_dbus_get_next_request_id ();
 
-	g_return_if_fail (path != NULL);
+	g_return_if_fail (uri != NULL);
 
 	/* NOTE: Don't reset the timeout to shutdown here */
-	values = get_file_metadata (object, request_id, path, mime);
+	statements = get_file_metadata (object, request_id, uri, mime);
 
-	if (values) {
-		g_hash_table_foreach (values, 
-				      print_file_metadata_item, 
-				      GUINT_TO_POINTER (request_id));
-		g_hash_table_destroy (values);
+	if (statements) {
+		statements_free (statements);
 	}
 }
 
@@ -394,22 +394,23 @@ tracker_extract_get_pid (TrackerExtract	        *object,
 
 void
 tracker_extract_get_metadata (TrackerExtract	     *object,
-			      const gchar            *path,
+			      const gchar            *uri,
 			      const gchar            *mime,
 			      DBusGMethodInvocation  *context,
 			      GError		    **error)
 {
 	guint       request_id;
-	GHashTable *values = NULL;
+	gint        i;
+	GPtrArray  *statements = NULL;
 
 	request_id = tracker_dbus_get_next_request_id ();
 
-	tracker_dbus_async_return_if_fail (path != NULL, context);
+	tracker_dbus_async_return_if_fail (uri != NULL, context);
 
 	tracker_dbus_request_new (request_id,
 				  "DBus request to extract metadata, "
-				  "path:'%s', mime:%s",
-				  path,
+				  "uri:'%s', mime:%s",
+				  uri,
 				  mime);
 
 	tracker_dbus_request_debug (request_id,
@@ -418,22 +419,22 @@ tracker_extract_get_metadata (TrackerExtract	     *object,
 	tracker_main_quit_timeout_reset ();
 	alarm (MAX_EXTRACT_TIME);
 
-	values = get_file_metadata (object, request_id, path, mime);
+	statements = get_file_metadata (object, request_id, uri, mime);
 
-	if (values) {
-		g_hash_table_foreach (values, 
-				      print_file_metadata_item, 
-				      GUINT_TO_POINTER (request_id));
-		dbus_g_method_return (context, values);
-		g_hash_table_destroy (values);
+	if (statements) {
+		dbus_g_method_return (context, statements);
+		for (i = 0; i < statements->len; i++) {
+			g_value_array_free (statements->pdata[i]);
+		}
+		g_ptr_array_free (statements, TRUE);
 		tracker_dbus_request_success (request_id);
 	} else {
 		GError *actual_error = NULL;
 
 		tracker_dbus_request_failed (request_id,
 					     &actual_error,
-					     "Could not get any metadata for path:'%s' and mime:'%s'",
-					     path, 
+					     "Could not get any metadata for uri:'%s' and mime:'%s'",
+					     uri, 
 					     mime);
 		dbus_g_method_return_error (context, actual_error);
 		g_error_free (actual_error);
diff --git a/src/tracker-extract/tracker-extract.h b/src/tracker-extract/tracker-extract.h
index 8cc031f..723ec7a 100644
--- a/src/tracker-extract/tracker-extract.h
+++ b/src/tracker-extract/tracker-extract.h
@@ -55,7 +55,7 @@ void            tracker_extract_get_pid                 (TrackerExtract
 							 DBusGMethodInvocation  *context,
 							 GError                **error);
 void            tracker_extract_get_metadata            (TrackerExtract         *object,
-							 const gchar            *path,
+							 const gchar            *uri,
 							 const gchar            *mime,
 							 DBusGMethodInvocation  *context,
 							 GError                **error);
diff --git a/src/tracker-extract/tracker-iptc.c b/src/tracker-extract/tracker-iptc.c
index 88d98a3..0e19a89 100644
--- a/src/tracker-extract/tracker-iptc.c
+++ b/src/tracker-extract/tracker-iptc.c
@@ -20,9 +20,17 @@
 
 #include "config.h"
 
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-statement-list.h>
+
 #include "tracker-iptc.h"
 #include "tracker-main.h"
 
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+
 #include <glib.h>
 #include <string.h>
 
@@ -31,87 +39,36 @@
 #include <libiptcdata/iptc-data.h>
 #include <libiptcdata/iptc-dataset.h>
 
-typedef gchar * (*IptcPostProcessor) (const gchar*);
+typedef const gchar * (*IptcPostProcessor) (const gchar*);
 
 typedef struct {
 	IptcRecord        record;
 	IptcTag           tag;
-	gchar	         *name;
-	gboolean          multi; /* Does the field have multiple values */
+	const gchar      *name;
 	IptcPostProcessor post;
+	const gchar      *urn;
+	const gchar      *rdf_type;
+	const gchar      *predicate;
 } IptcTagType;
 
-static gchar *fix_iptc_orientation (const gchar *orientation);
+static const gchar *fix_iptc_orientation (const gchar *orientation);
 
 static IptcTagType iptctags[] = {
-        { 2, IPTC_TAG_KEYWORDS, "Image:Keywords", TRUE, NULL },
-	/*	{ 2, IPTC_TAG_CONTENT_LOC_NAME, "Image:Location", NULL }, */
-	{ 2, IPTC_TAG_SUBLOCATION, "Image:Location", FALSE, NULL },
-        { 2, IPTC_TAG_DATE_CREATED, "Image:Date", FALSE, NULL },
-        { 2, IPTC_TAG_ORIGINATING_PROGRAM, "Image:Software", FALSE, NULL },
-        { 2, IPTC_TAG_BYLINE, "Image:Creator", FALSE, NULL },
-        { 2, IPTC_TAG_CITY, "Image:City", FALSE, NULL },
-        { 2, IPTC_TAG_COUNTRY_NAME, "Image:Country", FALSE, NULL },
-        { 2, IPTC_TAG_CREDIT, "Image:Creator", FALSE, NULL },
-        { 2, IPTC_TAG_COPYRIGHT_NOTICE, "File:Copyright", FALSE, NULL },
-        { 2, IPTC_TAG_IMAGE_ORIENTATION, "Image:Orientation", FALSE, fix_iptc_orientation },
-	{ -1, -1, NULL, FALSE, NULL }
+        { 2, IPTC_TAG_KEYWORDS, NIE_PREFIX "keyword", NULL, NULL, NULL, NULL }, /* We might have to strtok_r this one? */
+	/*	{ 2, IPTC_TAG_CONTENT_LOC_NAME, "Image:Location", NULL, NULL, NULL, NULL }, */
+	{ 2, IPTC_TAG_SUBLOCATION, "Image:Location", NULL, NULL, NULL, NULL },
+        { 2, IPTC_TAG_DATE_CREATED, NIE_PREFIX "contentCreated", NULL, NULL, NULL, NULL },
+        { 2, IPTC_TAG_ORIGINATING_PROGRAM, "Image:Software", NULL, NULL, NULL, NULL },
+        { 2, IPTC_TAG_BYLINE, NCO_PREFIX "creator", NULL, ":", NCO_PREFIX "Contact", NCO_PREFIX "fullname" },
+        { 2, IPTC_TAG_CITY, "Image:City", NULL, NULL, NULL, NULL },
+        { 2, IPTC_TAG_COUNTRY_NAME, "Image:Country", NULL, NULL, NULL, NULL },
+	{ 2, IPTC_TAG_CREDIT, NCO_PREFIX "creator", NULL, ":", NCO_PREFIX "Contact", NCO_PREFIX "fullname" },
+        { 2, IPTC_TAG_COPYRIGHT_NOTICE, NIE_PREFIX "copyright", NULL, NULL, NULL, NULL },
+        { 2, IPTC_TAG_IMAGE_ORIENTATION, "Image:Orientation", fix_iptc_orientation, NULL, NULL, NULL },
+	{ -1, -1, NULL, NULL, NULL, NULL, NULL }
 };
 
-static void
-metadata_append (GHashTable *metadata, gchar *key, gchar *value, gboolean append)
-{
-	gchar   *new_value;
-	gchar   *orig;
-	gchar  **list;
-	gboolean found = FALSE;
-	guint    i;
-
-	if (append && (orig = g_hash_table_lookup (metadata, key))) {
-		gchar *escaped;
-		
-		escaped = tracker_escape_metadata (value);
-
-		list = g_strsplit (orig, "|", -1);			
-		for (i=0; list[i]; i++) {
-			if (strcmp (list[i], escaped) == 0) {
-				found = TRUE;
-				break;
-			}
-		}			
-		g_strfreev(list);
-
-		if (!found) {
-			new_value = g_strconcat (orig, "|", escaped, NULL);
-			g_hash_table_insert (metadata, g_strdup (key), new_value);
-		}
-
-		g_free (escaped);		
-	} else {
-		new_value = tracker_escape_metadata (value);
-		g_hash_table_insert (metadata, g_strdup (key), new_value);
-
-		/* FIXME Postprocessing is evil and should be elsewhere */
-		if (strcmp (key, "Image:Keywords") == 0) {
-			g_hash_table_insert (metadata,
-					     g_strdup ("Image:HasKeywords"),
-					     tracker_escape_metadata ("1"));			
-		}		
-	}
-
-	/* Adding certain fields also to keywords FIXME Postprocessing is evil */
-	if ((strcmp (key, "Image:Location") == 0) ||
-	    (strcmp (key, "Image:Sublocation") == 0) ||
-	    (strcmp (key, "Image:Country") == 0) ||
-	    (strcmp (key, "Image:City") == 0) ) {
-		metadata_append (metadata, "Image:Keywords", value, TRUE);
-		g_hash_table_insert (metadata,
-				     g_strdup ("Image:HasKeywords"),
-				     tracker_escape_metadata ("1"));
-	}
-}
-
-static gchar *
+static const gchar *
 fix_iptc_orientation (const gchar *orientation)
 {
 	if (strcmp(orientation, "P")==0) {
@@ -127,7 +84,8 @@ fix_iptc_orientation (const gchar *orientation)
 void
 tracker_read_iptc (const unsigned char *buffer,
 		   size_t		len,
-		   GHashTable	       *metadata)
+		   const gchar         *uri,
+		   GPtrArray	       *metadata)
 {
 #ifdef HAVE_LIBIPTCDATA
 	IptcData     *iptc = NULL;
@@ -147,13 +105,22 @@ tracker_read_iptc (const unsigned char *buffer,
 
 		while ( (dataset = iptc_data_get_next_dataset (iptc, dataset, p->record, p->tag) ) ) {
 			gchar buffer[1024];
-			
+			const gchar *what_i_need;
+
 			iptc_dataset_get_as_str (dataset, buffer, 1024);
 			
 			if (p->post) {
-				metadata_append (metadata,p->name,(*p->post) (buffer), p->multi);
+				what_i_need = (*p->post) (buffer);
+			} else {
+				what_i_need = buffer;
+			}
+
+			if (p->urn) {
+				tracker_statement_list_insert (metadata, p->urn, RDF_TYPE, p->rdf_type);
+				tracker_statement_list_insert (metadata, p->urn, p->predicate, what_i_need);
+				tracker_statement_list_insert (metadata, uri, p->name, p->urn);
 			} else {
-				metadata_append (metadata, p->name, buffer, p->multi);
+				tracker_statement_list_insert (metadata, uri, p->name, what_i_need);
 			}
 		}
 	}
diff --git a/src/tracker-extract/tracker-iptc.h b/src/tracker-extract/tracker-iptc.h
index 2788e62..a173aac 100644
--- a/src/tracker-extract/tracker-iptc.h
+++ b/src/tracker-extract/tracker-iptc.h
@@ -6,6 +6,7 @@
 
 void tracker_read_iptc (const unsigned char *buffer,
 			size_t		    len,
-			GHashTable	   *metadata);
+			const gchar        *uri,
+			GPtrArray	   *metadata);
 
 #endif
diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c
index 45cb892..e8e4477 100644
--- a/src/tracker-extract/tracker-main.c
+++ b/src/tracker-extract/tracker-main.c
@@ -286,7 +286,7 @@ main (int argc, char *argv[])
 	if (filename) {
 		TrackerExtract *object;
 		GFile *file;
-		gchar *full_path;
+		gchar *uri;
 
 		object = tracker_extract_new ();
 		if (!object) {
@@ -294,13 +294,13 @@ main (int argc, char *argv[])
 		}
 
 		file = g_file_new_for_commandline_arg (filename);
-		full_path = g_file_get_path (file);
+		uri = g_file_get_uri (file);
 
-		tracker_extract_get_metadata_by_cmdline (object, full_path, mime_type);
+		tracker_extract_get_metadata_by_cmdline (object, uri, mime_type);
 
 		g_object_unref (object);
 		g_object_unref (file);
-		g_free (full_path);
+		g_free (uri);
 
 		return EXIT_SUCCESS;
 	}
diff --git a/src/tracker-extract/tracker-main.h b/src/tracker-extract/tracker-main.h
index ed23470..867b146 100644
--- a/src/tracker-extract/tracker-main.h
+++ b/src/tracker-extract/tracker-main.h
@@ -25,8 +25,7 @@
 #include <glib.h>
 
 #include <libtracker-common/tracker-hal.h>
-
-#include "tracker-escape.h"
+#include <libtracker-common/tracker-statement-list.h>
 
 G_BEGIN_DECLS
 
@@ -38,7 +37,7 @@ struct TrackerExtractData {
 	const gchar *mime;
 
 	void (* extract) (const gchar *path,
-			  GHashTable  *metadata);
+			  GPtrArray   *metadata);
 };
 
 /* This is defined in each extract */
diff --git a/src/tracker-extract/tracker-xmp.c b/src/tracker-extract/tracker-xmp.c
index 08a2c29..b313044 100644
--- a/src/tracker-extract/tracker-xmp.c
+++ b/src/tracker-extract/tracker-xmp.c
@@ -25,15 +25,25 @@
 
 #include <glib.h>
 
-#include "tracker-xmp.h"
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-statement-list.h>
+
 #include "tracker-main.h"
+#include "tracker-xmp.h"
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NCO_PREFIX TRACKER_NCO_PREFIX
+#define DC_PREFIX TRACKER_DC_PREFIX
 
 #ifdef HAVE_EXEMPI
 
 #include <exempi/xmp.h>
 #include <exempi/xmpconsts.h>
 
-static gchar *
+static const gchar *
 fix_metering_mode (const gchar *mode)
 {
 	gint value;
@@ -73,7 +83,7 @@ fix_flash (const gchar *flash)
 		
 }
 
-static gchar *
+static const gchar *
 fix_white_balance (const gchar *wb)
 {
 	gint value;
@@ -87,78 +97,30 @@ fix_white_balance (const gchar *wb)
 
 static void tracker_xmp_iter        (XmpPtr          xmp,
 				     XmpIteratorPtr  iter,
-				     GHashTable     *metadata,
+				     const gchar    *uri,
+				     GPtrArray      *metadata,
 				     gboolean        append);
-static void tracker_xmp_iter_simple (GHashTable     *metadata,
+static void tracker_xmp_iter_simple (const gchar    *uri,
+				     GPtrArray      *metadata,
 				     const gchar    *schema,
 				     const gchar    *path,
 				     const gchar    *value,
 				     gboolean        append);
 
-static void
-tracker_append_string_to_hash_table (GHashTable  *metadata, 
-				     const gchar *key, 
-				     const gchar *value, 
-				     gboolean     append,
-				     gboolean     prio)
-{
-	gchar *new_value;
-
-	if (append) {
-		gchar *orig;
-
-		if ( (orig = g_hash_table_lookup (metadata, key)) ) {
-			gchar   *escaped;
-			gchar  **list;
-			gboolean found = FALSE;
-			guint    i;
-
-			escaped = tracker_escape_metadata (value);
-
-			/* Don't add duplicates. FIXME This is inefficient */
-			list = g_strsplit (orig, "|", -1);			
-			for (i=0; list[i]; i++) {
-				if (strcmp (list[i], escaped) == 0) {
-					found = TRUE;
-					break;
-				}
-			}
-
-			g_strfreev(list);
-
-			if(!found) {
-				new_value = g_strconcat (orig, "|", escaped, NULL);
-				g_hash_table_insert (metadata, g_strdup (key), new_value);						
-			}
-
-			g_free (escaped);
-		} else {
-			new_value = tracker_escape_metadata (value);
-			g_hash_table_insert (metadata, g_strdup (key), new_value);
-		}
-	} else {
-		if (!(g_hash_table_lookup(metadata, key) && !prio)) {
-			new_value = tracker_escape_metadata (value);
-
-			g_hash_table_insert (metadata, g_strdup (key), new_value);		
-		}
-		
-	}
-}
-
 
 /* We have an array, now recursively iterate over it's children.  Set 'append' to true so that all values of the array are added
    under one entry. */
 static void
-tracker_xmp_iter_array (XmpPtr       xmp, 
-			GHashTable  *metadata, 
+tracker_xmp_iter_array (XmpPtr       xmp,
+			const gchar *uri,
+			GPtrArray   *metadata, 
 			const gchar *schema, 
 			const gchar *path)
 {
 	XmpIteratorPtr iter;
 
 	iter = xmp_iterator_new (xmp, schema, path, XMP_ITER_JUSTCHILDREN);
-	tracker_xmp_iter (xmp, iter, metadata, TRUE);
+	tracker_xmp_iter (xmp, iter, uri, metadata, TRUE);
 	xmp_iterator_free (iter);
 }
 
@@ -166,14 +128,15 @@ tracker_xmp_iter_array (XmpPtr       xmp,
 /* We have an array, now recursively iterate over it's children.  Set 'append' to false so that only one item is used. */
 static void
 tracker_xmp_iter_alt_text (XmpPtr       xmp, 
-			   GHashTable  *metadata, 
+			   const gchar *uri,
+			   GPtrArray   *metadata, 
 			   const gchar *schema, 
 			   const gchar *path)
 {
 	XmpIteratorPtr iter;
 
 	iter = xmp_iterator_new (xmp, schema, path, XMP_ITER_JUSTCHILDREN);
-	tracker_xmp_iter (xmp, iter, metadata, FALSE);
+	tracker_xmp_iter (xmp, iter, uri, metadata, FALSE);
 	xmp_iterator_free (iter);
 }
 
@@ -181,7 +144,8 @@ tracker_xmp_iter_alt_text (XmpPtr       xmp,
 /* We have a simple element, but need to iterate over the qualifiers */
 static void
 tracker_xmp_iter_simple_qual (XmpPtr       xmp, 
-			      GHashTable  *metadata,
+			      const gchar *uri,
+			      GPtrArray   *metadata,
 			      const gchar *schema, 
 			      const gchar *path, 
 			      const gchar *value, 
@@ -227,7 +191,7 @@ tracker_xmp_iter_simple_qual (XmpPtr       xmp,
 	}
 
 	if (!ignore_element) {
-		tracker_xmp_iter_simple (metadata, schema, path, value, append);
+		tracker_xmp_iter_simple (uri, metadata, schema, path, value, append);
 	}
 
 	xmp_string_free (the_prop);
@@ -240,7 +204,8 @@ tracker_xmp_iter_simple_qual (XmpPtr       xmp,
  * hash table.
  */
 static void
-tracker_xmp_iter_simple (GHashTable  *metadata,
+tracker_xmp_iter_simple (const gchar *uri,
+			 GPtrArray   *metadata,
 			 const gchar *schema, 
 			 const gchar *path, 
 			 const gchar *value, 
@@ -259,169 +224,205 @@ tracker_xmp_iter_simple (GHashTable  *metadata,
 	/* Dublin Core */
 	if (strcmp (schema, NS_DC) == 0) {
 		if (strcmp (name, "title") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Title", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  "Image:Title", value);
 		}
 		else if (strcmp (name, "rights") == 0) {
-			tracker_append_string_to_hash_table (metadata, "File:Copyright", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  NIE_PREFIX "copyright", value);
 		}
 		else if (strcmp (name, "creator") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Creator", value, append, FALSE);
+
+			tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+			tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", value);
+			tracker_statement_list_insert (metadata, uri, NCO_PREFIX "creator", ":");
+
 		}
 		else if (strcmp (name, "description") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Description", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Description", value);
 		}
 		else if (strcmp (name, "date") == 0) {
-			/* exempi considers this an array while we want a single value */
-			tracker_append_string_to_hash_table (metadata, "Image:Date", value, FALSE, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Date", value);
 		}
 		else if (strcmp (name, "keywords") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Keywords", value, append, FALSE);
-			tracker_append_string_to_hash_table (metadata, "Image:HasKeywords", "1", FALSE, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Keywords", value);
 		}
 		else if (strcmp (name, "subject") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Subject", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  NIE_PREFIX "subject", value);
 
 			/* The subject field may contain keywords as well */
-			tracker_append_string_to_hash_table (metadata, "Image:Keywords", value, TRUE, FALSE);
-			tracker_append_string_to_hash_table (metadata, "Image:HasKeywords", "1", FALSE, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Keywords", value);
 		}
 		else if (strcmp (name, "publisher") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Publisher", value, append, FALSE);
+			tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+			tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", value);
+			tracker_statement_list_insert (metadata, uri, NCO_PREFIX "publisher", ":");
 		}
 		else if (strcmp (name, "contributor") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Contributor", value, append, FALSE);
+			tracker_statement_list_insert (metadata, ":", RDF_TYPE, NCO_PREFIX "Contact");
+			tracker_statement_list_insert (metadata, ":", NCO_PREFIX "fullname", value);
+			tracker_statement_list_insert (metadata, uri, NCO_PREFIX "contributor", ":");
 		}
 		else if (strcmp (name, "type") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Type", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  DC_PREFIX "type", value);
 		}
 		else if (strcmp (name, "format") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Format", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  DC_PREFIX "format", value);
 		}
 		else if (strcmp (name, "identifier") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Identifier", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  DC_PREFIX "identifier", value);
 		}
 		else if (strcmp (name, "source") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Source", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  DC_PREFIX "source", value);
 		}
 		else if (strcmp (name, "language") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Language", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  DC_PREFIX "language", value);
 		}
 		else if (strcmp (name, "relation") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Relation", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  DC_PREFIX "relation", value);
 		}
 		else if (strcmp (name, "coverage") == 0) {
-			tracker_append_string_to_hash_table (metadata, "DC:Coverage", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  DC_PREFIX "coverage", value);
 		}
 
 	}
 	/* Creative Commons */
 	else if (strcmp (schema, NS_CC) == 0) {
 		if (strcmp (name, "license") == 0) {
-			tracker_append_string_to_hash_table (metadata, "File:License", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  NIE_PREFIX "license", value);
 		}
 	}
 	/* Exif basic scheme */
 	else if (strcmp (schema, NS_EXIF) == 0) {
 		if (strcmp (name, "Title") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Title", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Title", value);
 		}
 		else if (strcmp (name, "DateTimeOriginal") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Date", value, append, TRUE);
+			tracker_statement_list_insert (metadata, uri, 
+						  "Image:Date", value);
 		}
 		else if (strcmp (name, "Artist") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Creator", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Creator", value);
 		}
 		else if (strcmp (name, "Software") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Software", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Software", value);
 		}
 		else if (strcmp (name, "Make") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:CameraMake", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  "Image:CameraMake", value);
 		}
 		else if (strcmp (name, "Model") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:CameraModel", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  "Image:CameraModel", value);
 		}
 		else if (strcmp (name, "Orientation") == 0) {
-			tracker_append_string_to_hash_table (metadata, 
-							     "Image:Orientation", 
-							     value, 
-							     append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Orientation", 
+						  value);
 		}
 		else if (strcmp (name, "Flash") == 0) {
-			tracker_append_string_to_hash_table (metadata, 
-							     "Image:Flash", 
-							     fix_flash (value), 
-							     append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Flash", 
+						  fix_flash (value));
 		}
 		else if (strcmp (name, "MeteringMode") == 0) {
-			tracker_append_string_to_hash_table (metadata, 
-							     "Image:MeteringMode", 
-							     fix_metering_mode (value), 
-							     append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:MeteringMode", 
+						  fix_metering_mode (value));
 		}
 		else if (strcmp (name, "ExposureProgram") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:ExposureProgram", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:ExposureProgram", value);
 		}
 		else if (strcmp (name, "ExposureTime") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:ExposureTime", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:ExposureTime", value);
 		}
 		else if (strcmp (name, "FNumber") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:FNumber", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:FNumber", value);
 		}
 		else if (strcmp (name, "FocalLength") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:FocalLength", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  "Image:FocalLength", value);
 		}
 		else if (strcmp (name, "ISOSpeedRatings") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:ISOSpeed", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri, 
+						  "Image:ISOSpeed", value);
 		}
 		else if (strcmp (name, "WhiteBalance") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:WhiteBalance",
-							     fix_white_balance (value), append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:WhiteBalance",
+						   fix_white_balance (value));
 		}
 		else if (strcmp (name, "Copyright") == 0) {
-			tracker_append_string_to_hash_table (metadata, "File:Copyright", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  NIE_PREFIX "copyright", value);
 		}
 	}
 	/* XAP (XMP)scheme */
 	else if (strcmp (schema, NS_XAP) == 0) {
 	        if (strcmp (name, "Rating") == 0) {
-		        tracker_append_string_to_hash_table (metadata, "Image:Rating", value, append, FALSE);
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:Rating", value);
 		}
 		if (strcmp (name, "MetadataDate") == 0) {
-		        tracker_append_string_to_hash_table (metadata, "Image:Date", value, append, FALSE);
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:Date", value);
 		}
 	}
 	/* IPTC4XMP scheme */
 	else if (strcmp (schema,  NS_IPTC4XMP) == 0) {
 	        if (strcmp (name, "Location") == 0) {
-		        tracker_append_string_to_hash_table (metadata, "Image:Location", value, append, FALSE);
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:Location", value);
 
 			/* Added to the valid keywords */
-		        tracker_append_string_to_hash_table (metadata, "Image:Keywords", value, TRUE, FALSE);
-			tracker_append_string_to_hash_table (metadata, "Image:HasKeywords", "1", FALSE, FALSE);
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:Keywords", value);
 		}
 		if (strcmp (name, "Sublocation") == 0) {
-		        tracker_append_string_to_hash_table (metadata, "Image:Sublocation", value, append, FALSE);
-			
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:Sublocation", value);
+
 			/* Added to the valid keywords */
-		        tracker_append_string_to_hash_table (metadata, "Image:Keywords", value, TRUE, FALSE);
-			tracker_append_string_to_hash_table (metadata, "Image:HasKeywords", "1", FALSE, FALSE);
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:Keywords", value);
 		}
 	}
 	/* Photoshop scheme */
 	else if (strcmp (schema,  NS_PHOTOSHOP) == 0) {
 	        if (strcmp (name, "City") == 0) {
-		        tracker_append_string_to_hash_table (metadata, "Image:City", value, append, FALSE);
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:City", value);
 
 			/* Added to the valid keywords */
-		        tracker_append_string_to_hash_table (metadata, "Image:Keywords", value, TRUE, FALSE);
-			tracker_append_string_to_hash_table (metadata, "Image:HasKeywords", "1", FALSE, FALSE);
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:Keywords", value);
 		}
 		else if (strcmp (name, "Country") == 0) {
-			tracker_append_string_to_hash_table (metadata, "Image:Country", value, append, FALSE);
+			tracker_statement_list_insert (metadata, uri,
+						  "Image:Country", value);
 
 			/* Added to the valid keywords */
-		        tracker_append_string_to_hash_table (metadata, "Image:Keywords", value, TRUE, FALSE);
-			tracker_append_string_to_hash_table (metadata, "Image:HasKeywords", "1", FALSE, FALSE);			
+		        tracker_statement_list_insert (metadata, uri,
+						  "Image:Keywords", value);
 		}
 	}
 
@@ -435,7 +436,8 @@ tracker_xmp_iter_simple (GHashTable  *metadata,
 void
 tracker_xmp_iter (XmpPtr          xmp, 
 		  XmpIteratorPtr  iter, 
-		  GHashTable     *metadata, 
+		  const gchar    *uri,
+		  GPtrArray      *metadata, 
 		  gboolean        append)
 {
 	XmpStringPtr the_schema = xmp_string_new ();
@@ -451,18 +453,18 @@ tracker_xmp_iter (XmpPtr          xmp,
 		if (XMP_IS_PROP_SIMPLE (opt)) {
 			if (strcmp (path,"") != 0) {
 				if (XMP_HAS_PROP_QUALIFIERS (opt)) {
-					tracker_xmp_iter_simple_qual (xmp, metadata, schema, path, value, append);
+					tracker_xmp_iter_simple_qual (xmp, uri, metadata, schema, path, value, append);
 				} else {
-					tracker_xmp_iter_simple (metadata, schema, path, value, append);
+					tracker_xmp_iter_simple (uri, metadata, schema, path, value, append);
 				}
 			}
 		}
 		else if (XMP_IS_PROP_ARRAY (opt)) {
 			if (XMP_IS_ARRAY_ALTTEXT (opt)) {
-				tracker_xmp_iter_alt_text (xmp, metadata, schema, path);
+				tracker_xmp_iter_alt_text (xmp, uri, metadata, schema, path);
 				xmp_iterator_skip (iter, XMP_ITER_SKIPSUBTREE);
 			} else {
-				tracker_xmp_iter_array (xmp, metadata, schema, path);
+				tracker_xmp_iter_array (xmp, uri, metadata, schema, path);
 				xmp_iterator_skip (iter, XMP_ITER_SKIPSUBTREE);
 			}
 		}
@@ -478,7 +480,8 @@ tracker_xmp_iter (XmpPtr          xmp,
 void
 tracker_read_xmp (const gchar *buffer, 
 		  size_t       len, 
-		  GHashTable  *metadata)
+		  const gchar *uri,
+		  GPtrArray   *metadata)
 {
 #ifdef HAVE_EXEMPI
 	XmpPtr xmp;
@@ -492,7 +495,7 @@ tracker_read_xmp (const gchar *buffer,
 		XmpIteratorPtr iter;
 
 		iter = xmp_iterator_new (xmp, NULL, NULL, XMP_ITER_PROPERTIES);
-		tracker_xmp_iter (xmp, iter, metadata, FALSE);
+		tracker_xmp_iter (xmp, iter, uri, metadata, FALSE);
 		xmp_iterator_free (iter);
 		xmp_free (xmp);
 	}
diff --git a/src/tracker-extract/tracker-xmp.h b/src/tracker-extract/tracker-xmp.h
index eb14a0f..b8e18af 100644
--- a/src/tracker-extract/tracker-xmp.h
+++ b/src/tracker-extract/tracker-xmp.h
@@ -22,6 +22,6 @@
 
 #include <glib.h>
 
-void tracker_read_xmp (const gchar *buffer, size_t len, GHashTable *metadata);
+void tracker_read_xmp (const gchar *buffer, size_t len, const gchar *uri, GPtrArray *metadata);
 
 #endif /* _TRACKER_XMP_H_ */
diff --git a/src/tracker-fts/tracker-fts.c b/src/tracker-fts/tracker-fts.c
index d7fe8b5..5fa6414 100644
--- a/src/tracker-fts/tracker-fts.c
+++ b/src/tracker-fts/tracker-fts.c
@@ -324,7 +324,7 @@ db_metadata_get (TrackerDBInterface *iface,
 	g_return_val_if_fail (id, NULL);
 	g_return_val_if_fail (key, NULL);
 
-	def = tracker_ontology_get_field_by_name (key);
+	def = tracker_ontology_get_property_by_name (key);
 	
 	if (!def) {
 		g_warning ("Metadata not found for id:'%s' and type:'%s'", id, key);
@@ -332,8 +332,7 @@ db_metadata_get (TrackerDBInterface *iface,
 	}
 
 	switch (tracker_property_get_data_type (def)) {
-	case TRACKER_PROPERTY_TYPE_INDEX:
-	case TRACKER_PROPERTY_TYPE_STRING:
+	/*case TRACKER_PROPERTY_TYPE_STRING:
 	case TRACKER_PROPERTY_TYPE_DOUBLE:
 		proc = "GetMetadata";
 		break;
@@ -345,11 +344,7 @@ db_metadata_get (TrackerDBInterface *iface,
 
 	case TRACKER_PROPERTY_TYPE_FULLTEXT:
 		proc = "GetContents";
-		break;
-
-	case TRACKER_PROPERTY_TYPE_KEYWORD:
-		proc = "GetMetadataKeyword";
-		break;
+		break;*/
 		
 	default:
 		g_warning ("Metadata could not be retrieved as type:%d is not supported", 
@@ -357,12 +352,12 @@ db_metadata_get (TrackerDBInterface *iface,
 		return NULL;
 	}
 
-	return tracker_db_interface_execute_procedure (iface,
+	/*return tracker_db_interface_execute_procedure (iface,
 						       NULL, 
 				     		       proc, 
 				     		       id, 
 				     		       tracker_property_get_id (def),
-				     		       NULL);
+				     		       NULL);*/
 }
 
 static gchar *
@@ -395,13 +390,14 @@ db_get_text (const char     *service,
 static inline int
 get_metadata_weight (int id)
 {
-  if (id == 0) return 1;
+	/* TODO */
+  /*if (id == 0)*/ return 1;
 
-  TrackerProperty *field = tracker_ontology_get_field_by_id (id);
+  /*TrackerProperty *field = tracker_ontology_get_property_by_id (id);
   
   if (!field) return 1;
 
-  return tracker_property_get_weight (field);
+  return tracker_property_get_weight (field);*/
 
 }
 
diff --git a/src/tracker-indexer/modules/applications.c b/src/tracker-indexer/modules/applications.c
index f4d398d..87d2440 100644
--- a/src/tracker-indexer/modules/applications.c
+++ b/src/tracker-indexer/modules/applications.c
@@ -25,19 +25,27 @@
 
 #include <glib.h>
 
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-common/tracker-utils.h>
+
 #include <tracker-indexer/tracker-module.h>
+#include <libtracker-data/tracker-data-update.h>
+#include <libtracker-data/tracker-data-manager.h>
+#include <libtracker-data/tracker-data-query.h>
+
+#define RDF_TYPE 	TRACKER_RDF_PREFIX "type"
+#define NFO_PREFIX	TRACKER_NFO_PREFIX
+#define NIE_PREFIX	TRACKER_NIE_PREFIX
+#define MAEMO_PREFIX	TRACKER_MAEMO_PREFIX
 
 #define GROUP_DESKTOP_ENTRY "Desktop Entry"
-#define KEY_TYPE	    "Type"
-#define KEY_HIDDEN	    "Hidden"
-#define KEY_NAME	    "Name"
-#define KEY_GENERIC_NAME    "GenericName"
-#define KEY_COMMENT	    "Comment"
-#define KEY_EXECUTABLE	    "Exec"
-#define KEY_ICON	    "Icon"
-#define KEY_MIMETYPE	    "MimeType"
-#define KEY_CATEGORIES	    "Categories"
 
+#define APPLICATION_DATASOURCE_URN	    "urn:nepomuk:datasource:84f20000-1241-11de-8c30-0800200c9a66"
+#define APPLET_DATASOURCE_URN		    "urn:nepomuk:datasource:192bd060-1f9a-11de-8c30-0800200c9a66"
+#define SOFTWARE_CATEGORY_URN_PREFIX	    "urn:software-category:"
+#define THEME_ICON_URN_PREFIX		    "urn:theme-icon:"
+
+/*
 #define METADATA_FILE_NAME	  "File:Name"
 #define METADATA_APP_NAME	  "App:Name"
 #define METADATA_APP_DISPLAY_NAME "App:DisplayName"
@@ -47,6 +55,7 @@
 #define METADATA_APP_ICON	  "App:Icon"
 #define METADATA_APP_MIMETYPE	  "App:MimeType"
 #define METADATA_APP_CATEGORIES   "App:Categories"
+*/
 
 #define TRACKER_TYPE_APPLICATION_FILE    (tracker_application_file_get_type ())
 #define TRACKER_APPLICATION_FILE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), TRACKER_TYPE_APPLICATION_FILE, TrackerApplicationFile))
@@ -55,11 +64,11 @@ typedef struct TrackerApplicationFile TrackerApplicationFile;
 typedef struct TrackerApplicationFileClass TrackerApplicationFileClass;
 
 struct TrackerApplicationFile {
-        TrackerModuleFile parent_instance;
+	TrackerModuleFile parent_instance;
 };
 
 struct TrackerApplicationFileClass {
-        TrackerModuleFileClass parent_class;
+	TrackerModuleFileClass parent_class;
 };
 
 static GType                   tracker_application_file_get_type      (void) G_GNUC_CONST;
@@ -72,9 +81,9 @@ G_DEFINE_DYNAMIC_TYPE (TrackerApplicationFile, tracker_application_file, TRACKER
 static void
 tracker_application_file_class_init (TrackerApplicationFileClass *klass)
 {
-        TrackerModuleFileClass *file_class = TRACKER_MODULE_FILE_CLASS (klass);
+	TrackerModuleFileClass *file_class = TRACKER_MODULE_FILE_CLASS (klass);
 
-        file_class->get_metadata = tracker_application_file_get_metadata;
+	file_class->get_metadata = tracker_application_file_get_metadata;
 }
 
 static void
@@ -89,6 +98,7 @@ tracker_application_file_init (TrackerApplicationFile *file)
 
 static void
 insert_data_from_desktop_file (TrackerModuleMetadata *metadata,
+			       const gchar           *subject,
 			       const gchar           *metadata_key,
 			       GKeyFile              *desktop_file,
 			       const gchar           *key,
@@ -103,100 +113,179 @@ insert_data_from_desktop_file (TrackerModuleMetadata *metadata,
 	}
 
 	if (str) {
-		tracker_module_metadata_add_string (metadata, metadata_key, str);
+		tracker_module_metadata_add_string (metadata, subject, metadata_key, str);
 		g_free (str);
 	}
 }
 
-static void
-insert_list_from_desktop_file (TrackerModuleMetadata *metadata,
-			       const gchar           *metadata_key,
-			       GKeyFile              *desktop_file,
-			       const gchar           *key,
-			       gboolean		      use_locale)
-{
-	gchar **arr;
-
-	if (use_locale) {
-		arr = g_key_file_get_locale_string_list (desktop_file, GROUP_DESKTOP_ENTRY, key, NULL, NULL, NULL);
-	} else {
-		arr = g_key_file_get_string_list (desktop_file, GROUP_DESKTOP_ENTRY, key, NULL, NULL);
-	}
-
-	if (arr) {
-		gint i;
-
-		for (i = 0; arr[i]; i++) {
-			tracker_module_metadata_add_string (metadata, metadata_key, arr[i]);
-		}
-
-		g_strfreev (arr);
-	}
-}
 
 static TrackerModuleMetadata *
 tracker_application_file_get_metadata (TrackerModuleFile *file)
 {
-	TrackerModuleMetadata *metadata;
+	TrackerModuleMetadata *metadata = NULL;
 	GKeyFile *key_file;
-        GFile *f;
-	gchar *path, *type, *filename;
+	GFile *f;
+	gchar *path, *type, *filename, *name = NULL, *uri = NULL;
+	GStrv cats = NULL;
+	gsize cats_len;
 
-        f = tracker_module_file_get_file (file);
-        path = g_file_get_path (f);
+	f = tracker_module_file_get_file (file);
+	path = g_file_get_path (f);
 
 	/* Check we're dealing with a desktop file */
 	if (!g_str_has_suffix (path, ".desktop")) {
-                g_free (path);
+		g_free (path);
 		return NULL;
 	}
 
 	key_file = g_key_file_new ();
 
 	if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, NULL)) {
-                g_debug ("Couldn't load desktop file:'%s'", path);
+		g_debug ("Couldn't load desktop file:'%s'", path);
 		g_key_file_free (key_file);
-                g_free (path);
+		g_free (path);
 		return NULL;
 	}
 
-	if (g_key_file_get_boolean (key_file, GROUP_DESKTOP_ENTRY, KEY_HIDDEN, NULL)) {
-                g_debug ("Desktop file is 'hidden', not gathering metadata for it");
+	if (g_key_file_get_boolean (key_file, GROUP_DESKTOP_ENTRY, "Hidden", NULL)) {
+		g_debug ("Desktop file is 'hidden', not gathering metadata for it");
 		g_key_file_free (key_file);
-                g_free (path);
+		g_free (path);
 		return NULL;
 	}
 
-	type = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, KEY_TYPE, NULL);
+	type = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Type", NULL);
 
-	if (!type || g_ascii_strcasecmp (type, "Application") != 0) {
-                g_debug ("Desktop file is not of type 'Application', not gathering metadata for it");
+	if (!type) {
 		g_key_file_free (key_file);
 		g_free (type);
-                g_free (path);
+		g_free (path);
 		return NULL;
 	}
 
-	/* Begin collecting data */
-	metadata = tracker_module_metadata_new ();
+	
+	cats = g_key_file_get_locale_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", NULL, &cats_len, NULL);
+
+	if (!cats)
+		cats = g_key_file_get_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", &cats_len, NULL);
+
+	name = g_key_file_get_locale_string (key_file, GROUP_DESKTOP_ENTRY, "Name", NULL, NULL);
+
+	if (!name)
+		g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Name", NULL);
+
+	if (name && g_ascii_strcasecmp (type, "Directory") == 0) {
+		gchar *canonical_uri = tracker_uri_printf_escaped (SOFTWARE_CATEGORY_URN_PREFIX "%s", name);
+		gchar *icon = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Icon", NULL);
+
+		uri = NULL;
+		metadata = tracker_module_metadata_new ();
+
+		if (icon) {
+			gchar *icon_uri = g_strdup_printf (THEME_ICON_URN_PREFIX "%s", icon);
+			tracker_module_metadata_add_string (metadata, icon_uri, RDF_TYPE, NFO_PREFIX "Image");
+			tracker_module_metadata_add_string (metadata, canonical_uri, NFO_PREFIX "softwareCategoryIcon", icon_uri);
+			g_free (icon_uri);
+			g_free (icon);
+		}
+
+		tracker_module_metadata_add_string (metadata, canonical_uri, RDF_TYPE, NFO_PREFIX "SoftwareCategory");
+		tracker_module_metadata_add_string (metadata, canonical_uri, NIE_PREFIX "title", name);
+		g_free (canonical_uri);
+
+	} else if (name && g_ascii_strcasecmp (type, "Application") == 0) {
 
-	insert_data_from_desktop_file (metadata, METADATA_APP_NAME, key_file, KEY_NAME, FALSE);
-	insert_data_from_desktop_file (metadata, METADATA_APP_DISPLAY_NAME, key_file, KEY_NAME, TRUE);
-	insert_data_from_desktop_file (metadata, METADATA_APP_GENERIC_NAME, key_file, KEY_GENERIC_NAME, TRUE);
-	insert_data_from_desktop_file (metadata, METADATA_APP_COMMENT, key_file, KEY_COMMENT, TRUE);
-	insert_data_from_desktop_file (metadata, METADATA_APP_EXECUTABLE, key_file, KEY_EXECUTABLE, FALSE);
-	insert_data_from_desktop_file (metadata, METADATA_APP_ICON, key_file, KEY_ICON, FALSE);
+		uri = tracker_module_file_get_uri (file);
+		metadata = tracker_module_metadata_new ();
 
-	insert_list_from_desktop_file (metadata, METADATA_APP_MIMETYPE, key_file, KEY_MIMETYPE, FALSE);
-	insert_list_from_desktop_file (metadata, METADATA_APP_CATEGORIES, key_file, KEY_CATEGORIES, FALSE);
+		tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NFO_PREFIX "SoftwareApplication");
+
+		if (!tracker_data_query_resource_exists (APPLICATION_DATASOURCE_URN, NULL, NULL)) {
+			tracker_module_metadata_add_string (metadata, APPLICATION_DATASOURCE_URN, 
+							    RDF_TYPE, NIE_PREFIX "DataSource");
+		}
+
+		tracker_module_metadata_add_string (metadata, uri, NIE_PREFIX "dataSource",
+						    APPLICATION_DATASOURCE_URN);
+
+	/* This matches SomeApplet as Type= */
+	} else if (name && g_str_has_suffix (type, "Applet")) {
+
+		uri = tracker_module_file_get_uri (file);
+		metadata = tracker_module_metadata_new ();
+
+		/* TODO This is atm specific for Maemo */
+		tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, MAEMO_PREFIX "SoftwareApplet");
+
+		if (!tracker_data_query_resource_exists (APPLET_DATASOURCE_URN, NULL, NULL)) {
+			tracker_module_metadata_add_string (metadata, APPLET_DATASOURCE_URN, 
+							    RDF_TYPE, NIE_PREFIX "DataSource");
+		}
+
+		tracker_module_metadata_add_string (metadata, uri, NIE_PREFIX "dataSource",
+						    APPLET_DATASOURCE_URN);
+
+	}
+
+	if (metadata && uri) {
+		gchar *icon;
+
+		tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NFO_PREFIX "Executable");
+		tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NFO_PREFIX "FileDataObject");
+		tracker_module_metadata_add_string (metadata, uri, NIE_PREFIX "title", name);
+
+		insert_data_from_desktop_file (metadata, uri, NIE_PREFIX "comment", key_file, "Comment", TRUE);
+		insert_data_from_desktop_file (metadata, uri, NFO_PREFIX "softwareCmdLine", key_file, "Exec", TRUE);
+
+		icon = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Icon", NULL);
+
+		if (icon) {
+			gchar *icon_uri = g_strdup_printf (THEME_ICON_URN_PREFIX "%s", icon);
+			tracker_module_metadata_add_string (metadata, icon_uri, RDF_TYPE, NFO_PREFIX "Image");
+			tracker_module_metadata_add_string (metadata, uri, NFO_PREFIX "softwareIcon", icon_uri);
+			g_free (icon_uri);
+			g_free (icon);
+		}
+
+		if (cats) {
+			gsize i;
+
+			for (i = 0 ; cats[i] && i < cats_len ; i++) {
+				gchar *cat_uri = tracker_uri_printf_escaped (SOFTWARE_CATEGORY_URN_PREFIX "%s", cats[i]);
+
+				if (!tracker_data_query_resource_exists (cat_uri, NULL, NULL)) {
+
+					/* Oeps, first time we see the category, there are also .desktop
+					 * files that describe these categories, but we can handle 
+					 * preemptively creating them if we visit a app .desktop
+					 * file that mentions one that we don't yet know about */
+
+					tracker_data_insert_statement (cat_uri, RDF_TYPE, NFO_PREFIX "SoftwareCategory");
+					tracker_data_insert_statement (cat_uri, NIE_PREFIX "title", cats[i]);
+				}
+
+				tracker_module_metadata_add_string (metadata, uri, NFO_PREFIX "belongsToContainer", cat_uri);
+
+				g_free (cat_uri);
+			}
+		}
+
+		tracker_module_metadata_add_string (metadata, uri, NIE_PREFIX "dataSource",
+						    APPLICATION_DATASOURCE_URN);
+
+		filename = g_filename_display_basename (path);
+		tracker_module_metadata_add_string (metadata, uri, NFO_PREFIX "fileName", filename);
+		g_free (filename);
+	}
 
-	filename = g_filename_display_basename (path);
-	tracker_module_metadata_add_string (metadata, METADATA_FILE_NAME, filename);
-	g_free (filename);
+	if (cats)
+		g_strfreev (cats);
 
+	g_free (uri);
 	g_key_file_free (key_file);
 	g_free (type);
-        g_free (path);
+	g_free (path);
+	g_free (name);
 
 	return metadata;
 }
@@ -205,7 +294,7 @@ tracker_application_file_get_metadata (TrackerModuleFile *file)
 void
 indexer_module_initialize (GTypeModule *module)
 {
-        tracker_application_file_register_type (module);
+	tracker_application_file_register_type (module);
 }
 
 void
@@ -216,7 +305,7 @@ indexer_module_shutdown (void)
 TrackerModuleFile *
 indexer_module_create_file (GFile *file)
 {
-        return g_object_new (TRACKER_TYPE_APPLICATION_FILE,
-                             "file", file,
-                             NULL);
+	return g_object_new (TRACKER_TYPE_APPLICATION_FILE,
+	                     "file", file,
+	                     NULL);
 }
diff --git a/src/tracker-indexer/modules/evolution-common.c b/src/tracker-indexer/modules/evolution-common.c
index be383e4..fec5bf1 100644
--- a/src/tracker-indexer/modules/evolution-common.c
+++ b/src/tracker-indexer/modules/evolution-common.c
@@ -30,6 +30,7 @@
 #include <glib/gstdio.h>
 
 #include <tracker-indexer/tracker-module-metadata-utils.h>
+#include <tracker-indexer/tracker-module-metadata.h>
 
 #include "evolution-common.h"
 
@@ -56,10 +57,29 @@ evolution_common_get_stream (const gchar *path,
 	return stream;
 }
 
-TrackerModuleMetadata *
-evolution_common_get_wrapper_metadata (GMimeDataWrapper *wrapper)
-{
+typedef struct {
+	const gchar *subject;
 	TrackerModuleMetadata *metadata;
+} WrapInfo;
+
+static void
+foreach_wrap_metadata (const gchar     *subject,
+		       const gchar     *predicate,
+		       const gchar     *object,
+		       gpointer      user_data)
+{
+	WrapInfo *info = user_data;
+
+	tracker_module_metadata_add_string (info->metadata, 
+					    info->subject, 
+					    predicate, object);
+}
+
+void
+evolution_common_get_wrapper_metadata (GMimeDataWrapper *wrapper, 
+				       TrackerModuleMetadata *metadata, 
+				       const gchar *subject)
+{
 	GMimeStream *stream;
 	gchar *path;
 	gint fd;
@@ -71,14 +91,24 @@ evolution_common_get_wrapper_metadata (GMimeDataWrapper *wrapper)
 	stream = g_mime_stream_fs_new (fd);
 
 	if (g_mime_data_wrapper_write_to_stream (wrapper, stream) != -1) {
-                GFile *file;
+		GFile *file;
+		TrackerModuleMetadata *f_metadata;
+		WrapInfo info;
 
-                file = g_file_new_for_path (path);
+		info.subject = subject;
+		info.metadata = metadata;
+
+		file = g_file_new_for_path (path);
 		g_mime_stream_flush (stream);
 
-		metadata = tracker_module_metadata_utils_get_data (file);
+		f_metadata = tracker_module_metadata_utils_get_data (file);
+
+		tracker_module_metadata_foreach (f_metadata, 
+						 foreach_wrap_metadata,
+						 &info);
 
-                g_object_unref (file);
+		g_object_unref (f_metadata);
+		g_object_unref (file);
 		g_unlink (path);
 	}
 
@@ -86,7 +116,7 @@ evolution_common_get_wrapper_metadata (GMimeDataWrapper *wrapper)
 	g_object_unref (stream);
 	g_free (path);
 
-	return metadata;
+	return;
 }
 
 gchar *
diff --git a/src/tracker-indexer/modules/evolution-common.h b/src/tracker-indexer/modules/evolution-common.h
index 043a783..81aa3eb 100644
--- a/src/tracker-indexer/modules/evolution-common.h
+++ b/src/tracker-indexer/modules/evolution-common.h
@@ -26,18 +26,15 @@
 
 #include <gmime/gmime.h>
 
-#include <libtracker-data/tracker-data-metadata.h>
-
 G_BEGIN_DECLS
 
-#define METADATA_FILE_PATH	     "File:Path"
 #define METADATA_FILE_NAME	     "File:Name"
-#define METADATA_EMAIL_RECIPIENT     "Email:Recipient"
-#define METADATA_EMAIL_DATE	     "Email:Date"
-#define METADATA_EMAIL_SENDER	     "Email:Sender"
-#define METADATA_EMAIL_SUBJECT	     "Email:Subject"
-#define METADATA_EMAIL_SENT_TO	     "Email:SentTo"
-#define METADATA_EMAIL_CC	     "Email:CC"
+#define METADATA_EMAIL_RECIPIENT     "nmo:recipient"
+#define METADATA_EMAIL_DATE	     "nmo:sentDate"
+#define METADATA_EMAIL_SENDER	     "nmo:sender"
+#define METADATA_EMAIL_SUBJECT	     "nmo:messageSubject"
+#define METADATA_EMAIL_SENT_TO	     "nmo:to"
+#define METADATA_EMAIL_CC	     "nmo:cc"
 
 enum EvolutionFlags {
 	EVOLUTION_MESSAGE_ANSWERED     = 1 << 0,
@@ -54,7 +51,9 @@ enum EvolutionFlags {
 GMimeStream *           evolution_common_get_stream           (const gchar      *path,
 							       gint              flags,
 							       off_t             start);
-TrackerModuleMetadata * evolution_common_get_wrapper_metadata (GMimeDataWrapper *wrapper);
+void                    evolution_common_get_wrapper_metadata (GMimeDataWrapper *wrapper,
+							       TrackerModuleMetadata *metadata, 
+							       const gchar *subject);
 gchar *                 evolution_common_get_object_encoding  (GMimeObject      *object);
 
 G_END_DECLS
diff --git a/src/tracker-indexer/modules/evolution-imap.c b/src/tracker-indexer/modules/evolution-imap.c
index ae1b224..7d3eb56 100644
--- a/src/tracker-indexer/modules/evolution-imap.c
+++ b/src/tracker-indexer/modules/evolution-imap.c
@@ -25,7 +25,8 @@
 
 #include <gconf/gconf-client.h>
 
-#include <libtracker-data/tracker-data-metadata.h>
+#include <libtracker-common/tracker-common.h>
+#include <libtracker-common/tracker-ontology.h>
 
 #include <tracker-indexer/tracker-module-file.h>
 #include <tracker-indexer/tracker-module-iteratable.h>
@@ -33,12 +34,11 @@
 #include "evolution-imap.h"
 #include "evolution-common.h"
 
-#define METADATA_EMAIL_RECIPIENT     "Email:Recipient"
-#define METADATA_EMAIL_DATE	     "Email:Date"
-#define METADATA_EMAIL_SENDER	     "Email:Sender"
-#define METADATA_EMAIL_SUBJECT	     "Email:Subject"
-#define METADATA_EMAIL_SENT_TO	     "Email:SentTo"
-#define METADATA_EMAIL_CC	     "Email:CC"
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+#define NMO_PREFIX TRACKER_NMO_PREFIX
+
 
 #define MODULE_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) \
 { \
@@ -70,7 +70,6 @@ static GHashTable *accounts = NULL;
 static void          tracker_evolution_imap_file_finalize         (GObject *object);
 
 static void          tracker_evolution_imap_file_initialize       (TrackerModuleFile *file);
-static const gchar * tracker_evolution_imap_file_get_service_type (TrackerModuleFile *file);
 static gchar *       tracker_evolution_imap_file_get_uri          (TrackerModuleFile *file);
 static gchar *       tracker_evolution_imap_file_get_text         (TrackerModuleFile *file);
 static TrackerModuleMetadata *
@@ -97,7 +96,6 @@ tracker_evolution_imap_file_class_init (TrackerEvolutionImapFileClass *klass)
         object_class->finalize = tracker_evolution_imap_file_finalize;
 
         file_class->initialize = tracker_evolution_imap_file_initialize;
-        file_class->get_service_type = tracker_evolution_imap_file_get_service_type;
         file_class->get_uri = tracker_evolution_imap_file_get_uri;
         file_class->get_text = tracker_evolution_imap_file_get_text;
         file_class->get_metadata = tracker_evolution_imap_file_get_metadata;
@@ -519,19 +517,6 @@ tracker_evolution_imap_file_initialize (TrackerModuleFile *file)
         ensure_imap_accounts ();
 }
 
-static const gchar *
-tracker_evolution_imap_file_get_service_type (TrackerModuleFile *file)
-{
-        TrackerEvolutionImapFile *self;
-
-        self = TRACKER_EVOLUTION_IMAP_FILE (file);
-
-        if (self->current_mime_part) {
-                return "EvolutionAttachments";
-        }
-
-        return "EvolutionEmails";
-}
 
 static gchar *
 get_message_path (TrackerModuleFile *file,
@@ -879,7 +864,7 @@ get_message_metadata (TrackerModuleFile *file)
 {
         TrackerEvolutionImapFile *self;
 	TrackerModuleMetadata *metadata = NULL;
-	gchar *subject, *from, *to, *cc;
+	gchar *subject, *from, *to, *cc, *uri;
 	gint32 i, count, flags;
 	time_t t;
 	GList *list, *l;
@@ -919,16 +904,20 @@ get_message_metadata (TrackerModuleFile *file)
 	}
 
 	if (!deleted && subject && from) {
+		uri = tracker_module_file_get_uri (file);
+
 		metadata = tracker_module_metadata_new ();
 
-		tracker_module_metadata_add_date (metadata, METADATA_EMAIL_DATE, t);
-		tracker_module_metadata_add_string (metadata, METADATA_EMAIL_SENDER, from);
-		tracker_module_metadata_add_string (metadata, METADATA_EMAIL_SUBJECT, subject);
+		tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NMO_PREFIX "Email");
+
+		tracker_module_metadata_add_date (metadata, uri, METADATA_EMAIL_DATE, t);
+		tracker_module_metadata_add_string (metadata, uri, METADATA_EMAIL_SENDER, from);
+		tracker_module_metadata_add_string (metadata, uri, METADATA_EMAIL_SUBJECT, subject);
 
 		list = get_recipient_list (to);
 
 		for (l = list; l; l = l->next) {
-			tracker_module_metadata_add_string (metadata, METADATA_EMAIL_SENT_TO, l->data);
+			tracker_module_metadata_add_string (metadata, uri, METADATA_EMAIL_SENT_TO, l->data);
 			g_free (l->data);
 		}
 
@@ -937,11 +926,13 @@ get_message_metadata (TrackerModuleFile *file)
 		list = get_recipient_list (cc);
 
 		for (l = list; l; l = l->next) {
-			tracker_module_metadata_add_string (metadata, METADATA_EMAIL_CC, l->data);
+			tracker_module_metadata_add_string (metadata, uri, METADATA_EMAIL_CC, l->data);
 			g_free (l->data);
 		}
 
 		g_list_free (list);
+
+		g_free (uri);
 	}
 
 	g_free (subject);
@@ -1026,7 +1017,7 @@ get_attachment_metadata (TrackerModuleFile *file,
 	GMimeStream *stream;
 	GMimeDataWrapper *wrapper;
 	GMimePartEncodingType encoding;
-	gchar *path, *name;
+	gchar *path, *name, *tmp, *uri;
 
 	if (!get_attachment_info (mime_file, &name, &encoding)) {
 		return NULL;
@@ -1048,7 +1039,25 @@ get_attachment_metadata (TrackerModuleFile *file,
 	}
 
 	wrapper = g_mime_data_wrapper_new_with_stream (stream, encoding);
-	metadata = evolution_common_get_wrapper_metadata (wrapper);
+
+	tmp = tracker_module_file_get_uri (file);
+
+	metadata = tracker_module_metadata_new ();
+
+	/* TODO: we should add 1.1, 1.2, 1.3 as mime-spec per attachment to the 
+	 * URI. Else we don't have a valid URI. Also note that Evolution just
+	 * doesn't support this anyway. (So adding it to the URI and trying to
+	 * index Evolution's attachments is a bit pointless. We can't start/make
+	 * Evolution opening the specific attachment anyway */
+
+	uri = g_strdup_printf ("%s#%s", tmp, mime_file);
+
+	tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NMO_PREFIX "Attachment");
+
+	evolution_common_get_wrapper_metadata (wrapper, metadata, uri);
+
+	g_free (uri);
+	g_free (tmp);
 
 	g_object_unref (wrapper);
 	g_object_unref (stream);
@@ -1061,9 +1070,9 @@ get_attachment_metadata (TrackerModuleFile *file,
 static TrackerModuleMetadata *
 tracker_evolution_imap_file_get_metadata (TrackerModuleFile *file)
 {
-        TrackerEvolutionImapFile *self;
+	TrackerEvolutionImapFile *self;
 
-        self = TRACKER_EVOLUTION_IMAP_FILE (file);
+	self = TRACKER_EVOLUTION_IMAP_FILE (file);
 
 	if (self->cur_message > self->n_messages) {
 		return NULL;
@@ -1072,8 +1081,8 @@ tracker_evolution_imap_file_get_metadata (TrackerModuleFile *file)
 	if (self->current_mime_part) {
 		return get_attachment_metadata (file, self->current_mime_part->data);
 	} else {
-                return get_message_metadata (file);
-        }
+		return get_message_metadata (file);
+	}
 }
 
 static TrackerModuleFlags
diff --git a/src/tracker-indexer/modules/evolution-pop.c b/src/tracker-indexer/modules/evolution-pop.c
index 0802893..1cbfabe 100644
--- a/src/tracker-indexer/modules/evolution-pop.c
+++ b/src/tracker-indexer/modules/evolution-pop.c
@@ -26,7 +26,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <libtracker-data/tracker-data-metadata.h>
+#include <libtracker-common/tracker-common.h>
+#include <libtracker-common/tracker-ontology.h>
 
 #include <tracker-indexer/tracker-module-file.h>
 #include <tracker-indexer/tracker-module-iteratable.h>
@@ -34,6 +35,10 @@
 #include "evolution-pop.h"
 #include "evolution-common.h"
 
+#define NMO_PREFIX TRACKER_NMO_PREFIX
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
 #define MODULE_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) \
 { \
     const GInterfaceInfo g_implement_interface_info = { \
@@ -45,7 +50,6 @@
 static void          tracker_evolution_pop_file_finalize         (GObject *object);
 
 static void          tracker_evolution_pop_file_initialize       (TrackerModuleFile *file);
-static const gchar * tracker_evolution_pop_file_get_service_type (TrackerModuleFile *file);
 static gchar *       tracker_evolution_pop_file_get_uri          (TrackerModuleFile *file);
 static gchar *       tracker_evolution_pop_file_get_text         (TrackerModuleFile *file);
 static TrackerModuleMetadata *
@@ -71,7 +75,6 @@ tracker_evolution_pop_file_class_init (TrackerEvolutionPopFileClass *klass)
         object_class->finalize = tracker_evolution_pop_file_finalize;
 
         file_class->initialize = tracker_evolution_pop_file_initialize;
-        file_class->get_service_type = tracker_evolution_pop_file_get_service_type;
         file_class->get_uri = tracker_evolution_pop_file_get_uri;
         file_class->get_text = tracker_evolution_pop_file_get_text;
         file_class->get_metadata = tracker_evolution_pop_file_get_metadata;
@@ -154,19 +157,6 @@ tracker_evolution_pop_file_initialize (TrackerModuleFile *file)
         g_free (path);
 }
 
-static const gchar *
-tracker_evolution_pop_file_get_service_type (TrackerModuleFile *file)
-{
-        TrackerEvolutionPopFile *self;
-
-        self = TRACKER_EVOLUTION_POP_FILE (file);
-
-        if (self->current_mime_part) {
-                return "EvolutionAttachments";
-        }
-
-        return "EvolutionEmails";
-}
 
 static gint
 get_message_id (GMimeMessage *message)
@@ -338,24 +328,29 @@ get_message_recipients (GMimeMessage *message,
 }
 
 static TrackerModuleMetadata *
-get_message_metadata (GMimeMessage *message)
+get_message_metadata (TrackerModuleFile *file, GMimeMessage *message)
 {
 	TrackerModuleMetadata *metadata;
 	time_t t;
 	GList *list, *l;
+	gchar *uri;
+
+	uri = tracker_module_file_get_uri (file);
 
 	metadata = tracker_module_metadata_new ();
 
+	tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NMO_PREFIX "Email");
+
 	g_mime_message_get_date (message, &t, NULL);
 
-	tracker_module_metadata_add_date (metadata, METADATA_EMAIL_DATE, t);
-	tracker_module_metadata_add_string (metadata, METADATA_EMAIL_SENDER, g_mime_message_get_sender (message));
-	tracker_module_metadata_add_string (metadata, METADATA_EMAIL_SUBJECT, g_mime_message_get_subject (message));
+	tracker_module_metadata_add_date (metadata, uri, METADATA_EMAIL_DATE, t);
+	tracker_module_metadata_add_string (metadata, uri, METADATA_EMAIL_SENDER, g_mime_message_get_sender (message));
+	tracker_module_metadata_add_string (metadata, uri, METADATA_EMAIL_SUBJECT, g_mime_message_get_subject (message));
 
 	list = get_message_recipients (message, GMIME_RECIPIENT_TYPE_TO);
 
 	for (l = list; l; l = l->next) {
-		tracker_module_metadata_add_string (metadata, METADATA_EMAIL_SENT_TO, l->data);
+		tracker_module_metadata_add_string (metadata, uri, METADATA_EMAIL_SENT_TO, l->data);
 		g_free (l->data);
 	}
 
@@ -364,20 +359,23 @@ get_message_metadata (GMimeMessage *message)
 	list = get_message_recipients (message, GMIME_RECIPIENT_TYPE_CC);
 
 	for (l = list; l; l = l->next) {
-		tracker_module_metadata_add_string (metadata, METADATA_EMAIL_CC, l->data);
+		tracker_module_metadata_add_string (metadata, uri, METADATA_EMAIL_CC, l->data);
 		g_free (l->data);
 	}
 
 	g_list_free (list);
 
+	g_free (uri);
+
 	return metadata;
 }
 
 static TrackerModuleMetadata *
-get_attachment_metadata (GMimePart *part)
+get_attachment_metadata (TrackerModuleFile *file, GMimePart *part)
 {
 	TrackerModuleMetadata *metadata;
 	GMimeDataWrapper *content;
+	gchar *tmp, *uri;
 
 	content = g_mime_part_get_content_object (part);
 
@@ -385,7 +383,25 @@ get_attachment_metadata (GMimePart *part)
 		return NULL;
 	}
 
-	metadata = evolution_common_get_wrapper_metadata (content);
+	metadata = tracker_module_metadata_new ();
+
+	tmp = tracker_module_file_get_uri (file);
+
+	/* TODO: we should add 1.1, 1.2, 1.3 as mime-spec per attachment to the 
+	 * URI. Else we don't have a valid URI. Also note that Evolution just
+	 * doesn't support this anyway. (So adding it to the URI and trying to
+	 * index Evolution's attachments is a bit pointless. We can't start/make
+	 * Evolution opening the specific attachment anyway */
+
+	uri = g_strdup_printf ("%s#%s", tmp, g_mime_part_get_content_id (part));
+
+	tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NMO_PREFIX "Attachment");
+
+	evolution_common_get_wrapper_metadata (content, metadata, uri);
+
+	g_free (uri);
+	g_free (tmp);
+
 	g_object_unref (content);
 
 	return metadata;
@@ -411,10 +427,11 @@ tracker_evolution_pop_file_get_metadata (TrackerModuleFile *file)
 		return NULL;
 	}
 
+
         if (self->current_mime_part) {
-                metadata = get_attachment_metadata (self->current_mime_part->data);
+                metadata = get_attachment_metadata (file, self->current_mime_part->data);
         } else {
-                metadata = get_message_metadata (self->message);
+                metadata = get_message_metadata (file, self->message);
         }
 
         return metadata;
diff --git a/src/tracker-indexer/modules/files.c b/src/tracker-indexer/modules/files.c
index 0da0681..2f3de65 100644
--- a/src/tracker-indexer/modules/files.c
+++ b/src/tracker-indexer/modules/files.c
@@ -57,7 +57,6 @@ struct TrackerRegularFileClass {
 
 static GType                   tracker_regular_file_get_type         (void) G_GNUC_CONST;
 
-static const gchar *           tracker_regular_file_get_service_type (TrackerModuleFile *file);
 static gchar *                 tracker_regular_file_get_text         (TrackerModuleFile *file);
 static TrackerModuleMetadata * tracker_regular_file_get_metadata     (TrackerModuleFile *file);
 static void                    tracker_regular_file_cancel           (TrackerModuleFile *file);
@@ -71,7 +70,6 @@ tracker_regular_file_class_init (TrackerRegularFileClass *klass)
 {
         TrackerModuleFileClass *file_class = TRACKER_MODULE_FILE_CLASS (klass);
 
-        file_class->get_service_type = tracker_regular_file_get_service_type;
         file_class->get_text = tracker_regular_file_get_text;
         file_class->get_metadata = tracker_regular_file_get_metadata;
 	file_class->cancel = tracker_regular_file_cancel;
@@ -87,29 +85,6 @@ tracker_regular_file_init (TrackerRegularFile *file)
 {
 }
 
-static const gchar *
-tracker_regular_file_get_service_type (TrackerModuleFile *file)
-{
-        GFile *f;
-	const gchar *service_type;
-	gchar *mime_type, *path;
-
-        f = tracker_module_file_get_file (file);
-
-	if (!g_file_query_exists (f, NULL)) {
-		return NULL;
-	}
-
-	path = g_file_get_path (f);
-
-	mime_type = tracker_file_get_mime_type (path);
-	service_type = tracker_ontology_get_service_by_mime (mime_type);
-
-	g_free (mime_type);
-        g_free (path);
-
-	return service_type;
-}
 
 #ifdef ENABLE_FILE_EXCLUDE_CHECKING
 
diff --git a/src/tracker-indexer/modules/gaim-conversations.c b/src/tracker-indexer/modules/gaim-conversations.c
index 4defdf8..be56060 100644
--- a/src/tracker-indexer/modules/gaim-conversations.c
+++ b/src/tracker-indexer/modules/gaim-conversations.c
@@ -97,11 +97,13 @@ gaim_file_get_metadata (TrackerModuleFile *file)
 {
 	TrackerModuleMetadata *metadata;
 	GFile *f;
-	gchar *path;
+	gchar *path, *uri;
 	gchar **path_decomposed;
 	guint len;
 	struct tm tm;
 
+	uri = tracker_module_file_get_uri (file);
+
 	f = tracker_module_file_get_file (file);
 	path = g_file_get_path (f);
 
@@ -117,16 +119,17 @@ gaim_file_get_metadata (TrackerModuleFile *file)
 
 	metadata = tracker_module_metadata_new ();
 
-	tracker_module_metadata_add_string (metadata, METADATA_CONVERSATION_USER_ACCOUNT, path_decomposed [len - 3]);
-	tracker_module_metadata_add_string (metadata, METADATA_CONVERSATION_PEER_ACCOUNT, path_decomposed [len - 2]);
-	tracker_module_metadata_add_string (metadata, METADATA_CONVERSATION_PROTOCOL, path_decomposed [len - 4]);
+	tracker_module_metadata_add_string (metadata, uri, METADATA_CONVERSATION_USER_ACCOUNT, path_decomposed [len - 3]);
+	tracker_module_metadata_add_string (metadata, uri, METADATA_CONVERSATION_PEER_ACCOUNT, path_decomposed [len - 2]);
+	tracker_module_metadata_add_string (metadata, uri, METADATA_CONVERSATION_PROTOCOL, path_decomposed [len - 4]);
 
 	if (strptime (path_decomposed [len - 1], "%Y-%m-%d.%H%M%S%z", &tm) != NULL) {
-		tracker_module_metadata_add_date (metadata, METADATA_CONVERSATION_DATE, mktime (&tm));
+		tracker_module_metadata_add_date (metadata, uri, METADATA_CONVERSATION_DATE, mktime (&tm));
 	}
 
 	g_strfreev (path_decomposed);
 	g_free (path);
+	g_free (uri);
 
 	return metadata;
 }
diff --git a/src/tracker-indexer/tracker-indexer.c b/src/tracker-indexer/tracker-indexer.c
index 5c50b95..1e54281 100644
--- a/src/tracker-indexer/tracker-indexer.c
+++ b/src/tracker-indexer/tracker-indexer.c
@@ -21,7 +21,12 @@
 
 /* The indexer works as a state machine, there are 3 different queues:
  *
- * * The files queue: the highest priority one, individual files are
+ * * The update queue: the highest priority one, turtle files waiting for
+ *   import and single statements waiting for insertion or deleation are
+ *   taken one by one in order to be processed, when this queue is
+ *   empty, a single token from the next queue is processed.
+ *
+ * * The files queue: second highest priority, individual files are
  *   stored here, waiting for metadata extraction, etc... files are
  *   taken one by one in order to be processed, when this queue is
  *   empty, a single token from the next queue is processed.
@@ -64,10 +69,9 @@
 #include <libtracker-common/tracker-utils.h>
 #include <libtracker-common/tracker-thumbnailer.h>
 
-#include <libtracker-db/tracker-db-manager.h>
 #include <libtracker-db/tracker-db-index-manager.h>
-#include <libtracker-db/tracker-db-interface-sqlite.h>
 
+#include <libtracker-data/tracker-data-manager.h>
 #include <libtracker-data/tracker-data-query.h>
 #include <libtracker-data/tracker-data-update.h>
 #include <libtracker-data/tracker-data-search.h>
@@ -95,20 +99,30 @@
 #define TRACKER_INDEXER_ERROR	    "tracker-indexer-error-domain"
 #define TRACKER_INDEXER_ERROR_CODE  0
 
-/* Properties that change in move event */
-#define METADATA_FILE_NAME_DELIMITED "File:NameDelimited"
-#define METADATA_FILE_EXT	     "File:Ext"
-#define METADATA_FILE_PATH	     "File:Path"
-#define METADATA_FILE_NAME	     "File:Name"
-#define METADATA_FILE_MIMETYPE       "File:Mime"
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+#define TRACKER_PREFIX TRACKER_TRACKER_PREFIX
+
+#define NIE_PLAIN_TEXT_CONTENT NIE_PREFIX "plainTextContent"
+#define NIE_MIME_TYPE NIE_PREFIX "mimeType"
+
+#define TRACKER_DATASOURCE TRACKER_PREFIX "Volume"
+#define NIE_DATASOURCE_P NIE_PREFIX "dataSource"
+
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NFO_FILE_NAME NFO_PREFIX "fileName"
+#define NIE_PLAIN_TEXT_CONTENT NIE_PREFIX "plainTextContent"
+#define NIE_MIME_TYPE NIE_PREFIX "mimeType"
+
 
 typedef struct PathInfo PathInfo;
 typedef struct MetadataForeachData MetadataForeachData;
 typedef struct MetadataRequest MetadataRequest;
-typedef struct UpdateWordsForeachData UpdateWordsForeachData;
 typedef enum TrackerIndexerState TrackerIndexerState;
 
 struct TrackerIndexerPrivate {
+	GQueue *import_queue;
 	GQueue *dir_queue;
 	GQueue *file_queue;
 	GQueue *modules_queue;
@@ -119,14 +133,7 @@ struct TrackerIndexerPrivate {
 
 	gchar *db_dir;
 
-	TrackerDBIndex *file_index;
-	TrackerDBIndex *email_index;
-
-	TrackerDBInterface *file_metadata;
-	TrackerDBInterface *file_contents;
-	TrackerDBInterface *email_metadata;
-	TrackerDBInterface *email_contents;
-	TrackerDBInterface *common;
+	TrackerDBIndex *resources_index;
 
 	TrackerConfig *config;
 	TrackerLanguage *language;
@@ -151,6 +158,8 @@ struct TrackerIndexerPrivate {
 	guint in_process : 1;
 	guint interrupted : 1;
 
+	gboolean turtle_import_in_progress;
+
 	guint state;
 };
 
@@ -168,14 +177,10 @@ struct MetadataForeachData {
 	TrackerConfig *config;
 	TrackerClass *service;
 	gboolean add;
+	const gchar *uri;
 	guint32 id;
 };
 
-struct UpdateWordsForeachData {
-	guint32 service_id;
-	guint32 service_type_id;
-};
-
 enum TrackerIndexerState {
 	TRACKER_INDEXER_STATE_INDEX_OVERLOADED = 1 << 0,
 	TRACKER_INDEXER_STATE_PAUSED	= 1 << 1,
@@ -208,15 +213,13 @@ static void	state_check	       (TrackerIndexer	    *indexer);
 
 static void     item_remove            (TrackerIndexer      *indexer,
 					PathInfo	    *info,
-					const gchar         *dirname,
-					const gchar         *basename);
+					const gchar         *uri);
 static void     check_finished         (TrackerIndexer      *indexer,
 					gboolean             interrupted);
 
 static gboolean item_process           (TrackerIndexer      *indexer,
 					PathInfo            *info,
-					const gchar         *dirname,
-					const gchar         *basename);
+					const gchar         *uri);
 
 
 static guint signals[LAST_SIGNAL] = { 0, };
@@ -276,11 +279,7 @@ start_transaction (TrackerIndexer *indexer)
 
 	indexer->private->in_transaction = TRUE;
 
-	tracker_db_interface_start_transaction (indexer->private->file_contents);
-	tracker_db_interface_start_transaction (indexer->private->email_contents);
-	tracker_db_interface_start_transaction (indexer->private->file_metadata);
-	tracker_db_interface_start_transaction (indexer->private->email_metadata);
-	tracker_db_interface_start_transaction (indexer->private->common);
+	tracker_data_begin_transaction ();
 }
 
 static void
@@ -290,11 +289,7 @@ stop_transaction (TrackerIndexer *indexer)
 		return;
 	}
 
-	tracker_db_interface_end_transaction (indexer->private->common);
-	tracker_db_interface_end_transaction (indexer->private->email_metadata);
-	tracker_db_interface_end_transaction (indexer->private->file_metadata);
-	tracker_db_interface_end_transaction (indexer->private->email_contents);
-	tracker_db_interface_end_transaction (indexer->private->file_contents);
+	tracker_data_commit_transaction ();
 
 	indexer->private->in_transaction = FALSE;
 
@@ -362,8 +357,7 @@ flush_data (TrackerIndexer *indexer)
 		stop_transaction (indexer);
 	}
 
-	tracker_db_index_flush (indexer->private->file_index);
-	tracker_db_index_flush (indexer->private->email_index);
+	tracker_db_index_flush (indexer->private->resources_index);
 
 	if ((indexer->private->state & TRACKER_INDEXER_STATE_STOPPED) == 0) {
 		signal_status (indexer, "flush");
@@ -421,7 +415,6 @@ schedule_flush (TrackerIndexer *indexer,
 							    indexer);
 }
 
-
 void 
 tracker_indexer_transaction_commit (TrackerIndexer *indexer)
 {
@@ -499,8 +492,7 @@ index_flushing_notify_cb (GObject        *object,
 	state = indexer->private->state;
 
 	if ((state & TRACKER_INDEXER_STATE_STOPPED) != 0 &&
-	    !tracker_db_index_get_flushing (indexer->private->file_index) &&
-	    !tracker_db_index_get_flushing (indexer->private->email_index)) {
+	    !tracker_db_index_get_flushing (indexer->private->resources_index)) {
 		/* The indexer has been already stopped and all indices are flushed */
 		check_finished (indexer, indexer->private->interrupted);
 	}
@@ -511,8 +503,7 @@ index_overloaded_notify_cb (GObject        *object,
 			    GParamSpec     *pspec,
 			    TrackerIndexer *indexer)
 {
-	if (tracker_db_index_get_overloaded (indexer->private->file_index) ||
-	    tracker_db_index_get_overloaded (indexer->private->email_index)) {
+	if (tracker_db_index_get_overloaded (indexer->private->resources_index)) {
 		g_debug ("Index overloaded, stopping indexer to let it process items");
 		state_set_flags (indexer, TRACKER_INDEXER_STATE_INDEX_OVERLOADED);
 	} else {
@@ -630,21 +621,13 @@ tracker_indexer_finalize (GObject *object)
 	g_object_unref (priv->language);
 	g_object_unref (priv->config);
 
-	g_signal_handlers_disconnect_by_func (priv->file_index,
+	g_signal_handlers_disconnect_by_func (priv->resources_index,
 					      index_flushing_notify_cb,
 					      object);
-	g_signal_handlers_disconnect_by_func (priv->file_index,
+	g_signal_handlers_disconnect_by_func (priv->resources_index,
 					      index_overloaded_notify_cb,
 					      object);
-	g_object_unref (priv->file_index);
-
-	g_signal_handlers_disconnect_by_func (priv->email_index,
-					      index_flushing_notify_cb,
-					      object);
-	g_signal_handlers_disconnect_by_func (priv->email_index,
-					      index_overloaded_notify_cb,
-					      object);
-	g_object_unref (priv->email_index);
+	g_object_unref (priv->resources_index);
 
 	g_free (priv->db_dir);
 
@@ -662,6 +645,9 @@ tracker_indexer_finalize (GObject *object)
 	g_queue_foreach (priv->file_queue, (GFunc) path_info_free, NULL);
 	g_queue_free (priv->file_queue);
 
+	g_queue_foreach (priv->import_queue, (GFunc) g_free, NULL);
+	g_queue_free (priv->import_queue);
+
 	if (priv->volume_monitor) {
 		g_signal_handlers_disconnect_by_func (priv->volume_monitor,
 						      mount_pre_unmount_cb,
@@ -816,8 +802,7 @@ check_started (TrackerIndexer *indexer)
 	indexer->private->timer = g_timer_new ();
 
 	/* Open indexes */
-	tracker_db_index_open (indexer->private->file_index);
-	tracker_db_index_open (indexer->private->email_index);
+	tracker_db_index_open (indexer->private->resources_index);
 
 	g_signal_emit (indexer, signals[STARTED], 0);
 }
@@ -841,8 +826,7 @@ check_finished (TrackerIndexer *indexer,
 	}
 
 	/* Close indexes */
-	tracker_db_index_close (indexer->private->file_index);
-	tracker_db_index_close (indexer->private->email_index);
+	tracker_db_index_close (indexer->private->resources_index);
 
 	/* Print out how long it took us */
 	str = tracker_seconds_to_string (seconds_elapsed, FALSE);
@@ -879,8 +863,7 @@ check_stopped (TrackerIndexer *indexer,
 		/* If the indexer is stopped and the indices aren't
 		 * being flushed, then it's ready for finishing right away
 		 */
-		if (!tracker_db_index_get_flushing (indexer->private->file_index) &&
-		    !tracker_db_index_get_flushing (indexer->private->email_index)) {
+		if (!tracker_db_index_get_flushing (indexer->private->resources_index)) {
 			check_finished (indexer, interrupted);
 		}
 	}
@@ -978,9 +961,9 @@ tracker_indexer_init (TrackerIndexer *indexer)
 	priv->items_processed = 0;
 	priv->in_transaction = FALSE;
 
+	priv->import_queue = g_queue_new ();
 	priv->dir_queue = g_queue_new ();
 	priv->file_queue = g_queue_new ();
-
 	priv->modules_queue = g_queue_new ();
 	priv->config = tracker_config_new ();
 
@@ -1003,37 +986,16 @@ tracker_indexer_init (TrackerIndexer *indexer)
 	tracker_indexer_load_modules (indexer);
 
 	/* Set up indexer */
-	lindex = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_FILE);
-	priv->file_index = g_object_ref (lindex);
+	lindex = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_RESOURCES);
+	priv->resources_index = g_object_ref (lindex);
 
-	g_signal_connect (priv->file_index, "notify::flushing",
+	g_signal_connect (priv->resources_index, "notify::flushing",
 			  G_CALLBACK (index_flushing_notify_cb), indexer);
-	g_signal_connect (priv->file_index, "notify::overloaded",
+	g_signal_connect (priv->resources_index, "notify::overloaded",
 			  G_CALLBACK (index_overloaded_notify_cb), indexer);
-	g_signal_connect (priv->file_index, "error-received",
+	g_signal_connect (priv->resources_index, "error-received",
 			  G_CALLBACK (index_error_received_cb), indexer);
 
-	lindex = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_EMAIL);
-	priv->email_index = g_object_ref (lindex);
-
-	g_signal_connect (priv->email_index, "notify::flushing",
-			  G_CALLBACK (index_flushing_notify_cb), indexer);
-	g_signal_connect (priv->email_index, "notify::overloaded",
-			  G_CALLBACK (index_overloaded_notify_cb), indexer);
-	g_signal_connect (priv->email_index, "error-received",
-			  G_CALLBACK (index_error_received_cb), indexer);
-
-	/* Set up databases, these pointers are mostly used to
-	 * start/stop transactions, since TrackerDBManager treats
-	 * interfaces as singletons, it's safe to just ask it
-	 * again for an interface.
-	 */
-	priv->common = tracker_db_manager_get_db_interface (TRACKER_DB_COMMON);
-	priv->file_metadata = tracker_db_manager_get_db_interface (TRACKER_DB_FILE_METADATA);
-	priv->file_contents = tracker_db_manager_get_db_interface (TRACKER_DB_FILE_CONTENTS);
-	priv->email_metadata = tracker_db_manager_get_db_interface (TRACKER_DB_EMAIL_METADATA);
-	priv->email_contents = tracker_db_manager_get_db_interface (TRACKER_DB_EMAIL_CONTENTS);
-
 	/* Set up volume monitor */
 	priv->volume_monitor = g_volume_monitor_get ();
 	g_signal_connect (priv->volume_monitor, "mount-pre-unmount",
@@ -1044,6 +1006,17 @@ tracker_indexer_init (TrackerIndexer *indexer)
 }
 
 static void
+add_turtle_file (TrackerIndexer *indexer,
+                 const gchar    *file)
+{
+	g_queue_push_tail (indexer->private->import_queue,
+		g_strdup (file));
+
+	/* Make sure we are still running */
+	check_started (indexer);
+}
+
+static void
 add_file (TrackerIndexer *indexer,
 	  PathInfo *info)
 {
@@ -1064,66 +1037,15 @@ add_directory (TrackerIndexer *indexer,
 }
 
 static void
-index_metadata_item (TrackerProperty	 *field,
-		     const gchar	 *value,
-		     MetadataForeachData *data)
-{
-	TrackerDBIndex *lindex;
-	gchar *parsed_value;
-	gchar **arr;
-	gint service_id;
-	gint i;
-	gint score;
-
-	parsed_value = tracker_parser_text_to_string (value,
-						      data->language,
-						      tracker_config_get_max_word_length (data->config),
-						      tracker_config_get_min_word_length (data->config),
-						      tracker_property_get_filtered (field),
-						      tracker_property_get_filtered (field),
-						      tracker_property_get_delimited (field));
-
-	if (!parsed_value) {
-		return;
-	}
-
-	if (data->add) {
-		score = tracker_property_get_weight (field);
-	} else {
-		score = -1 * tracker_property_get_weight (field);
-	}
-
-	arr = g_strsplit (parsed_value, " ", -1);
-	service_id = tracker_class_get_id (data->service);
-	lindex = tracker_db_index_manager_get_index_by_service_id (service_id);
-
-	for (i = 0; arr[i]; i++) {
-		tracker_db_index_add_word (lindex,
-					   arr[i],
-					   data->id,
-					   tracker_class_get_id (data->service),
-					   score);
-	}
-
-	if (data->add) {
-		tracker_data_update_set_metadata (data->service, data->id, field, (gchar *) value, parsed_value);
-	} else {
-		tracker_data_update_delete_metadata (data->service, data->id, field, (gchar *)value);
-	}
-
-	g_strfreev (arr);
-	g_free (parsed_value);
-}
-
-static void
-index_metadata_foreach (TrackerProperty *field,
-			gpointer      value,
+index_metadata_foreach (const gchar  *subject,
+			const gchar  *predicate,
+			const gchar  *object,
 			gpointer      user_data)
 {
 	MetadataForeachData *data;
 	gint throttle;
 
-	if (!value) {
+	if (!object) {
 		return;
 	}
 
@@ -1135,31 +1057,24 @@ index_metadata_foreach (TrackerProperty *field,
 		tracker_throttle (data->config, throttle * 100);
 	}
 
-	if (!tracker_property_get_multiple_values (field)) {
-		index_metadata_item (field, value, data);
+	if (data->add) {
+		tracker_data_insert_statement (subject, predicate, object);
 	} else {
-		GList *list;
-
-		list = value;
-
-		while (list) {
-			index_metadata_item (field, list->data, data);
-			list = list->next;
-		}
+		tracker_data_delete_statement (subject, predicate, object);
 	}
 }
 
 static void
 index_metadata (TrackerIndexer	      *indexer,
+		const gchar	      *uri,
 		guint32		       id,
-		TrackerClass	      *service,
 		TrackerModuleMetadata *metadata)
 {
 	MetadataForeachData data;
 
 	data.language = indexer->private->language;
 	data.config = indexer->private->config;
-	data.service = service;
+	data.uri = uri;
 	data.id = id;
 	data.add = TRUE;
 
@@ -1169,404 +1084,103 @@ index_metadata (TrackerIndexer	      *indexer,
 }
 
 static void
-unindex_metadata (TrackerIndexer      *indexer,
-		  guint32	       id,
-		  TrackerClass      *service,
-		  TrackerDataMetadata *metadata)
-{
-	MetadataForeachData data;
-
-	data.language = indexer->private->language;
-	data.config = indexer->private->config;
-	data.service = service;
-	data.id = id;
-	data.add = FALSE;
-
-	tracker_data_metadata_foreach (metadata, index_metadata_foreach, &data);
-
-	schedule_flush (indexer, FALSE);
-}
-
-
-static void
-send_text_to_index (TrackerIndexer *indexer,
-		    gint	    service_id,
-		    gint	    service_type,
-		    const gchar    *text,
-		    gboolean	    full_parsing,
-		    gint	    weight_factor)
-{
-	TrackerDBIndex *lindex;
-	GHashTable     *parsed;
-	GHashTableIter	iter;
-	gpointer	key, value;
-
-	if (!text) {
-		return;
-	}
-
-	if (full_parsing) {
-		parsed = tracker_parser_text (NULL,
-					      text,
-					      weight_factor,
-					      indexer->private->language,
-					      tracker_config_get_max_words_to_index (indexer->private->config),
-					      tracker_config_get_max_word_length (indexer->private->config),
-					      tracker_config_get_min_word_length (indexer->private->config),
-					      tracker_config_get_enable_stemmer (indexer->private->config),
-					      FALSE);
-	} else {
-		/* We dont know the exact property weight.
-		   Big value works.
-		 */
-		parsed = tracker_parser_text_fast (NULL,
-						   text,
-						   weight_factor);
-	}
-
-	g_hash_table_iter_init (&iter, parsed);
-
-	lindex = tracker_db_index_manager_get_index_by_service_id (service_type);
-
-	while (g_hash_table_iter_next (&iter, &key, &value)) {
-		tracker_db_index_add_word (lindex,
-					   key,
-					   service_id,
-					   service_type,
-					   GPOINTER_TO_INT (value));
-	}
-
-	g_hash_table_unref (parsed);
-}
-
-static void
-index_text_with_parsing (TrackerIndexer *indexer,
-			 gint		 service_id,
-			 gint		 service_type_id,
-			 const gchar	*content,
-			 gint		 weight_factor)
-{
-	send_text_to_index (indexer,
-			    service_id,
-			    service_type_id,
-			    content,
-			    TRUE,
-			    weight_factor);
-}
-
-static void
-unindex_text_with_parsing (TrackerIndexer *indexer,
-			   gint		   service_id,
-			   gint		   service_type_id,
-			   const gchar	  *content,
-			   gint		   weight_factor)
-{
-	send_text_to_index (indexer,
-			    service_id,
-			    service_type_id,
-			    content,
-			    TRUE,
-			    weight_factor * -1);
-}
-
-static void
-index_text_no_parsing (TrackerIndexer *indexer,
-		       gint	       service_id,
-		       gint	       service_type_id,
-		       const gchar    *content,
-		       gchar	       weight_factor)
-{
-	send_text_to_index (indexer,
-			    service_id,
-			    service_type_id,
-			    content,
-			    FALSE,
-			    weight_factor);
-}
-
-static void
-unindex_text_no_parsing (TrackerIndexer *indexer,
-			 gint		 service_id,
-			 gint		 service_type_id,
-			 const gchar	*content,
-			 gint		 weight_factor)
-{
-	send_text_to_index (indexer,
-			    service_id,
-			    service_type_id,
-			    content,
-			    FALSE,
-			    weight_factor * -1);
-}
-
-static void
-update_word_foreach (gpointer key,
-		     gpointer value,
-		     gpointer user_data)
-{
-	TrackerDBIndex	       *lindex;
-	UpdateWordsForeachData *data;
-	gchar		       *word;
-	gint			score;
-
-	word = key;
-	score = GPOINTER_TO_INT (value);
-
-	data = user_data;
-
-	lindex = tracker_db_index_manager_get_index_by_service_id (data->service_type_id);
-
-	tracker_db_index_add_word (lindex,
-				   word,
-				   data->service_id,
-				   data->service_type_id,
-				   score);
-}
-
-static void
-update_words_no_parsing (TrackerIndexer *indexer,
-			 gint		 service_id,
-			 gint		 service_type_id,
-			 GHashTable	*words)
-{
-	UpdateWordsForeachData user_data;
-
-	user_data.service_id = service_id;
-	user_data.service_type_id = service_type_id;
-
-	g_hash_table_foreach (words, update_word_foreach, &user_data);
-}
-
-static void
-merge_word_table (gpointer key,
-		  gpointer value,
-		  gpointer user_data)
-{
-	GHashTable *new_table;
-	gpointer    k;
-	gpointer    v;
-	gchar	   *word;
-	gint	    new_score;
-
-	word = key;
-	new_score = GPOINTER_TO_INT (value);
-	new_table = user_data;
-
-	if (g_hash_table_lookup_extended (new_table, word, &k, &v)) {
-		gint old_score;
-		gint calculated_score;
-
-		old_score = GPOINTER_TO_INT (v);
-		calculated_score = old_score - new_score;
-
-		if (calculated_score != 0) {
-			g_hash_table_insert (new_table,
-					     g_strdup (word),
-					     GINT_TO_POINTER (calculated_score));
-		} else {
-			/* The word is the same in old and new text */
-			g_hash_table_remove (new_table, word);
-		}
-	} else {
-		g_hash_table_insert (new_table,
-				     g_strdup (word),
-				     GINT_TO_POINTER (0 - new_score));
-	}
-}
-
-static void
 item_update_content (TrackerIndexer *indexer,
-		     TrackerClass *service,
+		     const gchar    *uri,
 		     guint32	     id,
 		     const gchar    *old_text,
 		     const gchar    *new_text)
 {
-	GHashTable *old_words;
-	GHashTable *new_words;
-
 	if (!old_text && !new_text) {
 		return;
 	}
 
-	/* Service has/had full text */
-	old_words = tracker_parser_text (NULL,
-					 old_text,
-					 1,
-					 indexer->private->language,
-					 tracker_config_get_max_words_to_index (indexer->private->config),
-					 tracker_config_get_max_word_length (indexer->private->config),
-					 tracker_config_get_min_word_length (indexer->private->config),
-					 tracker_config_get_enable_stemmer (indexer->private->config),
-					 FALSE);
-
-	new_words = tracker_parser_text (NULL,
-					 new_text,
-					 1,
-					 indexer->private->language,
-					 tracker_config_get_max_words_to_index (indexer->private->config),
-					 tracker_config_get_max_word_length (indexer->private->config),
-					 tracker_config_get_min_word_length (indexer->private->config),
-					 tracker_config_get_enable_stemmer (indexer->private->config),
-					 FALSE);
-
-	/* Merge the score of the words from one and
-	 * other file new_table contains the words
-	 * with the updated scores
-	 */
-	g_hash_table_foreach (old_words, merge_word_table, new_words);
-
-	update_words_no_parsing (indexer,
-				 id,
-				 tracker_class_get_id (service),
-				 new_words);
-
 	/* Remove old text and set new one in the db */
 	if (old_text) {
-		tracker_data_update_delete_content (service, id);
+		tracker_data_delete_statement (uri, NIE_PLAIN_TEXT_CONTENT, old_text);
 	}
 
 	if (new_text) {
-		tracker_data_update_set_content (service, id, new_text);
+		tracker_data_insert_statement (uri, NIE_PLAIN_TEXT_CONTENT, new_text);
 	}
-
-	g_hash_table_unref (old_words);
-	g_hash_table_unref (new_words);
 }
 
-static TrackerClass *
-get_service_for_file (TrackerModuleFile    *file,
-		      TrackerIndexerModule *module)
+static void
+generate_item_thumbnail (TrackerIndexer        *indexer,
+			 const gchar           *uri)
 {
-	const gchar *service_type;
+	gchar *mime_type;
 
-	service_type = tracker_module_file_get_service_type (file);
-
-	if (!service_type) {
-		service_type = tracker_module_config_get_index_service (module->name);
-	}
-
-	if (!service_type) {
-		return NULL;
-	}
-
-	return tracker_ontology_get_service_by_name (service_type);
-}
+	mime_type = tracker_data_query_property_value (uri, NIE_MIME_TYPE);
 
-static gboolean
-remove_existing_non_emb_metadata (TrackerProperty *field,
-				  gpointer      value,
-				  gpointer      user_data)
-{
-	TrackerDataMetadata *old_metadata = (TrackerDataMetadata *) user_data;
-	const gchar *name;
-
-	if (tracker_property_get_embedded (field)) {
-		return FALSE;
+	if (mime_type && tracker_config_get_enable_thumbnails (indexer->private->config)) {
+		tracker_thumbnailer_queue_file (uri, mime_type);
 	}
 
-	name = tracker_property_get_name (field);
-
-	if (tracker_property_get_multiple_values (field)) {
-		return (tracker_data_metadata_lookup_values (old_metadata, name) != NULL);
-	} else {
-		return (tracker_data_metadata_lookup (old_metadata, name) != NULL);
-	}
+	g_free (mime_type);
 }
 
 static void
-remove_stale_children (TrackerIndexer *indexer,
-		       TrackerClass *service,
-		       PathInfo       *parent_info,
-		       const gchar    *path)
+item_add_to_datasource (TrackerIndexer *indexer,
+			const gchar *uri,
+			TrackerModuleFile *module_file,
+			TrackerModuleMetadata *metadata)
 {
-	TrackerDBInterface *iface;
-	gchar **children;
-	PathInfo *info;
-	gint i;
-
-	iface = tracker_db_manager_get_db_interface_by_type (tracker_class_get_name (service),
-							     TRACKER_DB_CONTENT_TYPE_METADATA);
+	GFile *file;
+	const gchar *removable_device_udi;
 
-	children = tracker_data_search_files_get (iface, path);
+	file = tracker_module_file_get_file (module_file);
+	removable_device_udi = tracker_hal_get_volume_udi_for_file (indexer->private->hal, 
+								    file);
 
-	for (i = 0; children[i]; i++) {
-		GFile *file;
+	if (removable_device_udi) {
+		gchar *removable_device_urn;
 
-		file = g_file_new_for_path (children[i]);
+		removable_device_urn = g_strdup_printf (TRACKER_DATASOURCE_URN_PREFIX "%s", 
+						        removable_device_udi);
 
-		if (!g_file_query_exists (file, NULL)) {
-			/* File doesn't exist, check for deletion */
-			info = path_info_new (parent_info->module, file, NULL, TRUE);
-			add_file (indexer, info);
+		if (!tracker_data_query_resource_exists (removable_device_urn, NULL, NULL)) {
+			tracker_data_insert_statement (removable_device_urn, 
+						       RDF_TYPE, TRACKER_DATASOURCE);
 		}
 
-		g_object_unref (file);
-	}
-
-	g_strfreev (children);
-}
-
-static void
-generate_item_thumbnail (TrackerIndexer        *indexer,
-			 const gchar           *dirname,
-			 const gchar           *basename,
-			 TrackerModuleMetadata *metadata)
-{
-	const gchar *path, *mime_type;
-
-	path = tracker_module_metadata_lookup (metadata, METADATA_FILE_NAME_DELIMITED, FALSE);
-	mime_type = tracker_module_metadata_lookup (metadata, METADATA_FILE_MIMETYPE, FALSE);
-
-	if (path && path[0] == G_DIR_SEPARATOR && mime_type &&
-	    tracker_config_get_enable_thumbnails (indexer->private->config)) {
-		GFile *file;
-		gchar *uri;
-
-		file = g_file_new_for_path (path);
-		uri = g_file_get_uri (file);
+		tracker_module_metadata_add_string (metadata, uri, NIE_DATASOURCE_P,
+		                                    removable_device_urn);
 
-		tracker_thumbnailer_queue_file (uri, mime_type);
+		g_free (removable_device_urn);
+	} else {
+		if (!tracker_data_query_resource_exists (TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN, NULL, NULL)) {
+			tracker_data_insert_statement (TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN, 
+						       RDF_TYPE, TRACKER_DATASOURCE);
+		}
 
-		g_object_unref (file);
-		g_free (uri);
+		tracker_module_metadata_add_string (metadata, uri, NIE_DATASOURCE_P,
+						    TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN);
 	}
 }
 
 static void
 item_add_or_update (TrackerIndexer        *indexer,
 		    PathInfo              *info,
-		    const gchar           *dirname,
-		    const gchar           *basename,
+		    const gchar           *uri,
 		    TrackerModuleMetadata *metadata,
 		    const gchar           *text)
 {
-	TrackerClass *service;
 	guint32 id;
 	gchar *mount_point = NULL;
-	gchar *service_path;
-
-	service = get_service_for_file (info->module_file, info->module);
 
-	if (!service) {
-		return;
-	}
-
-	if (tracker_data_query_service_exists (service, dirname, basename, &id, NULL)) {
-		TrackerDataMetadata *old_metadata_emb, *old_metadata_non_emb;
+	if (tracker_data_query_resource_exists (uri, &id, NULL)) {
 		gchar *old_text;
 
 		if (tracker_module_file_get_flags (info->module_file) & TRACKER_FILE_CONTENTS_STATIC) {
 			/* According to the module, the metadata can't change for this item */
-			g_debug ("Not updating static item '%s/%s'",
-				 dirname,
-				 basename);
+			g_debug ("Not updating static item '%s'",
+				 uri);
 			return;
 		}
 
 		/* Update case */
-		g_debug ("Updating item '%s/%s'", 
-			 dirname, 
-			 basename);
+		g_debug ("Updating item '%s'", 
+			 uri);
 
 		/* "metadata" (new metadata) contains embedded props and can contain
 		 * non-embedded properties with default values! Dont overwrite those 
@@ -1577,358 +1191,180 @@ item_add_or_update (TrackerIndexer        *indexer,
 		 *    properties that already have value.
 		 * 3) Save the remain new metadata.
 		 */
-		old_metadata_emb = tracker_data_query_metadata (service, id, TRUE);
-		old_metadata_non_emb = tracker_data_query_metadata (service, id, FALSE);
+		tracker_data_delete_resource_description (uri);
 
-		unindex_metadata (indexer, id, service, old_metadata_emb);
-
-		tracker_module_metadata_foreach_remove (metadata,
-							remove_existing_non_emb_metadata,
-							old_metadata_non_emb);
-
-		index_metadata (indexer, id, service, metadata);
+		index_metadata (indexer, uri, id, metadata);
 
 		/* Take the old text -> the new one, calculate
 		 * difference and add the words.
 		 */
-		old_text = tracker_data_query_content (service, id);
-
-		item_update_content (indexer, service, id, old_text, text);
-
-		if (strcmp (tracker_class_get_name (service), "Folders") == 0) {
-			gchar *path;
-
-			/* Remove no longer existing children, this is necessary in case
-			 * there were files added/removed in a directory between tracker
-			 * executions
-			 */
-
-			path = g_build_path (G_DIR_SEPARATOR_S, dirname, basename, NULL);
-			remove_stale_children (indexer, service, info, path);
-			g_free (path);
-		}
+		old_text = tracker_data_query_property_value (uri, NIE_PLAIN_TEXT_CONTENT);
 
+		item_update_content (indexer, uri, id, old_text, text);
 		g_free (old_text);
-		tracker_data_metadata_free (old_metadata_emb);
-		tracker_data_metadata_free (old_metadata_non_emb);
 	} else {
-		GHashTable *data;
-
-		g_debug ("Adding item '%s/%s'",
-			 dirname,
-			 basename);
+		g_debug ("Adding item '%s'", 
+			 uri);
 
 		/* Service wasn't previously indexed */
-		id = tracker_data_update_get_new_service_id (indexer->private->common);
-		data = tracker_module_metadata_get_hash_table (metadata);
+		id = tracker_data_insert_resource (uri);
 
-		tracker_data_update_create_service (service,
-						    id,
-						    dirname,
-						    basename,
-						    data);
+		index_metadata (indexer, uri, id, metadata);
 
-		index_metadata (indexer, id, service, metadata);
+		item_add_to_datasource (indexer, uri, info->module_file, metadata);
 
 		if (text) {
-			/* Save in the index */
-			index_text_with_parsing (indexer,
-						 id,
-						 tracker_class_get_id (service),
-						 text,
-						 1);
-
 			/* Save in the DB */
-			tracker_data_update_set_content (service, id, text);
+			tracker_data_insert_statement (uri, NIE_PLAIN_TEXT_CONTENT, text);
 		}
-
-		g_hash_table_destroy (data);
 	}
 
-	generate_item_thumbnail (indexer, dirname, basename, metadata);
-
-	/* TODO: URI branch path -> uri */
-
-	service_path = g_build_path (G_DIR_SEPARATOR_S, 
-				     dirname, 
-				     basename, 
-				     NULL);
+	generate_item_thumbnail (indexer, uri);
 
 #ifdef HAVE_HAL
-	if (tracker_hal_path_is_on_removable_device (indexer->private->hal,
-						     service_path, 
-						     &mount_point,
-						     NULL)) {
+	if (tracker_hal_uri_is_on_removable_device (indexer->private->hal,
+						    uri, 
+						    &mount_point,
+						    NULL)) {
 
 		tracker_removable_device_add_metadata (indexer, 
 						       mount_point, 
-						       service_path, 
-						       tracker_class_get_name (service),
+						       uri, 
 						       metadata);
 	}
 #endif
 	g_free (mount_point);
-	g_free (service_path);
-}
-
-
-static gboolean 
-filter_invalid_after_move_properties (TrackerProperty *field,
-				      gpointer value,
-				      gpointer user_data) 
-{
-	const gchar *name;
-
-	name = tracker_property_get_name (field);
-
-	if (g_strcmp0 (name, METADATA_FILE_NAME_DELIMITED) == 0 ||
-	    g_strcmp0 (name, METADATA_FILE_NAME) == 0 ||
-	    g_strcmp0 (name, METADATA_FILE_PATH) == 0 ||
-	    g_strcmp0 (name, METADATA_FILE_EXT) == 0) {
-		return FALSE;
-	}
-
-	return TRUE;
 }
 
 static void
-update_moved_item_thumbnail (TrackerIndexer      *indexer,
-			     TrackerDataMetadata *old_metadata,
-			     GFile               *file,
-			     GFile               *source_file)
+update_file_uri_recursively (const gchar *source_uri,
+			     const gchar *uri)
 {
-	gchar *uri, *source_uri;
-	const gchar *mime_type;
-
-	if (!old_metadata) {
-		gchar *path;
-
-		path = g_file_get_path (file);
-		g_message ("Could not get mime type to remove thumbnail for:'%s'", path);
-		g_free (path);
-
-		return;
-	}
-
-	/* TODO URI branch: this is a URI conversion */
-	uri = g_file_get_uri (file);
-	source_uri = g_file_get_uri (source_file);
+	gchar *mime_type, *sparql;
+	TrackerDBResultSet *result_set;
+	GError *error = NULL;
 
-	mime_type = tracker_data_metadata_lookup (old_metadata, "File:Mime");
-	tracker_thumbnailer_move (source_uri, mime_type, uri);
+	g_debug ("Moving item from '%s' to '%s'",
+		 source_uri,
+		 uri);
 
-	g_free (source_uri);
-	g_free (uri);
-}
+	if (!tracker_data_update_resource_uri (source_uri, uri)) {
+		/* Move operation failed, which means the dest path
+		 * corresponded to an indexed file, remove any info
+		 * related to it.
+		 */
 
-static void
-update_moved_item_removable_device (TrackerIndexer *indexer,
-				    TrackerClass *service,
-				    GFile          *file,
-				    GFile          *source_file)
-{
-	const gchar *service_name;
-	gchar *path, *source_path;
-	gchar *mount_point = NULL;
+		g_message ("Destination file '%s' already existed in database, removing", uri);
 
-	service_name = tracker_class_get_name (service);
-	path = g_file_get_path (file);
-	source_path = g_file_get_path (source_file);
+		tracker_data_delete_resource (uri);
 
-#ifdef HAVE_HAL
-	if (tracker_hal_path_is_on_removable_device (indexer->private->hal,
-						     source_path,
-						     &mount_point,
-						     NULL) ) {
-
-		if (tracker_hal_path_is_on_removable_device (indexer->private->hal,
-						     path,
-						     NULL,
-						     NULL) ) {
-
-			tracker_removable_device_add_move (indexer,
-							   mount_point,
-							   source_path,
-							   path,
-							   service_name);
+		if (!tracker_data_update_resource_uri (source_uri, uri)) {
+			/* It failed again, no point in trying anymore */
 
-		} else {
-			tracker_removable_device_add_removal (indexer,
-							      mount_point,
-							      source_path,
-							      service_name);
+			return;
 		}
 	}
-#endif
-	g_free (mount_point);
-	g_free (source_path);
-	g_free (path);
-}
-
-static void
-update_moved_item_index (TrackerIndexer      *indexer,
-			 TrackerClass      *service,
-			 TrackerDataMetadata *old_metadata,
-			 guint32              service_id,
-			 GFile               *file,
-			 GFile               *source_file)
-{
-	TrackerModuleMetadata *new_metadata;
-	gchar *path, *new_path, *new_name;
-	const gchar *ext;
-
-	path = g_file_get_path (file);
-
-	/*
-	 *  Update what changes in move event (Path related properties)
-	 */
-	tracker_data_metadata_foreach_remove (old_metadata,
-					      filter_invalid_after_move_properties,
-					      NULL);
-
-	unindex_metadata (indexer, service_id, service, old_metadata);
 
-	new_metadata = tracker_module_metadata_new ();
+	/* Get mime type in order to move thumbnail from thumbnailerd */
+	mime_type = tracker_data_query_property_value (uri, NIE_MIME_TYPE);
 
-	tracker_file_get_path_and_name (path, &new_path, &new_name);
+	if (mime_type) {
+		tracker_thumbnailer_move (source_uri, mime_type, uri);
+		g_free (mime_type);
+	} else {
+		g_message ("Could not get mime type to remove thumbnail for:'%s'",
+			   uri);
+	}
+
+	sparql = g_strdup_printf ("SELECT ?child WHERE { ?child nfo:belongsToContainer <%s> }", uri);
+	result_set = tracker_data_query_sparql (sparql, &error);
+	g_free (sparql);
+	if (result_set) {
+		do {
+			gchar *child_source_uri, *child_uri;
+
+			tracker_db_result_set_get (result_set, 0, &child_source_uri, -1);
+			if (!g_str_has_prefix (child_source_uri, source_uri)) {
+				g_warning ("Child URI '%s' does not start with parent URI '%s'",
+				           child_source_uri,
+				           source_uri);
+				continue;
+			}
+			child_uri = g_strdup_printf ("%s%s", uri, child_source_uri + strlen (source_uri));
 
-	tracker_module_metadata_add_string (new_metadata, METADATA_FILE_PATH, new_path);
-	tracker_module_metadata_add_string (new_metadata, METADATA_FILE_NAME, new_name);
-	tracker_module_metadata_add_string (new_metadata, METADATA_FILE_NAME_DELIMITED, path);
+			update_file_uri_recursively (child_source_uri, child_uri);
 
-	ext = strrchr (path, '.');
-	if (ext) {
-		ext++;
-		tracker_module_metadata_add_string (new_metadata, METADATA_FILE_EXT, ext);
+			g_free (child_source_uri);
+			g_free (child_uri);
+		} while (tracker_db_result_set_iter_next (result_set));
+		g_object_unref (result_set);
 	}
-
-	index_metadata (indexer, service_id, service, new_metadata);
-
-	g_object_unref (new_metadata);
-	g_free (new_path);
-	g_free (new_name);
-	g_free (path);
 }
 
 static gboolean
 item_move (TrackerIndexer  *indexer,
 	   PathInfo	   *info,
-	   const gchar	   *dirname,
-	   const gchar	   *basename)
+	   const gchar	   *source_uri)
 {
-	TrackerClass *service;
-	TrackerDataMetadata *old_metadata;
-	gchar *path, *source_path;
 	guint32 service_id;
-	GHashTable *children = NULL;
-
-	service = get_service_for_file (info->module_file, info->module);
-
-	if (!service) {
-		return FALSE;
-	}
-
-	path = g_file_get_path (info->file);
-	source_path = g_file_get_path (info->source_file);
+	gchar *uri, *old_filename;
+	GFileInfo *file_info;
+	gchar *mount_point = NULL;
 
-	g_debug ("Moving item from '%s' to '%s'", source_path, path);
+	uri = g_file_get_uri (info->file);
 
 	/* Get 'source' ID */
-	if (!tracker_data_query_service_exists (service,
-						dirname,
-						basename,
-						&service_id,
-						NULL)) {
-		gchar *dest_dirname, *dest_basename;
+	if (!tracker_data_query_resource_exists (source_uri,
+					       &service_id,
+					       NULL)) {
 		gboolean res;
 
-		g_message ("Source file '%s' not found in database to move, indexing '%s' from scratch", source_path, path);
+		g_message ("Source file '%s' not found in database to move, indexing '%s' from scratch", source_uri, uri);
 
-		tracker_file_get_path_and_name (path, &dest_dirname, &dest_basename);
-		res = item_process (indexer, info, dest_dirname, dest_basename);
+		res = item_process (indexer, info, uri);
 
-		g_free (dest_dirname);
-		g_free (dest_basename);
-		g_free (path);
-		g_free (source_path);
+		g_free (uri);
 
 		return res;
 	}
 
-	if (info->recurse && strcmp (tracker_class_get_name (service), "Folders") == 0) {
-		children = tracker_data_query_service_children (service, source_path);
-	}
-
-	/* Get mime type in order to move thumbnail from thumbnailerd */
-	old_metadata = tracker_data_query_metadata (service, service_id, TRUE);
-
-	if (!tracker_data_update_move_service (service, source_path, path)) {
-		gchar *dest_dirname, *dest_basename;
-
-		/* Move operation failed, which means the dest path
-		 * corresponded to an indexed file, remove any info
-		 * related to it.
-		 */
-
-		g_message ("Destination file '%s' already existed in database, removing", path);
+	update_file_uri_recursively (source_uri, uri);
 
-		tracker_file_get_path_and_name (path, &dest_dirname, &dest_basename);
-		item_remove (indexer, info, dest_dirname, dest_basename);
-
-		g_free (dest_dirname);
-		g_free (dest_basename);
-
-		if (!tracker_data_update_move_service (service, source_path, path)) {
-			/* It failed again, no point in trying anymore */
-			g_free (path);
-			g_free (source_path);
-
-			if (old_metadata) {
-				tracker_data_metadata_free (old_metadata);
-			}
-
-			return FALSE;
-		}
-	}
-
-	/* Update item being moved */
-	update_moved_item_thumbnail (indexer, old_metadata, info->file, info->source_file);
-	update_moved_item_removable_device (indexer, service, info->file, info->source_file);
-	update_moved_item_index (indexer, service, old_metadata, service_id, info->file, info->source_file);
-
-	if (children) {
-		GHashTableIter iter;
-		gpointer key, value;
-
-		g_hash_table_iter_init (&iter, children);
-
-		/* Queue children to be moved */
-		while (g_hash_table_iter_next (&iter, &key, &value)) {
-			PathInfo *child_info;
-			const gchar *child_name;
-			GFile *child_file, *child_source_file;
-
-			child_name = (const gchar *) value;
-
-			child_file = g_file_get_child (info->file, child_name);
-			child_source_file = g_file_get_child (info->source_file, child_name);
-
-			child_info = path_info_new (info->module, child_file, child_source_file, TRUE);
-			add_file (indexer, child_info);
-
-			g_object_unref (child_file);
-			g_object_unref (child_source_file);
+#ifdef HAVE_HAL
+	if (tracker_hal_uri_is_on_removable_device (indexer->private->hal,
+						    source_uri, 
+						    &mount_point,
+						    NULL) ) {
+		if (tracker_hal_uri_is_on_removable_device (indexer->private->hal,
+							    uri, 
+							    NULL,
+							    NULL) ) {
+
+			tracker_removable_device_add_move (indexer, 
+							   mount_point, 
+							   source_uri, 
+							   uri);
+		} else {
+			tracker_removable_device_add_removal (indexer, 
+							      mount_point, 
+							      source_uri);
 		}
 
-		g_hash_table_destroy (children);
+		g_free (mount_point);
 	}
+#endif
 
-	if (old_metadata) {
-		tracker_data_metadata_free (old_metadata);
-	}
+	file_info = g_file_query_info (info->file,
+					G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+					G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+					NULL, NULL);
 
-	g_free (source_path);
-	g_free (path);
+	old_filename = tracker_data_query_property_value (uri, NFO_FILE_NAME);
+	tracker_data_delete_statement (uri, NFO_FILE_NAME, old_filename);
+	tracker_data_insert_statement (uri, NFO_FILE_NAME, g_file_info_get_display_name (file_info));
+
+	g_free (uri);
+	g_object_unref (file_info);
 
 	return TRUE;
 }
@@ -1937,133 +1373,81 @@ item_move (TrackerIndexer  *indexer,
 static void
 item_remove (TrackerIndexer *indexer,
 	     PathInfo	    *info,
-	     const gchar    *dirname,
-	     const gchar    *basename)
+	     const gchar    *uri)
 {
-	TrackerClass *service;
-	TrackerDataMetadata *data_metadata;
 	gchar *content;
-	gchar *metadata;
-	gchar *path;
 	gchar *mount_point = NULL;
 	const gchar *service_type;
-	guint service_id, service_type_id;
+	gchar *mime_type;
+	guint service_id;
 
-	g_debug ("Removing item: '%s/%s' (no metadata was given by module)", 
-		 dirname, 
-		 basename);
+	g_debug ("Removing item: '%s' (no metadata was given by module)", 
+		 uri);
 
-	/* The file is not anymore in the filesystem. Obtain
-	 * the service type from the DB.
-	 */
-	service_type_id = tracker_data_query_service_type_id (dirname, basename);
+	service_type = tracker_module_config_get_index_service (info->module->name);
 
-	if (service_type_id == 0) {
-		/* File didn't exist, nothing to delete */
-		return;
+	if (!service_type || !service_type[0]) {
+		/* The file is not anymore in the filesystem. Obtain
+		 * the service type from the DB.
+		 */
+		if (!tracker_data_query_resource_exists (uri, NULL, NULL)) {
+			/* File didn't exist, nothing to delete */
+			return;
+		}
 	}
 
-	service_type = tracker_ontology_get_service_by_id (service_type_id);
-	service = tracker_ontology_get_service_by_name (service_type);
-
-	tracker_data_query_service_exists (service, dirname, basename, &service_id, NULL);
+	tracker_data_query_resource_exists (uri, &service_id, NULL);
 
 	if (service_id < 1) {
 		g_debug ("  File does not exist anyway "
-			 "(dirname:'%s', basename:'%s')",
-			 dirname, basename);
+			 "(uri:'%s')",
+			 uri);
 		return;
 	}
 
-	/* This is needed in a few places. */
-	path = g_build_path (G_DIR_SEPARATOR_S, dirname, basename, NULL);
-
 	/* Get mime type and remove thumbnail from thumbnailerd */
-	data_metadata = tracker_data_query_metadata (service, service_id, TRUE);
+	mime_type = tracker_data_query_property_value (uri, NIE_MIME_TYPE);
 
-	if (data_metadata) {
-		GFile *file;
-		const gchar *mime_type;
-		gchar *uri;
-
-		/* TODO URI branch: this is a URI conversion */
-		file = g_file_new_for_path (path);
-		uri = g_file_get_uri (file);
-		g_object_unref (file);
-		
-		mime_type = tracker_data_metadata_lookup (data_metadata, "File:Mime");
+	if (mime_type) {
 		tracker_thumbnailer_remove (uri, mime_type);
 
-		tracker_data_metadata_free (data_metadata);
-		g_free (uri);
+		g_free (mime_type);
 	} else {
 		g_message ("Could not get mime type to remove thumbnail for:'%s'",
-			   path);
+			   uri);
 	}
 
-	tracker_data_update_delete_content (service, service_id);
-
 	/* Get content, unindex the words and delete the contents */
-	content = tracker_data_query_content (service, service_id);
+	content = tracker_data_query_property_value (uri, NIE_PLAIN_TEXT_CONTENT);
 	if (content) {
-		unindex_text_with_parsing (indexer,
-					   service_id,
-					   service_type_id,
-					   content,
-					   1000);
+		tracker_data_delete_statement (uri, NIE_PLAIN_TEXT_CONTENT, content);
 		g_free (content);
-		tracker_data_update_delete_content (service, service_id);
 	}
 
-	/* Get metadata from DB to remove it from the index */
-	metadata = tracker_data_query_parsed_metadata (service,
-						       service_id);
-	unindex_text_no_parsing (indexer,
-				 service_id,
-				 service_type_id,
-				 metadata,
-				 1000);
-	g_free (metadata);
-
-	/* The weight depends on metadata, but a number high enough
-	 * force deletion.
-	 */
-	metadata = tracker_data_query_unparsed_metadata (service,
-							 service_id);
-	unindex_text_with_parsing (indexer,
-				   service_id,
-				   service_type_id,
-				   metadata,
-				   1000);
-	g_free (metadata);
-
 	/* Delete service */
-	tracker_data_update_delete_service (service, service_id);
-	tracker_data_update_delete_all_metadata (service, service_id);
+	tracker_data_delete_resource (uri);
 
+	/* TODO
 	if (info->recurse && strcmp (service_type, "Folders") == 0) {
-		tracker_data_update_delete_service_recursively (service, path);
-	}
+		tracker_data_update_delete_service_recursively (uri);
+	}*/
 
-	if (tracker_hal_path_is_on_removable_device (indexer->private->hal,
-						     path, 
-						     &mount_point,
-						     NULL)) {
+	if (tracker_hal_uri_is_on_removable_device (indexer->private->hal,
+						    uri, 
+						    &mount_point,
+						    NULL)) {
 
-		tracker_removable_device_add_removal (indexer, mount_point, 
-						      path,
-						      tracker_class_get_name (service));
+		tracker_removable_device_add_removal (indexer, mount_point, uri);
 	}
 
 	g_free (mount_point);
-	g_free (path);
+
 }
 
 static gboolean
 item_process (TrackerIndexer *indexer,
 	      PathInfo       *info,
-	      const gchar    *dirname,
-	      const gchar    *basename)
+	      const gchar    *uri)
 {
 	TrackerModuleMetadata *metadata;
 	gchar *text;
@@ -2088,12 +1472,12 @@ item_process (TrackerIndexer *indexer,
 			return FALSE;
 		}
 
-		item_add_or_update (indexer, info, dirname, basename, metadata, text);
+		item_add_or_update (indexer, info, uri, metadata, text);
 
 		g_object_unref (metadata);
 		g_free (text);
 	} else {
-		item_remove (indexer, info, dirname, basename);
+		item_remove (indexer, info, uri);
 	}
 
 	return TRUE;
@@ -2105,17 +1489,13 @@ item_process (TrackerIndexer *indexer,
  */
 static gboolean
 handle_metadata_add (TrackerIndexer *indexer,
-		     const gchar    *service_type,
 		     const gchar    *uri,
 		     const gchar    *property,
 		     GStrv	     values,
 		     GError	   **error)
 {
-	TrackerClass *service;
 	TrackerProperty   *field;
 	guint           service_id, i, j;
-	gchar         **set_values;
-	gchar          *joined, *dirname = NULL, *basename = NULL;
 	gchar         **old_contents;
 	gint            len;
 
@@ -2123,17 +1503,7 @@ handle_metadata_add (TrackerIndexer *indexer,
 
 	check_started (indexer);
 
-	service = tracker_ontology_get_service_by_name (service_type);
-	if (!service) {
-		g_set_error (error,
-			     g_quark_from_string (TRACKER_INDEXER_ERROR),
-			     TRACKER_INDEXER_ERROR_CODE,
-			     "Unknown service type: '%s'",
-			     service_type);
-		return FALSE;
-	}
-
-	field = tracker_ontology_get_field_by_name (property);
+	field = tracker_ontology_get_property_by_uri (property);
 	if (!field) {
 		g_set_error (error,
 			     g_quark_from_string (TRACKER_INDEXER_ERROR),
@@ -2155,15 +1525,9 @@ handle_metadata_add (TrackerIndexer *indexer,
 		return FALSE;
 	}
 
-	tracker_file_get_path_and_name (uri, &dirname, &basename);
-
-	tracker_data_query_service_exists (service,
-				  dirname,
-				  basename,
-				  &service_id,
-				  NULL);
-	g_free (dirname);
-	g_free (basename);
+	tracker_data_query_resource_exists (uri,
+					  &service_id,
+					  NULL);
 
 	if (service_id < 1) {
 		g_set_error (error,
@@ -2173,9 +1537,7 @@ handle_metadata_add (TrackerIndexer *indexer,
 		return FALSE;
 	}
 
-	old_contents = tracker_data_query_metadata_field_values (service,
-						       service_id,
-						       field);
+	old_contents = tracker_data_query_property_values (uri, tracker_property_get_uri (field));
 	if (!tracker_property_get_multiple_values (field) && old_contents) {
 		/* Remove old value from DB and index */
 		len = g_strv_length (old_contents);
@@ -2184,28 +1546,12 @@ handle_metadata_add (TrackerIndexer *indexer,
 			g_critical ("Seems to be multiple values in field:'%s' that doesn allow that",
 				    tracker_property_get_name (field));
 		} else if (old_contents && len == 1) {
-			if (tracker_property_get_filtered (field)) {
-				unindex_text_with_parsing (indexer,
-							   service_id,
-							   tracker_class_get_id (service),
-							   old_contents[0],
-							   tracker_property_get_weight (field));
-			} else {
-				unindex_text_no_parsing (indexer,
-							 service_id,
-							 tracker_class_get_id (service),
-							 old_contents[0],
-							 tracker_property_get_weight (field));
-			}
-			tracker_data_update_delete_metadata (service, service_id, field, old_contents[0]);
+			tracker_data_delete_statement (uri, tracker_property_get_uri (field), old_contents[0]);
 		}
 	}
 
-	set_values = g_new0 (gchar *, g_strv_length (values) + 1);
-
 	for (i = 0, j = 0; values[i] != NULL; i++) {
-		g_debug ("Setting metadata: service_type '%s' id '%d' field '%s' value '%s'",
-			 tracker_class_get_name (service),
+		g_debug ("Setting metadata: id '%d' field '%s' value '%s'",
 			 service_id,
 			 tracker_property_get_name (field),
 			 values[i]);
@@ -2215,61 +1561,30 @@ handle_metadata_add (TrackerIndexer *indexer,
 			continue;
 		}
 
-		tracker_data_update_set_metadata (service, service_id, field, values[i], NULL);
-		set_values [++j] = values[i];
-	}
-
-	joined = g_strjoinv (" ", set_values);
-	if (tracker_property_get_filtered (field)) {
-		index_text_no_parsing (indexer,
-				       service_id,
-				       tracker_class_get_id (service),
-				       joined,
-				       tracker_property_get_weight (field));
-	} else {
-		index_text_with_parsing (indexer,
-					 service_id,
-					 tracker_class_get_id (service),
-					 joined,
-					 tracker_property_get_weight (field));
+		tracker_data_insert_statement (uri, tracker_property_get_uri (field), values[i]);
 	}
 
 	if (old_contents) {
 		g_strfreev (old_contents);
 	}
 
-	/* Not g_strfreev because. It contains the pointers of "values"! */
-	g_free (set_values);
-	g_free (joined);
-
 	return TRUE;
 }
 
 static gboolean
 should_change_index_for_file (TrackerIndexer *indexer,
-			      PathInfo        *info,
-			      const gchar	  *dirname,
-			      const gchar	  *basename)
+			      PathInfo       *info,
+			      const gchar    *uri)
 {
-	TrackerClass *service;
-	gchar *path;
-	guint64 current_mtime;
-	time_t db_mtime;
-
-	service = get_service_for_file (info->module_file, info->module);
-
-	if (!service) {
-		return TRUE;
-	}
+	GFileInfo *file_info;
+	time_t mtime;
 
 	/* Check the file/directory exists. If it doesn't we
 	 * definitely want to index it.
 	 */
-	if (!tracker_data_query_service_exists (service,
-						dirname,
-						basename,
-						NULL,
-						&db_mtime)) {
+	if (!tracker_data_query_resource_exists (uri,
+					       NULL,
+					       &mtime)) {
 		return TRUE;
 	}
 
@@ -2279,26 +1594,20 @@ should_change_index_for_file (TrackerIndexer *indexer,
 	 * the database. If it does, then we can ignore any files
 	 * immediately in this parent directory.
 	 */
-	path = g_file_get_path (info->file);
-	current_mtime = tracker_file_get_mtime (path);
-
-	/* NOTE: We return TRUE here because we want to update the DB
-	 * about this file, not because we want to index it.
-	 */
-	if (current_mtime == 0) {
-		g_free (path);
+	file_info = g_file_query_info (info->file, "standard::*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
+	if (!file_info) {
+		/* NOTE: We return TRUE here because we want to update the DB
+		 * about this file, not because we want to index it.
+		 */
 		return TRUE;
 	}
 
-	if (current_mtime == db_mtime) {
-		g_message ("'%s' is already up to date in DB, not (re)indexing", path);
-		g_free (path);
+	if (g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED) == mtime) {
+		g_message ("%s: is already up to date in DB, not (re)indexing", uri);
 
 		return FALSE;
 	}
 
-	g_free (path);
-
 	return TRUE;
 }
 
@@ -2306,7 +1615,7 @@ static gboolean
 process_file (TrackerIndexer *indexer,
 	      PathInfo	     *info)
 {
-	gchar *uri, *dirname, *basename;
+	gchar *uri;
 	gboolean inc_counters = FALSE;
 
 	/* Note: If info->source_file is set, the PathInfo is for a
@@ -2334,39 +1643,12 @@ process_file (TrackerIndexer *indexer,
 		return TRUE;
 	}
 
-	tracker_file_get_path_and_name (uri, &dirname, &basename);
-	g_free (uri);
-
-	/*
-	 * FIRST:
-	 * ======
-	 * We don't check if we should index files for MOVE events.
-	 *
-	 * SECOND:
-	 * =======
-	 * Here we do a quick check to see if this is an email URI or
-	 * not. For emails we don't check if we should index them, we
-	 * always do since it is ONLY summary files we index and we
-	 * need to look at them to know if anything changed anyway.
-	 * The only improvement we could have here is an mtime check.
-	 * This is yet to do.
-	 *
-	 * The info->file->path is the REAL location. The dirname and
-	 * basename which are returned by the module are combined to
-	 * look like:
-	 *
-	 *   email://1192717939 16218 20 petunia/INBOX;uid=1
-	 *
-	 * We simply check the dirname[0] to make sure it isn't an
-	 * email based dirname.
-	 */
-	if (G_LIKELY (!info->source_file) && dirname[0] == G_DIR_SEPARATOR) {
-		if (!should_change_index_for_file (indexer, info, dirname, basename)) {
+	/* We don't check if we should index files for MOVE events */
+	if (G_LIKELY (!info->source_file)) {
+		if (!should_change_index_for_file (indexer, info, uri)) {
 			indexer->private->items_processed++;
 
-			g_free (dirname);
-			g_free (basename);
-
+			g_free (uri);
 			return TRUE;
 		}
 	}
@@ -2379,11 +1661,11 @@ process_file (TrackerIndexer *indexer,
 	 * a service and set the metadata.
 	 */
 	if (G_UNLIKELY (info->source_file)) {
-		if (item_move (indexer, info, dirname, basename)) {
+		if (item_move (indexer, info, uri)) {
 			inc_counters = TRUE;
 		}
 	} else {
-		if (item_process (indexer, info, dirname, basename)) {
+		if (item_process (indexer, info, uri)) {
 			inc_counters = TRUE;
 		}
 	}
@@ -2394,8 +1676,7 @@ process_file (TrackerIndexer *indexer,
 		indexer->private->items_to_index++;
 	}
 
-	g_free (dirname);
-	g_free (basename);
+	g_free (uri);
 
 	if (!tracker_module_file_is_cancelled (info->module_file) &&
 	    TRACKER_IS_MODULE_ITERATABLE (info->module_file)) {
@@ -2409,48 +1690,44 @@ static void
 process_directory (TrackerIndexer *indexer,
 		   PathInfo       *info)
 {
-	gchar *path;
-	const gchar *name;
-	GDir *dir;
+	char *path;
+	GFileEnumerator *enumerator;
+	GFileInfo *file_info;
 
 	path = g_file_get_path (info->file);
-
-	/* FIXME: Use gio to iterate the directory */
 	g_debug ("Processing directory:'%s'", path);
+	g_free (path);
 
-	dir = g_dir_open (path, 0, NULL);
+	enumerator = g_file_enumerate_children (info->file, "standard::*", 0, NULL, NULL);
 
-	if (!dir) {
-		g_free (path);
+	if (!enumerator) {
 		return;
 	}
 
-	while ((name = g_dir_read_name (dir)) != NULL) {
+	while ((file_info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) {
 		PathInfo *new_info;
 		GFile *child;
-		gchar *child_path;
 
-		if (name[0] == '.') {
+		if (g_file_info_get_is_hidden (file_info)) {
+			g_object_unref (file_info);
 			continue;
 		}
 
-		child = g_file_get_child (info->file, name);
-		child_path = g_file_get_path (child);
+		child = g_file_get_child (info->file, g_file_info_get_name (file_info));
 
 		new_info = path_info_new (info->module, child, NULL, FALSE);
 		add_file (indexer, new_info);
 
-		if (info->recurse && g_file_test (child_path, G_FILE_TEST_IS_DIR)) {
-			new_info = path_info_new (info->module, child, NULL, TRUE);
+		if (info->recurse && g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) {
+			new_info = path_info_new (info->module, child, NULL, FALSE);
 			add_directory (indexer, new_info);
 		}
 
 		g_object_unref (child);
-		g_free (child_path);
+		g_object_unref (file_info);
 	}
 
-	g_dir_close (dir);
-	g_free (path);
+	g_object_unref (enumerator);
 }
 
 static void
@@ -2500,8 +1777,8 @@ process_module (TrackerIndexer *indexer,
 	process_module_emit_signals (indexer, module_name);
 
 	for (d = dirs; d; d = d->next) {
-		PathInfo *info;
 		GFile *file;
+		PathInfo *info;
 
 		file = g_file_new_for_path (d->data);
 		info = path_info_new (module, file, NULL, TRUE);
@@ -2513,11 +1790,51 @@ process_module (TrackerIndexer *indexer,
 	g_list_free (dirs);
 }
 
+static void
+process_turtle_file_part (TrackerIndexer *indexer)
+{
+	int i;
+
+	/* process 100 statements at once before returning to main loop */
+
+	i = 0;
+
+	while (tracker_turtle_reader_next ()) {
+		/* insert statement */
+		tracker_data_insert_statement (
+			tracker_turtle_reader_get_subject (),
+			tracker_turtle_reader_get_predicate (),
+			tracker_turtle_reader_get_object ());
+
+		indexer->private->items_processed++;
+		indexer->private->items_to_index++;
+		i++;
+		if (i >= 100) {
+			/* return to main loop */
+			return;
+		}
+	}
+
+	indexer->private->turtle_import_in_progress = FALSE;
+}
+
+static void
+process_turtle_file (TrackerIndexer *indexer,
+                     const gchar    *file)
+{
+	indexer->private->turtle_import_in_progress = TRUE;
+
+	tracker_turtle_reader_init (file, NULL);
+
+	process_turtle_file_part (indexer);
+}
+
 static gboolean
 process_func (gpointer data)
 {
 	TrackerIndexer *indexer;
 	PathInfo *path;
+	gchar *file;
 
 	indexer = TRACKER_INDEXER (data);
 
@@ -2527,7 +1844,13 @@ process_func (gpointer data)
 		start_transaction (indexer);
 	}
 
-	if ((path = g_queue_peek_head (indexer->private->file_queue)) != NULL) {
+	if (indexer->private->turtle_import_in_progress) {
+		process_turtle_file_part (indexer);
+	} else if ((file = g_queue_pop_head (indexer->private->import_queue)) != NULL) {
+		/* Import file */
+		process_turtle_file (indexer, file);
+		g_free (file);
+	} else if ((path = g_queue_peek_head (indexer->private->file_queue)) != NULL) {
 		/* Process file */
 		if (process_file (indexer, path)) {
 			indexer->private->subelements_processed = 0;
@@ -2746,13 +2069,11 @@ tracker_indexer_set_running (TrackerIndexer *indexer,
 	if (running && (state & TRACKER_INDEXER_STATE_PAUSED)) {
 		state_unset_flags (indexer, TRACKER_INDEXER_STATE_PAUSED);
 
-		tracker_db_index_set_paused (indexer->private->file_index, FALSE);
-		tracker_db_index_set_paused (indexer->private->email_index, FALSE);
+		tracker_db_index_set_paused (indexer->private->resources_index, FALSE);
 	} else if (!running && !(state & TRACKER_INDEXER_STATE_PAUSED)) {
 		state_set_flags (indexer, TRACKER_INDEXER_STATE_PAUSED);
 
-		tracker_db_index_set_paused (indexer->private->file_index, TRUE);
-		tracker_db_index_set_paused (indexer->private->email_index, TRUE);
+		tracker_db_index_set_paused (indexer->private->resources_index, TRUE);
 	}
 }
 
@@ -2896,6 +2217,30 @@ tracker_indexer_process_modules (TrackerIndexer  *indexer,
 }
 
 void
+tracker_indexer_turtle_add (TrackerIndexer *indexer,
+			    const gchar    *file,
+			    DBusGMethodInvocation *context,
+			    GError **error)
+{
+	guint request_id;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (TRACKER_IS_INDEXER (indexer), context);
+	tracker_dbus_async_return_if_fail (file != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to check TTL file %s",
+				  file);
+
+	add_turtle_file (indexer, file);
+
+	dbus_g_method_return (context);
+	tracker_dbus_request_success (request_id);
+}
+
+
+void
 tracker_indexer_files_check (TrackerIndexer *indexer,
 			     const gchar *module_name,
 			     GStrv files,
@@ -2930,8 +2275,8 @@ tracker_indexer_files_check (TrackerIndexer *indexer,
 
 	/* Add files to the queue */
 	for (i = 0; files[i]; i++) {
-		PathInfo *info;
 		GFile *file;
+		PathInfo *info;
 
 		file = g_file_new_for_path (files[i]);
 		info = path_info_new (module, file, NULL, TRUE);
@@ -3046,7 +2391,7 @@ tracker_indexer_volume_update_state (TrackerIndexer         *indexer,
 				     DBusGMethodInvocation  *context,
 				     GError                **error)
 {
-	guint request_id;
+	guint  request_id;
 
 	request_id = tracker_dbus_get_next_request_id ();
 
@@ -3067,7 +2412,11 @@ tracker_indexer_volume_update_state (TrackerIndexer         *indexer,
 		tracker_data_update_disable_volume (volume_uuid);
 	}
 
+	/* tracker_turtle_process_ttl will be spinning the mainloop, therefore 
+	   we can already return the DBus method */
+
 	dbus_g_method_return (context);
+
 	tracker_dbus_request_success (request_id);
 
 	/* tracker_turtle_process_ttl will be spinning the mainloop, therefore
@@ -3076,6 +2425,71 @@ tracker_indexer_volume_update_state (TrackerIndexer         *indexer,
 	if (enabled) {
 		tracker_removable_device_load (indexer, path);
 	}
+
+}
+
+void
+tracker_indexer_insert_statement (TrackerIndexer	     *indexer,
+			          const gchar	     *subject,
+			          const gchar	     *predicate,
+			          const gchar	     *object,
+			          DBusGMethodInvocation  *context,
+			          GError		    **error)
+{
+	guint	request_id;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (TRACKER_IS_INDEXER (indexer), context);
+	tracker_dbus_async_return_if_fail (subject != NULL, context);
+	tracker_dbus_async_return_if_fail (predicate != NULL, context);
+	tracker_dbus_async_return_if_fail (object != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to insert statement: "
+				  "'%s' '%s' '%s'",
+				  subject,
+				  predicate,
+				  object);
+
+	schedule_flush (indexer, TRUE);
+
+	tracker_data_insert_statement (subject, predicate, object);
+
+	dbus_g_method_return (context);
+	tracker_dbus_request_success (request_id);
+}
+
+void
+tracker_indexer_delete_statement (TrackerIndexer	     *indexer,
+			          const gchar	     *subject,
+			          const gchar	     *predicate,
+			          const gchar	     *object,
+			          DBusGMethodInvocation  *context,
+			          GError		    **error)
+{
+	guint	request_id;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (TRACKER_IS_INDEXER (indexer), context);
+	tracker_dbus_async_return_if_fail (subject != NULL, context);
+	tracker_dbus_async_return_if_fail (predicate != NULL, context);
+	tracker_dbus_async_return_if_fail (object != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to delete statement: "
+				  "'%s' '%s' '%s'",
+				  subject,
+				  predicate,
+				  object);
+
+	schedule_flush (indexer, TRUE);
+
+	tracker_data_delete_statement (subject, predicate, object);
+
+	dbus_g_method_return (context);
+	tracker_dbus_request_success (request_id);
 }
 
 static void
@@ -3089,7 +2503,6 @@ restore_backup_cb (const gchar *subject,
 	GError *error = NULL;
 
 	handle_metadata_add (indexer,
-			     "Files",
 			     subject,
 			     predicate,
 			     (GStrv) values,
diff --git a/src/tracker-indexer/tracker-indexer.h b/src/tracker-indexer/tracker-indexer.h
index 0972e48..8c78293 100644
--- a/src/tracker-indexer/tracker-indexer.h
+++ b/src/tracker-indexer/tracker-indexer.h
@@ -85,7 +85,6 @@ gboolean        tracker_indexer_get_running         (TrackerIndexer         *ind
 void            tracker_indexer_set_running         (TrackerIndexer         *indexer,
 						     gboolean                running);
 gboolean        tracker_indexer_get_stoppable       (TrackerIndexer         *indexer);
-
 void            tracker_indexer_stop                (TrackerIndexer         *indexer);
 void            tracker_indexer_process_all         (TrackerIndexer         *indexer);
 void            tracker_indexer_process_modules     (TrackerIndexer         *indexer,
@@ -104,6 +103,10 @@ void            tracker_indexer_pause_for_duration  (TrackerIndexer         *ind
 void            tracker_indexer_continue            (TrackerIndexer         *indexer,
 						     DBusGMethodInvocation  *context,
 						     GError                **error);
+void		tracker_indexer_turtle_add	   (TrackerIndexer *indexer,
+						    const gchar             *file,
+						    DBusGMethodInvocation *context,
+						    GError **error);
 void            tracker_indexer_files_check         (TrackerIndexer         *indexer,
 						     const gchar            *module,
 						     GStrv                   files,
@@ -134,6 +137,18 @@ void            tracker_indexer_volume_update_state (TrackerIndexer         *ind
 						     gboolean                enabled,
 						     DBusGMethodInvocation  *context,
 						     GError                **error);
+void            tracker_indexer_insert_statement    (TrackerIndexer         *indexer,
+						     const gchar            *subject,
+						     const gchar            *predicate,
+						     const gchar            *object,
+						     DBusGMethodInvocation  *context,
+						     GError                **error);
+void            tracker_indexer_delete_statement    (TrackerIndexer         *indexer,
+						     const gchar            *subject,
+						     const gchar            *predicate,
+						     const gchar            *object,
+						     DBusGMethodInvocation  *context,
+						     GError                **error);
 void            tracker_indexer_restore_backup      (TrackerIndexer         *indexer,
 						     const gchar            *backup_file,
 						     DBusGMethodInvocation  *context,
diff --git a/src/tracker-indexer/tracker-main.c b/src/tracker-indexer/tracker-main.c
index 908fa95..7ea7588 100644
--- a/src/tracker-indexer/tracker-main.c
+++ b/src/tracker-indexer/tracker-main.c
@@ -46,9 +46,9 @@
 #include <libtracker-db/tracker-db-manager.h>
 #include <libtracker-db/tracker-db-index-manager.h>
 
+#include <libtracker-data/tracker-data-manager.h>
 #include <libtracker-data/tracker-data-update.h>
 #include <libtracker-data/tracker-turtle.h>
-#include <libtracker-data/tracker-data-manager.h>
 
 #include "tracker-dbus.h"
 #include "tracker-indexer.h"
@@ -289,8 +289,7 @@ main (gint argc, gchar *argv[])
 	GOptionContext *context;
 	GError *error = NULL;
 	gchar *filename;
-	TrackerDBIndex *file_index;
-	TrackerDBIndex *email_index;
+	gboolean		    is_first_time_index;
 
 	g_type_init ();
 
@@ -363,10 +362,7 @@ main (gint argc, gchar *argv[])
 		flags |= TRACKER_DB_MANAGER_LOW_MEMORY_MODE;
 	}
 
-	tracker_db_manager_init (flags, NULL, FALSE);
-	if (!tracker_db_index_manager_init (0,
-					    tracker_config_get_min_bucket_count (config),
-					    tracker_config_get_max_bucket_count (config))) {
+	if (!tracker_data_manager_init (config, language, flags, 0, NULL, &is_first_time_index)) {
 		return EXIT_FAILURE;
 	}
 
@@ -417,11 +413,6 @@ main (gint argc, gchar *argv[])
                 tracker_indexer_process_modules (indexer, modules);
         }
 
-	file_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_FILE);
-	email_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_EMAIL);
-
-	tracker_data_manager_init (config, language, file_index, email_index);
-
 	tracker_push_init (config, indexer);
 
 	tracker_turtle_init ();
@@ -445,14 +436,11 @@ main (gint argc, gchar *argv[])
 	g_object_unref (config);
 	g_object_unref (language);
 
-	tracker_data_manager_shutdown ();
-
 	tracker_push_shutdown ();
 
 	tracker_thumbnailer_shutdown ();
 	tracker_dbus_shutdown ();
-	tracker_db_index_manager_shutdown ();
-	tracker_db_manager_shutdown ();
+	tracker_data_manager_shutdown ();
 	tracker_module_config_shutdown ();
 	tracker_log_shutdown ();
 
diff --git a/src/tracker-indexer/tracker-module-file.c b/src/tracker-indexer/tracker-module-file.c
index 5470f4b..1f4b833 100644
--- a/src/tracker-indexer/tracker-module-file.c
+++ b/src/tracker-indexer/tracker-module-file.c
@@ -21,10 +21,6 @@
 #include "tracker-module-metadata-private.h"
 #include "tracker-module-file.h"
 
-#define METADATA_FILE_PATH	     "File:Path"
-#define METADATA_FILE_NAME	     "File:Name"
-#define METADATA_FILE_MODIFIED       "File:Modified"
-
 #define TRACKER_MODULE_FILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MODULE_FILE, TrackerModuleFilePrivate))
 
 typedef struct TrackerModuleFilePrivate TrackerModuleFilePrivate;
@@ -193,24 +189,6 @@ tracker_module_file_get_file (TrackerModuleFile *file)
         return priv->file;
 }
 
-/**
- * tracker_module_file_get_service_type:
- * @file: A #TrackerModuleFile
- *
- * Returns the service type for @file in the current
- * state (See #TrackerModuleIteratable).
- *
- * Returns: The service type name.
- **/
-G_CONST_RETURN gchar *
-tracker_module_file_get_service_type (TrackerModuleFile *file)
-{
-        if (TRACKER_MODULE_FILE_GET_CLASS (file)->get_service_type == NULL) {
-                return NULL;
-        }
-
-        return TRACKER_MODULE_FILE_GET_CLASS (file)->get_service_type (file);
-}
 
 /**
  * tracker_module_file_get_uri:
@@ -234,10 +212,7 @@ tracker_module_file_get_uri (TrackerModuleFile *file)
 
                 f = tracker_module_file_get_file (file);
 
-                /* FIXME: When we agree on storing URIs in the
-                 * database, this should stop returning the path
-                 */
-                uri = g_file_get_path (f);
+                uri = g_file_get_uri (f);
         }
 
         return uri;
@@ -283,29 +258,6 @@ tracker_module_file_get_metadata (TrackerModuleFile *file)
                 metadata = TRACKER_MODULE_FILE_GET_CLASS (file)->get_metadata (file);
         }
 
-        if (!metadata) {
-                return NULL;
-        }
-
-        if (!tracker_module_metadata_lookup (metadata, METADATA_FILE_PATH, NULL) &&
-            !tracker_module_metadata_lookup (metadata, METADATA_FILE_NAME, NULL)) {
-                gchar *uri, *dirname, *basename;
-
-                uri = tracker_module_file_get_uri (file);
-                tracker_file_get_path_and_name (uri, &dirname, &basename);
-
-                tracker_module_metadata_add_string (metadata, METADATA_FILE_PATH, dirname);
-                tracker_module_metadata_add_string (metadata, METADATA_FILE_NAME, basename);
-
-                g_free (dirname);
-                g_free (basename);
-                g_free (uri);
-        }
-
-        if (!tracker_module_metadata_lookup (metadata, METADATA_FILE_MODIFIED, NULL)) {
-                tracker_module_metadata_add_date (metadata, METADATA_FILE_MODIFIED, time (NULL));
-        }
-
         return metadata;
 }
 
diff --git a/src/tracker-indexer/tracker-module-file.h b/src/tracker-indexer/tracker-module-file.h
index c6b47de..8e018ec 100644
--- a/src/tracker-indexer/tracker-module-file.h
+++ b/src/tracker-indexer/tracker-module-file.h
@@ -55,7 +55,6 @@ struct TrackerModuleFileClass {
         GObjectClass parent_class;
 
         void (* initialize) (TrackerModuleFile *file);
-        G_CONST_RETURN gchar * (* get_service_type) (TrackerModuleFile *file);
         gchar * (* get_uri) (TrackerModuleFile *file);
         gchar * (* get_text) (TrackerModuleFile *file);
         TrackerModuleMetadata * (* get_metadata) (TrackerModuleFile *file);
diff --git a/src/tracker-indexer/tracker-module-metadata-private.h b/src/tracker-indexer/tracker-module-metadata-private.h
index a03358d..0290afd 100644
--- a/src/tracker-indexer/tracker-module-metadata-private.h
+++ b/src/tracker-indexer/tracker-module-metadata-private.h
@@ -28,27 +28,19 @@
 
 G_BEGIN_DECLS
 
-typedef void (* TrackerModuleMetadataForeach) (TrackerProperty *field,
-					       gpointer      value,
+typedef void (* TrackerModuleMetadataForeach) (const gchar     *subject,
+					       const gchar     *predicate,
+					       const gchar     *object,
 					       gpointer      user_data);
-typedef gboolean (* TrackerModuleMetadataRemove) (TrackerProperty *field,
-						  gpointer      value,
+typedef gboolean (* TrackerModuleMetadataRemove) (const gchar     *subject,
+						  const gchar     *predicate,
+						  const gchar     *object,
 						  gpointer      user_data);
 
-gconstpointer          tracker_module_metadata_lookup         (TrackerModuleMetadata        *metadata,
-							       const gchar                  *field_name,
-							       gboolean                     *multiple_values);
-
 void		       tracker_module_metadata_foreach        (TrackerModuleMetadata        *metadata,
 							       TrackerModuleMetadataForeach  func,
 							       gpointer	                     user_data);
 
-void		       tracker_module_metadata_foreach_remove (TrackerModuleMetadata        *metadata,
-							       TrackerModuleMetadataRemove   func,
-							       gpointer	                     user_data);
-
-GHashTable *           tracker_module_metadata_get_hash_table (TrackerModuleMetadata        *metadata);
-
 
 G_END_DECLS
 
diff --git a/src/tracker-indexer/tracker-module-metadata-utils.c b/src/tracker-indexer/tracker-module-metadata-utils.c
index 04f500e..cdfd6f4 100644
--- a/src/tracker-indexer/tracker-module-metadata-utils.c
+++ b/src/tracker-indexer/tracker-module-metadata-utils.c
@@ -42,35 +42,43 @@
 #include "tracker-extract-client.h"
 #include "tracker-dbus.h"
 
-#define METADATA_FILE_NAME_DELIMITED "File:NameDelimited"
-#define METADATA_FILE_EXT            "File:Ext"
-#define METADATA_FILE_PATH           "File:Path"
-#define METADATA_FILE_NAME           "File:Name"
-#define METADATA_FILE_LINK           "File:Link"
-#define METADATA_FILE_MIMETYPE       "File:Mime"
-#define METADATA_FILE_SIZE           "File:Size"
-#define METADATA_FILE_MODIFIED       "File:Modified"
-#define METADATA_FILE_ACCESSED       "File:Accessed"
-
-#undef  TRY_LOCALE_TO_UTF8_CONVERSION
-#define TEXT_MAX_SIZE                1048576  /* bytes */
-#define TEXT_CHECK_SIZE              65535    /* bytes */
+#define THUMBNAIL_RETRIEVAL_ENABLED
+#define HAVE_HILDON_THUMBNAIL
+
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+#define NIE_PREFIX TRACKER_NIE_PREFIX
+#define NIE_MIME_TYPE NIE_PREFIX "mimeType"
+
+#define NFO_PREFIX TRACKER_NFO_PREFIX
+#define NFO_BELONGS_TO_CONTAINER NFO_PREFIX "belongsToContainer"
+#define NFO_FILE_DATA_OBJECT NFO_PREFIX "FileDataObject"
+#define NFO_FILE_LAST_ACCESSED NFO_PREFIX "fileLastAccessed"
+#define NFO_FILE_LAST_MODIFIED NFO_PREFIX "fileLastModified"
+#define NFO_FILE_NAME NFO_PREFIX "fileName"
+#define NFO_FILE_SIZE NFO_PREFIX "fileSize"
+#define NFO_FOLDER NFO_PREFIX "Folder"
+
+#undef	TRY_LOCALE_TO_UTF8_CONVERSION
+#define TEXT_MAX_SIZE		     1048576  /* bytes */
+#define TEXT_CHECK_SIZE		     65535    /* bytes */
 
 #define TEXT_EXTRACTION_TIMEOUT      10
 
 typedef struct {
-        GPid pid;
-        guint stdout_watch_id;
-        GIOChannel *stdin_channel;
-        GIOChannel *stdout_channel;
-        GMainLoop  *data_incoming_loop;
-        gpointer data;
+	GPid pid;
+	guint stdout_watch_id;
+	GIOChannel *stdin_channel;
+	GIOChannel *stdout_channel;
+	GMainLoop  *data_incoming_loop;
+	gpointer data;
 } ProcessContext;
 
 typedef struct {
-        GHashTable *metadata;
-        GMainLoop *main_loop;
-        GPid pid;
+	TrackerModuleMetadata *metadata;
+	GMainLoop *main_loop;
+	GPid pid;
 } ExtractorContext;
 
 static GPid extractor_pid = 0;
@@ -115,351 +123,328 @@ extractor_changed_availability_cb (const gchar *name,
 static DBusGProxy *
 get_dbus_extract_proxy (void)
 {
-        static DBusGProxy *proxy = NULL;
-        DBusGConnection *connection;
-        GError *error = NULL;
-
-        /* FIXME: Not perfect, we leak */
-        if (G_LIKELY (proxy)) {
-                return proxy;
-        }
-
-        connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-
-        if (!connection) {
-                g_critical ("Could not connect to the DBus session bus, %s",
-                            error ? error->message : "no error given.");
-                g_clear_error (&error);
-                return FALSE;
-        }
-
-        /* Get proxy for Service / Path / Interface of the indexer */
-        proxy = dbus_g_proxy_new_for_name (connection,
-                                           "org.freedesktop.Tracker.Extract",
-                                           "/org/freedesktop/Tracker/Extract",
-                                           "org.freedesktop.Tracker.Extract");
-
-        if (!proxy) {
-                g_critical ("Could not create a DBusGProxy to the extract service");
-        }
+	static DBusGProxy *proxy = NULL;
+	DBusGConnection *connection;
+	GError *error = NULL;
+
+	/* FIXME: Not perfect, we leak */
+	if (G_LIKELY (proxy)) {
+		return proxy;
+	}
+
+	connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+	if (!connection) {
+		g_critical ("Could not connect to the DBus session bus, %s",
+			    error ? error->message : "no error given.");
+		g_clear_error (&error);
+		return FALSE;
+	}
+
+	/* Get proxy for Service / Path / Interface of the indexer */
+	proxy = dbus_g_proxy_new_for_name (connection,
+					   "org.freedesktop.Tracker.Extract",
+					   "/org/freedesktop/Tracker/Extract",
+					   "org.freedesktop.Tracker.Extract");
+
+	if (!proxy) {
+		g_critical ("Could not create a DBusGProxy to the extract service");
+	}
 
 	tracker_dbus_add_name_monitor ("org.freedesktop.Tracker.Extract",
 				       extractor_changed_availability_cb,
 				       NULL, NULL);
-        return proxy;
+	return proxy;
 }
 
 static void
 process_context_destroy (ProcessContext *context)
 {
-        if (context->stdin_channel) {
-                g_io_channel_shutdown (context->stdin_channel, FALSE, NULL);
-                g_io_channel_unref (context->stdin_channel);
-                context->stdin_channel = NULL;
-        }
-
-        if (context->stdout_watch_id != 0) {
-                g_source_remove (context->stdout_watch_id);
-                context->stdout_watch_id = 0;
-        }
-
-        if (context->stdout_channel) {
-                g_io_channel_shutdown (context->stdout_channel, FALSE, NULL);
-                g_io_channel_unref (context->stdout_channel);
-                context->stdout_channel = NULL;
-        }
-
-        if (context->data_incoming_loop) {
-                if (g_main_loop_is_running (context->data_incoming_loop)) {
-                        g_main_loop_quit (context->data_incoming_loop);
-                }
-
-                g_main_loop_unref (context->data_incoming_loop);
-                context->data_incoming_loop = NULL;
-        }
-
-        if (context->pid != 0) {
-                g_spawn_close_pid (context->pid);
-                context->pid = 0;
-        }
-
-        g_free (context);
+	if (context->stdin_channel) {
+		g_io_channel_shutdown (context->stdin_channel, FALSE, NULL);
+		g_io_channel_unref (context->stdin_channel);
+		context->stdin_channel = NULL;
+	}
+
+	if (context->stdout_watch_id != 0) {
+		g_source_remove (context->stdout_watch_id);
+		context->stdout_watch_id = 0;
+	}
+
+	if (context->stdout_channel) {
+		g_io_channel_shutdown (context->stdout_channel, FALSE, NULL);
+		g_io_channel_unref (context->stdout_channel);
+		context->stdout_channel = NULL;
+	}
+
+	if (context->data_incoming_loop) {
+		if (g_main_loop_is_running (context->data_incoming_loop)) {
+			g_main_loop_quit (context->data_incoming_loop);
+		}
+
+		g_main_loop_unref (context->data_incoming_loop);
+		context->data_incoming_loop = NULL;
+	}
+
+	if (context->pid != 0) {
+		g_spawn_close_pid (context->pid);
+		context->pid = 0;
+	}
+
+	g_free (context);
 }
 
 static void
 process_context_kill (ProcessContext *context)
 {
-        g_message ("Attempting to kill text filter with SIGKILL");
+	g_message ("Attempting to kill text filter with SIGKILL");
 
-        if (kill (context->pid, SIGKILL) == -1) {
-                const gchar *str = g_strerror (errno);
+	if (kill (context->pid, SIGKILL) == -1) {
+		const gchar *str = g_strerror (errno);
 
-                g_message ("  Could not kill process %d, %s",
-                           context->pid,
-                           str ? str : "no error given");
-        } else {
-                g_message ("  Killed process %d", context->pid);
-        }
+		g_message ("  Could not kill process %d, %s",
+			   context->pid,
+			   str ? str : "no error given");
+	} else {
+		g_message ("  Killed process %d", context->pid);
+	}
 }
 
 static void
-process_context_child_watch_cb (GPid     pid,
-                                gint     status,
-                                gpointer user_data)
+process_context_child_watch_cb (GPid	 pid,
+				gint	 status,
+				gpointer user_data)
 {
-        ProcessContext *context;
+	ProcessContext *context;
 
-        g_debug ("Process '%d' exited with code %d",
-                 pid,
-                 status);
+	g_debug ("Process '%d' exited with code %d",
+		 pid,
+		 status);
 
-        context = (ProcessContext *) user_data;
-        process_context_destroy (context);
+	context = (ProcessContext *) user_data;
+	process_context_destroy (context);
 }
 
 static ProcessContext *
 process_context_create (const gchar **argv,
-                        GIOFunc       stdout_watch_func)
+			GIOFunc       stdout_watch_func)
 {
-        ProcessContext *context;
-        GIOChannel *stdin_channel, *stdout_channel;
-        GIOFlags flags;
-        GPid pid;
-
-        if (!tracker_spawn_async_with_channels (argv,
-                                                TEXT_EXTRACTION_TIMEOUT,
-                                                &pid,
-                                                &stdin_channel,
-                                                &stdout_channel,
-                                                NULL)) {
-                return NULL;
-        }
-
-        g_debug ("Process '%d' spawned for command:'%s'",
-                 pid,
-                 argv[0]);
-
-        context = g_new0 (ProcessContext, 1);
-        context->pid = pid;
-        context->stdin_channel = stdin_channel;
-        context->stdout_channel = stdout_channel;
-        context->data_incoming_loop = g_main_loop_new (NULL, FALSE);
-        context->stdout_watch_id = g_io_add_watch (stdout_channel,
-                                                   G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
-                                                   stdout_watch_func,
-                                                   context);
-
-        flags = g_io_channel_get_flags (context->stdout_channel);
-        flags |= G_IO_FLAG_NONBLOCK;
-
-        g_io_channel_set_flags (context->stdout_channel, flags, NULL);
-
-        g_child_watch_add (context->pid, process_context_child_watch_cb, context);
-
-        return context;
+	ProcessContext *context;
+	GIOChannel *stdin_channel, *stdout_channel;
+	GIOFlags flags;
+	GPid pid;
+
+	if (!tracker_spawn_async_with_channels (argv,
+						TEXT_EXTRACTION_TIMEOUT,
+						&pid,
+						&stdin_channel,
+						&stdout_channel,
+						NULL)) {
+		return NULL;
+	}
+
+	g_debug ("Process '%d' spawned for command:'%s'",
+		 pid,
+		 argv[0]);
+
+	context = g_new0 (ProcessContext, 1);
+	context->pid = pid;
+	context->stdin_channel = stdin_channel;
+	context->stdout_channel = stdout_channel;
+	context->data_incoming_loop = g_main_loop_new (NULL, FALSE);
+	context->stdout_watch_id = g_io_add_watch (stdout_channel,
+						   G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
+						   stdout_watch_func,
+						   context);
+
+	flags = g_io_channel_get_flags (context->stdout_channel);
+	flags |= G_IO_FLAG_NONBLOCK;
+
+	g_io_channel_set_flags (context->stdout_channel, flags, NULL);
+
+	g_child_watch_add (context->pid, process_context_child_watch_cb, context);
+
+	return context;
 }
 
 static ExtractorContext *
 extractor_context_create (TrackerModuleMetadata *metadata)
 {
-        ExtractorContext *context;
+	ExtractorContext *context;
 
 	if (G_UNLIKELY (extractor_pid == 0)) {
 		/* Ensure we have a PID to kill if anything goes wrong */
 		extractor_pid = get_extractor_pid ();
 	}
 
-        context = g_slice_new0 (ExtractorContext);
-        context->main_loop = g_main_loop_new (NULL, FALSE);
-        context->metadata = g_object_ref (metadata);
-        context->pid = extractor_pid;
+	context = g_slice_new0 (ExtractorContext);
+	context->main_loop = g_main_loop_new (NULL, FALSE);
+	context->metadata = g_object_ref (metadata);
+	context->pid = extractor_pid;
 
-        return context;
+	return context;
 }
 
 static void
 extractor_context_destroy (ExtractorContext *context)
 {
-        g_object_unref (context->metadata);
-        g_main_loop_unref (context->main_loop);
-        g_slice_free (ExtractorContext, context);
+	g_object_unref (context->metadata);
+	g_main_loop_unref (context->main_loop);
+	g_slice_free (ExtractorContext, context);
 }
 
 static void
 extractor_context_kill (ExtractorContext *context)
 {
-        g_message ("Attempting to kill tracker-extract with SIGKILL");
+	g_message ("Attempting to kill tracker-extract with SIGKILL");
 
-        if (kill (context->pid, SIGKILL) == -1) {
-                const gchar *str = g_strerror (errno);
+	if (kill (context->pid, SIGKILL) == -1) {
+		const gchar *str = g_strerror (errno);
 
-                g_message ("  Could not kill process %d, %s",
-                           context->pid,
-                           str ? str : "no error given");
-        } else {
-                g_message ("  Killed process %d", context->pid);
-        }
+		g_message ("  Could not kill process %d, %s",
+			   context->pid,
+			   str ? str : "no error given");
+	} else {
+		g_message ("  Killed process %d", context->pid);
+	}
 }
 
 static void
 metadata_utils_add_embedded_data (TrackerModuleMetadata *metadata,
-                                  TrackerProperty          *field,
-                                  const gchar           *value)
+				  const gchar           *uri,
+				  TrackerProperty       *field,
+				  const gchar           *value)
 {
-        gchar *utf_value;
-
-        if (!g_utf8_validate (value, -1, NULL)) {
-                utf_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
-        } else {
-                utf_value = g_strdup (value);
-        }
+	gchar *utf_value;
 
-        if (utf_value) {
-                const gchar *name;
+	if (!g_utf8_validate (value, -1, NULL)) {
+		utf_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
+	} else {
+		utf_value = g_strdup (value);
+	}
 
-                name = tracker_property_get_name (field);
+	if (utf_value) {
+		const gchar *predicate;
 
-                if (tracker_property_get_data_type (field) == TRACKER_PROPERTY_TYPE_DATE) {
-                        gchar *time_str;
+		predicate = tracker_property_get_uri (field);
 
-                        /* Dates come in ISO 8601 format, we handle them as time_t */
-                        time_str = tracker_date_to_time_string (utf_value);
-                        tracker_module_metadata_add_string (metadata, name, time_str);
-                        g_free (time_str);
-                } else {
-                        tracker_module_metadata_add_string (metadata, name, utf_value);
-                }
+		tracker_module_metadata_add_string (metadata, uri, predicate, utf_value);
 
-                g_free (utf_value);
-        }
+		g_free (utf_value);
+	}
 }
 
 static void
-metadata_utils_get_embedded_foreach (gpointer key,
-                                     gpointer value,
-                                     gpointer user_data)
+metadata_utils_get_embedded_foreach (TrackerModuleMetadata *metadata,
+                                     const gchar           *uri,
+                                     const gchar           *key,
+                                     const gchar           *value)
 {
-        TrackerModuleMetadata *metadata;
-        TrackerProperty *field;
-        gchar *key_str;
-        gchar *value_str;
-
-        metadata = user_data;
-        key_str = key;
-        value_str = value;
-        
-        if (!key || !value) {
-                return;
-        }
-        
-        field = tracker_ontology_get_field_by_name (key_str);
-        if (!field) {
-                g_warning ("Field name '%s' isn't described in the ontology", key_str);
-                return;
-        }
-        
-        if (tracker_property_get_multiple_values (field)) {
-                GStrv strv;
-                guint i;
-                
-                strv = g_strsplit (value_str, "|", -1);
-                
-                for (i = 0; strv[i]; i++) {
-                        metadata_utils_add_embedded_data (metadata, field, strv[i]);
-                }
-                
-                g_strfreev (strv);
-        } else {
-                metadata_utils_add_embedded_data (metadata, field, value_str);
-        }
+	TrackerProperty *field;
+	
+	if (!key || !value) {
+		return;
+	}
+	
+	field = tracker_ontology_get_property_by_uri (key);
+	if (!field) {
+		g_warning ("Field name '%s' isn't described in the ontology", key);
+		return;
+	}
+	
+	metadata_utils_add_embedded_data (metadata, uri, field, value);
 }
 
 static void
 get_metadata_async_cb (DBusGProxy *proxy,
-                       GHashTable *values,
-                       GError     *error,
-                       gpointer    user_data)
+		       GPtrArray  *statements,
+		       GError     *error,
+		       gpointer    user_data)
 {
-        ExtractorContext *context;
-        gboolean should_kill = TRUE;
-
-        context = (ExtractorContext *) user_data;
-
-        if (error) {
-                switch (error->code) {
-                case DBUS_GERROR_FAILED:
-                case DBUS_GERROR_NO_MEMORY:
-                case DBUS_GERROR_NO_REPLY:
-                case DBUS_GERROR_IO_ERROR:
-                case DBUS_GERROR_LIMITS_EXCEEDED:
-                case DBUS_GERROR_TIMEOUT:
-                case DBUS_GERROR_DISCONNECTED:
-                case DBUS_GERROR_TIMED_OUT:
-                case DBUS_GERROR_REMOTE_EXCEPTION:
-                        break;
-
-                default:
-                        should_kill = FALSE;
-                        break;
-                }
-
-                g_message ("Couldn't extract metadata, %s",
-                           error->message);
-
-                g_clear_error (&error);
-
-                if (should_kill) {
-                        extractor_context_kill (context);
-                }
-        } else if (values) {
-                g_hash_table_foreach (values,
-                                      metadata_utils_get_embedded_foreach,
-                                      context->metadata);
-
-                g_hash_table_destroy (values);
-        }
-
-        g_main_loop_quit (context->main_loop);
+	ExtractorContext *context;
+	gint i;
+
+	gboolean should_kill = TRUE;
+
+	context = (ExtractorContext *) user_data;
+
+	if (error) {
+		switch (error->code) {
+		case DBUS_GERROR_FAILED:
+		case DBUS_GERROR_NO_MEMORY:
+		case DBUS_GERROR_NO_REPLY:
+		case DBUS_GERROR_IO_ERROR:
+		case DBUS_GERROR_LIMITS_EXCEEDED:
+		case DBUS_GERROR_TIMEOUT:
+		case DBUS_GERROR_DISCONNECTED:
+		case DBUS_GERROR_TIMED_OUT:
+		case DBUS_GERROR_REMOTE_EXCEPTION:
+			break;
+
+		default:
+			should_kill = FALSE;
+			break;
+		}
+
+		g_message ("Couldn't extract metadata, %s",
+			   error->message);
+
+		g_clear_error (&error);
+
+		if (should_kill) {
+			extractor_context_kill (context);
+		}
+	} else if (statements) {
+		for (i = 0; i < statements->len; i++) {
+			GValueArray *statement;
+			const gchar *subject;
+			const gchar *predicate;
+			const gchar *object;
+
+			statement = statements->pdata[i];
+			subject = g_value_get_string (&statement->values[0]);
+			predicate = g_value_get_string (&statement->values[1]);
+			object = g_value_get_string (&statement->values[2]);
+
+			metadata_utils_get_embedded_foreach (context->metadata, subject, predicate, object);
+
+			g_value_array_free (statement);
+		}
+
+		g_ptr_array_free (statements, TRUE);
+	}
+
+	g_main_loop_quit (context->main_loop);
 }
 
 static void
-metadata_utils_get_embedded (GFile                 *file,
-                             const char            *mime_type,
-                             TrackerModuleMetadata *metadata)
+metadata_utils_get_embedded (GFile		 *file,
+			     const char	    *mime_type,
+			     TrackerModuleMetadata *metadata)
 {
-        ExtractorContext *context;
-        const gchar *service_type;
-        gchar *path;
+	ExtractorContext *context;
+	gchar *uri;
 
-        service_type = tracker_ontology_get_service_by_mime (mime_type);
-        if (!service_type) {
-                return;
-        }
-
-        if (!tracker_ontology_service_has_metadata (service_type)) {
-                return;
-        }
-
-        context = extractor_context_create (metadata);
+	context = extractor_context_create (metadata);
 
 	if (!context) {
 		return;
 	}
 
 	g_object_set_data (G_OBJECT (file), "extractor-context", context);
-        path = g_file_get_path (file);
+	uri = g_file_get_uri (file);
 
-        org_freedesktop_Tracker_Extract_get_metadata_async (get_dbus_extract_proxy (),
-                                                            path,
-                                                            mime_type,
-                                                            get_metadata_async_cb,
-                                                            context);
+	org_freedesktop_Tracker_Extract_get_metadata_async (get_dbus_extract_proxy (),
+							    uri,
+							    mime_type,
+							    get_metadata_async_cb,
+							    context);
 
-        g_main_loop_run (context->main_loop);
+	g_main_loop_run (context->main_loop);
 
-        g_object_set_data (G_OBJECT (file), "extractor-context", NULL);
-        extractor_context_destroy (context);
-        g_free (path);
+	g_object_set_data (G_OBJECT (file), "extractor-context", NULL);
+	extractor_context_destroy (context);
+	g_free (uri);
 }
 
 static gboolean
@@ -568,9 +553,8 @@ get_file_in_locale (GString *s)
 #endif /* TRY_LOCALE_TO_UTF8_CONVERSION */
 
 static gchar *
-get_file_content (const gchar *path)
+get_file_content (GFile *file)
 {
-	GFile		 *file;
 	GFileInputStream *stream;
 	GError		 *error = NULL;
 	GString		 *s;
@@ -582,8 +566,9 @@ get_file_content (const gchar *path)
 	gboolean	  has_more_data;
 	gboolean	  has_reached_max;
 	gboolean	  is_utf8;
+	gchar		 *path;
 
-	file = g_file_new_for_path (path);
+	path = g_file_get_path (file);
 	stream = g_file_read (file, NULL, &error);
 
 	if (error) {
@@ -591,7 +576,7 @@ get_file_content (const gchar *path)
 			   path,
 			   error->message);
 		g_error_free (error);
-		g_object_unref (file);
+		g_free (path);
 
 		return NULL;
 	}
@@ -692,7 +677,7 @@ get_file_content (const gchar *path)
 		g_error_free (error);
 		g_string_free (s, TRUE);
 		g_object_unref (stream);
-		g_object_unref (file);
+		g_free (path);
 
 		return NULL;
 	}
@@ -724,13 +709,14 @@ get_file_content (const gchar *path)
 #endif	/* TRY_LOCALE_TO_UTF8_CONVERSION */
 
 	g_object_unref (stream);
-	g_object_unref (file);
 
 	if (s->len < 1) {
 		g_string_free (s, TRUE);
 		s = NULL;
 	}
 
+	g_free (path);
+
 	return s ? g_string_free (s, FALSE) : NULL;
 }
 
@@ -803,25 +789,19 @@ get_file_content_by_filter (GFile       *file,
 gchar *
 tracker_module_metadata_utils_get_text (GFile *file)
 {
-	const gchar *service_type;
-	gchar *path, *mime_type, *text;
-
-	path = g_file_get_path (file);
+	gchar *mime_type, *text;
 
-	mime_type = tracker_file_get_mime_type (path);
-	service_type = tracker_ontology_get_service_by_mime (mime_type);
+	mime_type = tracker_file_get_mime_type (file);
 
 	/* No need to filter text based files - index them directly */
-	if (service_type &&
-	    (strcmp (service_type, "Text") == 0 ||
-	     strcmp (service_type, "Development") == 0)) {
-		text = get_file_content (path);
+
+	if (g_str_has_prefix (mime_type, "text/")) {
+		text = get_file_content (file);
 	} else {
 		text = get_file_content_by_filter (file, mime_type);
 	}
 
 	g_free (mime_type);
-	g_free (path);
 
 	return text;
 }
@@ -839,62 +819,49 @@ TrackerModuleMetadata *
 tracker_module_metadata_utils_get_data (GFile *file)
 {
 	TrackerModuleMetadata *metadata;
-	struct stat st;
-	const gchar *ext;
-	gchar *path, *mime_type;
-	gchar *dirname, *basename, *path_delimited;
-
-	path = g_file_get_path (file);
-
-	if (g_lstat (path, &st) < 0) {
-		g_free (path);
+	gchar *mime_type, *uri;
+	GFileInfo *file_info;
+	guint64 time_;
+	GFile *parent;
+	gchar *parent_uri;
+
+	file_info = g_file_query_info (file, "standard::*,time::*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
+	if (!file_info) {
 		return NULL;
 	}
 
 	metadata = tracker_module_metadata_new ();
-	ext = strrchr (path, '.');
-
-	if (ext) {
-		ext++;
-		tracker_module_metadata_add_string (metadata, METADATA_FILE_EXT, ext);
-	}
-
-	mime_type = tracker_file_get_mime_type (path);
 
-	dirname = g_path_get_dirname (path);
-	basename = g_filename_display_basename (path);
-	path_delimited = g_filename_to_utf8 (path, -1, NULL, NULL, NULL);
+	uri = g_file_get_uri (file);
 
-	tracker_module_metadata_add_string (metadata, METADATA_FILE_NAME, basename);
-	tracker_module_metadata_add_string (metadata, METADATA_FILE_PATH, dirname);
-	tracker_module_metadata_add_string (metadata, METADATA_FILE_NAME_DELIMITED, path_delimited);
-	tracker_module_metadata_add_string (metadata, METADATA_FILE_MIMETYPE, mime_type);
+	mime_type = tracker_file_get_mime_type (file);
 
-	g_free (path_delimited);
-	g_free (basename);
-	g_free (dirname);
-
-	if (S_ISLNK (st.st_mode)) {
-		gchar *link_path;
-		gchar *link_path_delimited;
-
-		link_path = g_file_read_link (path, NULL);
-		link_path_delimited = g_filename_to_utf8 (link_path, -1, NULL, NULL, NULL);
-
-		tracker_module_metadata_add_string (metadata, METADATA_FILE_LINK, link_path_delimited);
+	tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NFO_FILE_DATA_OBJECT);
+	if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) {
+		tracker_module_metadata_add_string (metadata, uri, RDF_TYPE, NFO_FOLDER);
+	}
 
-		g_free (link_path_delimited);
-		g_free (link_path);
+	parent = g_file_get_parent (file);
+	if (parent) {
+		parent_uri = g_file_get_uri (parent);
+		tracker_module_metadata_add_string (metadata, uri, NFO_BELONGS_TO_CONTAINER, parent_uri);
+		g_free (parent_uri);
+		g_object_unref (parent);
 	}
 
-	tracker_module_metadata_add_uint (metadata, METADATA_FILE_SIZE, st.st_size);
-	tracker_module_metadata_add_date (metadata, METADATA_FILE_MODIFIED, st.st_mtime);
-	tracker_module_metadata_add_date (metadata, METADATA_FILE_ACCESSED, st.st_atime);
+	tracker_module_metadata_add_string (metadata, uri, NFO_FILE_NAME, g_file_info_get_display_name (file_info));
+	tracker_module_metadata_add_string (metadata, uri, NIE_MIME_TYPE, mime_type);
+
+	tracker_module_metadata_add_uint (metadata, uri, NFO_FILE_SIZE, g_file_info_get_size (file_info));
+	time_ = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+	tracker_module_metadata_add_date (metadata, uri, NFO_FILE_LAST_MODIFIED, time_);
+	time_ = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_ACCESS);
+	tracker_module_metadata_add_date (metadata, uri, NFO_FILE_LAST_ACCESSED, time_);
 
 	metadata_utils_get_embedded (file, mime_type, metadata);
 
 	g_free (mime_type);
-	g_free (path);
+	g_free (uri);
 
 	return metadata;
 }
diff --git a/src/tracker-indexer/tracker-module-metadata.c b/src/tracker-indexer/tracker-module-metadata.c
index e3d6c75..027fd4c 100644
--- a/src/tracker-indexer/tracker-module-metadata.c
+++ b/src/tracker-indexer/tracker-module-metadata.c
@@ -20,12 +20,21 @@
  */
 
 #include <glib.h>
+#include <time.h>
 #include <libtracker-common/tracker-type-utils.h>
 #include "tracker-module-metadata-private.h"
 
+typedef struct _Statement Statement;
+
+struct _Statement {
+	gchar *subject;
+	gchar *predicate;
+	gchar *object;
+};
+
 struct TrackerModuleMetadata {
 	GObject parent_instance;
-	GHashTable *table;
+	GArray *statements;
 };
 
 struct TrackerModuleMetadataClass {
@@ -49,100 +58,29 @@ tracker_module_metadata_class_init (TrackerModuleMetadataClass *klass)
 static void
 tracker_module_metadata_init (TrackerModuleMetadata *metadata)
 {
-	metadata->table = g_hash_table_new_full (g_direct_hash,
-						 g_direct_equal,
-						 (GDestroyNotify) g_object_unref,
-						 NULL);
-}
-
-static void
-free_metadata (TrackerProperty *field,
-	       gpointer      data)
-{
-	if (tracker_property_get_multiple_values (field)) {
-		GList *list;
-
-		list = (GList *) data;
-		g_list_foreach (list, (GFunc) g_free, NULL);
-		g_list_free (list);
-	} else {
-		g_free (data);
-	}
-}
-
-static gboolean
-remove_metadata_foreach (gpointer key,
-			 gpointer value,
-			 gpointer user_data)
-{
-	TrackerProperty *field;
-
-	field = (TrackerProperty *) key;
-	free_metadata (field, value);
-
-	return TRUE;
+	metadata->statements = g_array_new (FALSE, TRUE, sizeof (Statement));
 }
 
 static void
 tracker_module_metadata_finalize (GObject *object)
 {
 	TrackerModuleMetadata *metadata;
+	gint i;
 
 	metadata = TRACKER_MODULE_METADATA (object);
 
-	g_hash_table_foreach_remove (metadata->table,
-				     remove_metadata_foreach,
-				     NULL);
-
-	g_hash_table_destroy (metadata->table);
+	for (i = 0; i < metadata->statements->len; i++) {
+		Statement *stmt;
 
-	G_OBJECT_CLASS (tracker_module_metadata_parent_class)->finalize (object);
-}
-
-gconstpointer
-tracker_module_metadata_lookup (TrackerModuleMetadata *metadata,
-				const gchar           *field_name,
-				gboolean              *multiple_values)
-{
-	TrackerProperty *field;
-
-	field = tracker_ontology_get_field_by_name (field_name);
-
-	if (multiple_values) {
-		*multiple_values = tracker_property_get_multiple_values (field);
+		stmt = &g_array_index (metadata->statements, Statement, i);
+		g_free (stmt->subject);
+		g_free (stmt->predicate);
+		g_free (stmt->object);
 	}
 
-	return g_hash_table_lookup (metadata->table, field);
-}
-
-/**
- * tracker_module_metadata_clear_field:
- * @metadata: A #TrackerModuleMetadata
- * @field_name: Field name for the metadata to clear
- *
- * Clears any content for the given field name.
- **/
-void
-tracker_module_metadata_clear_field (TrackerModuleMetadata *metadata,
-				     const gchar           *field_name)
-{
-	TrackerProperty *field;
+	g_array_free (metadata->statements, TRUE);
 
-	gpointer data;
-
-	field = tracker_ontology_get_field_by_name (field_name);
-
-	if (!field) {
-		g_warning ("Field name '%s' isn't described in the ontology", field_name);
-		return;
-	}
-
-	data = g_hash_table_lookup (metadata->table, field);
-
-	if (data) {
-		free_metadata (field, data);
-		g_hash_table_remove (metadata->table, field);
-	}
+	G_OBJECT_CLASS (tracker_module_metadata_parent_class)->finalize (object);
 }
 
 /**
@@ -164,41 +102,25 @@ tracker_module_metadata_clear_field (TrackerModuleMetadata *metadata,
  **/
 gboolean
 tracker_module_metadata_add_take_string (TrackerModuleMetadata *metadata,
-					 const gchar           *field_name,
+					 const gchar           *subject,
+					 const gchar           *predicate,
 					 gchar                 *value)
 {
-	TrackerProperty *field;
-	gpointer data;
+	Statement stmt;
 
 	g_return_val_if_fail (metadata != NULL, FALSE);
-	g_return_val_if_fail (field_name != NULL, FALSE);
+	g_return_val_if_fail (subject != NULL, FALSE);
+	g_return_val_if_fail (predicate != NULL, FALSE);
 
 	if (!value) {
 		return FALSE;
 	}
 
-	field = tracker_ontology_get_field_by_name (field_name);
+	stmt.subject = g_strdup (subject);
+	stmt.predicate = g_strdup (predicate);
+	stmt.object = value;
 
-	if (!field) {
-		g_warning ("Field name '%s' isn't described in the ontology", field_name);
-		return FALSE;
-	}
-
-	if (tracker_property_get_multiple_values (field)) {
-		GList *list;
-
-		list = g_hash_table_lookup (metadata->table, field);
-		list = g_list_prepend (list, value);
-		data = list;
-	} else {
-		data = g_hash_table_lookup (metadata->table, field);
-		g_free (data);
-		data = value;
-	}
-
-	g_hash_table_replace (metadata->table,
-			      g_object_ref (field),
-			      data);
+	g_array_append_val (metadata->statements, stmt);
 
 	return TRUE;
 }
@@ -214,14 +136,15 @@ tracker_module_metadata_add_take_string (TrackerModuleMetadata *metadata,
  **/
 void
 tracker_module_metadata_add_string (TrackerModuleMetadata *metadata,
-				    const gchar           *field_name,
+				    const gchar           *subject,
+				    const gchar           *predicate,
 				    const gchar           *value)
 {
 	gchar *str;
 
 	str = g_strdup (value);
 
-	if (!tracker_module_metadata_add_take_string (metadata, field_name, str)) {
+	if (!tracker_module_metadata_add_take_string (metadata, subject, predicate, str)) {
 		g_free (str);
 	}
 }
@@ -237,14 +160,15 @@ tracker_module_metadata_add_string (TrackerModuleMetadata *metadata,
  **/
 void
 tracker_module_metadata_add_int (TrackerModuleMetadata *metadata,
-				 const gchar           *field_name,
+				 const gchar           *subject,
+				 const gchar           *predicate,
 				 gint                   value)
 {
 	gchar *str;
 
 	str = tracker_gint_to_string (value);
 
-	if (!tracker_module_metadata_add_take_string (metadata, field_name, str)) {
+	if (!tracker_module_metadata_add_take_string (metadata, subject, predicate, str)) {
 		g_free (str);
 	}
 }
@@ -260,14 +184,15 @@ tracker_module_metadata_add_int (TrackerModuleMetadata *metadata,
  **/
 void
 tracker_module_metadata_add_uint (TrackerModuleMetadata *metadata,
-				  const gchar           *field_name,
+				  const gchar           *subject,
+				  const gchar           *predicate,
 				  guint                  value)
 {
 	gchar *str;
 
 	str = tracker_guint_to_string (value);
 
-	if (!tracker_module_metadata_add_take_string (metadata, field_name, str)) {
+	if (!tracker_module_metadata_add_take_string (metadata, subject, predicate, str)) {
 		g_free (str);
 	}
 }
@@ -283,14 +208,15 @@ tracker_module_metadata_add_uint (TrackerModuleMetadata *metadata,
  **/
 void
 tracker_module_metadata_add_double (TrackerModuleMetadata *metadata,
-				    const gchar           *field_name,
+				    const gchar           *subject,
+				    const gchar           *predicate,
 				    gdouble                value)
 {
 	gchar *str;
 
 	str = g_strdup_printf ("%f", value);
 
-	if (!tracker_module_metadata_add_take_string (metadata, field_name, str)) {
+	if (!tracker_module_metadata_add_take_string (metadata, subject, predicate, str)) {
 		g_free (str);
 	}
 }
@@ -306,14 +232,15 @@ tracker_module_metadata_add_double (TrackerModuleMetadata *metadata,
  **/
 void
 tracker_module_metadata_add_float (TrackerModuleMetadata *metadata,
-				   const gchar           *field_name,
+				   const gchar           *subject,
+				   const gchar           *predicate,
 				   gfloat                 value)
 {
 	gchar *str;
 
 	str = g_strdup_printf ("%f", value);
 
-	if (!tracker_module_metadata_add_take_string (metadata, field_name, str)) {
+	if (!tracker_module_metadata_add_take_string (metadata, subject, predicate, str)) {
 		g_free (str);
 	}
 }
@@ -329,18 +256,23 @@ tracker_module_metadata_add_float (TrackerModuleMetadata *metadata,
  **/
 void
 tracker_module_metadata_add_date (TrackerModuleMetadata *metadata,
-				  const gchar           *field_name,
+				  const gchar           *subject,
+				  const gchar           *predicate,
 				  time_t                 value)
 {
+	struct tm t;
 	gchar *str;
 
-	if (sizeof (time_t) == 8) {
-		str = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) value);
-	} else {
-		str = g_strdup_printf ("%d", (gint32) value);
-	}
+	gmtime_r (&value, &t);
+	str = g_strdup_printf ("%04d-%02d-%02dT%02d:%02d:%02d",
+	                       t.tm_year + 1900,
+	                       t.tm_mon + 1,
+	                       t.tm_mday,
+	                       t.tm_hour,
+	                       t.tm_min,
+	                       t.tm_sec);
 
-	if (!tracker_module_metadata_add_take_string (metadata, field_name, str)) {
+	if (!tracker_module_metadata_add_take_string (metadata, subject, predicate, str)) {
 		g_free (str);
 	}
 }
@@ -358,46 +290,14 @@ tracker_module_metadata_foreach (TrackerModuleMetadata        *metadata,
 				 TrackerModuleMetadataForeach  func,
 				 gpointer		       user_data)
 {
-	g_hash_table_foreach (metadata->table,
-			      (GHFunc) func,
-			      user_data);
-}
-
-void
-tracker_module_metadata_foreach_remove (TrackerModuleMetadata       *metadata,
-					TrackerModuleMetadataRemove  func,
-					gpointer                     user_data)
-{
-	g_hash_table_foreach_remove (metadata->table,
-				     (GHRFunc) func,
-				     user_data);
-}
-
-static void
-get_hash_table_foreach (gpointer key,
-			gpointer value,
-			gpointer user_data)
-{
-	TrackerProperty *field;
-	GHashTable *table;
-
-	field = TRACKER_PROPERTY (key);
-	table = user_data;
+	gint i;
 
-	g_hash_table_insert (table,
-			     (gpointer) tracker_property_get_name (field),
-			     value);
-}
+	for (i = 0; i < metadata->statements->len; i++) {
+		Statement *stmt;
 
-GHashTable *
-tracker_module_metadata_get_hash_table (TrackerModuleMetadata *metadata)
-{
-	GHashTable *table;
-
-	table = g_hash_table_new (g_str_hash, g_str_equal);
-	g_hash_table_foreach (metadata->table, (GHFunc) get_hash_table_foreach, table);
-
-	return table;
+		stmt = &g_array_index (metadata->statements, Statement, i);
+		func (stmt->subject, stmt->predicate, stmt->object, user_data);
+	}
 }
 
 /**
diff --git a/src/tracker-indexer/tracker-module-metadata.h b/src/tracker-indexer/tracker-module-metadata.h
index 831ddef..2e154cb 100644
--- a/src/tracker-indexer/tracker-module-metadata.h
+++ b/src/tracker-indexer/tracker-module-metadata.h
@@ -47,29 +47,33 @@ GType                  tracker_module_metadata_get_type         (void) G_GNUC_CO
 
 TrackerModuleMetadata *tracker_module_metadata_new              (void);
 
-void                   tracker_module_metadata_clear_field      (TrackerModuleMetadata *metadata,
-								 const gchar           *field_name);
-
 gboolean               tracker_module_metadata_add_take_string  (TrackerModuleMetadata *metadata,
-								 const gchar           *field_name,
+								 const gchar           *subject,
+								 const gchar           *predicate,
 								 gchar                 *value);
 void                   tracker_module_metadata_add_string       (TrackerModuleMetadata *metadata,
-								 const gchar           *field_name,
+								 const gchar           *subject,
+								 const gchar           *predicate,
 								 const gchar           *value);
 void                   tracker_module_metadata_add_int          (TrackerModuleMetadata *metadata,
-								 const gchar           *field_name,
+								 const gchar           *subject,
+								 const gchar           *predicate,
 								 gint                   value);
 void                   tracker_module_metadata_add_uint         (TrackerModuleMetadata *metadata,
-								 const gchar           *field_name,
+								 const gchar           *subject,
+								 const gchar           *predicate,
 								 guint                  value);
 void                   tracker_module_metadata_add_double       (TrackerModuleMetadata *metadata,
-								 const gchar           *field_name,
+								 const gchar           *subject,
+								 const gchar           *predicate,
 								 gdouble                value);
 void                   tracker_module_metadata_add_float        (TrackerModuleMetadata *metadata,
-								 const gchar           *field_name,
+								 const gchar           *subject,
+								 const gchar           *predicate,
 								 gfloat                 value);
 void                   tracker_module_metadata_add_date         (TrackerModuleMetadata *metadata,
-								 const gchar           *field_name,
+								 const gchar           *subject,
+								 const gchar           *predicate,
 								 time_t                 value);
 
 G_END_DECLS
diff --git a/src/tracker-indexer/tracker-removable-device.c b/src/tracker-indexer/tracker-removable-device.c
index d9dfa7f..0fe4833 100644
--- a/src/tracker-indexer/tracker-removable-device.c
+++ b/src/tracker-indexer/tracker-removable-device.c
@@ -20,19 +20,6 @@
  * Author: Philip Van Hoof <philip codeminded be>
  */
 
-/* When merging the decomposed branch to trunk: this filed used to be called
- * tracker-indexer/tracker-turtle.c. What has happened in trunk is that this
- * file got renamed to tracker-indexer/tracker-removable-device.c and that
- * we created a new file libtracker-data/tracker-turtle.c which contains some
- * of the functions that used to be available in this file. 
- *
- * The reason for that is that Ivan's backup support, which runs in trackerd,
- * needed access to the same Turtle related routines. So we moved it to one of
- * our internally shared libraries (libtracker-data got elected for this). 
- *
- * When merging the decomposed branch, simply pick this file over the file 
- * tracker-indexer/tracker-turtle.c (in the decomposed branch). */
-
 #include "config.h"
 
 
@@ -61,21 +48,20 @@ typedef struct {
 	gchar *base;
 	guint amount;
 	TrackerIndexer *indexer;
-	TrackerModuleMetadata *metadata;
-	gchar *rdf_type;
+	GHashTable *metadata;
 } TurtleStorerInfo;
 
-typedef struct {
-	raptor_serializer *serializer;
-	gchar *about_uri;
-} AddMetadataInfo;
-
 typedef enum {
 	REMOVAL,
 	REPLACE,
 	MOVE
 } StorerTask;
 
+typedef struct {
+	raptor_serializer *serializer;
+	gchar *about_uri;
+} AddMetadataInfo;
+
 static void
 commit_turtle_parse_info_storer (TurtleStorerInfo *info, 
 				 gboolean          may_flush, 
@@ -83,70 +69,33 @@ commit_turtle_parse_info_storer (TurtleStorerInfo *info,
 				 const gchar      *destination)
 {
 	if (info->last_subject) {
-		GHashTable *data;
-		GFile *file, *dest_file = NULL;
-		gchar *path, *dest_path = NULL;
-
-		/* We have it as a URI, database api wants Paths. Update this when
-		 * the database api becomes sane and uses URIs everywhere
-		 */
-		file = g_file_new_for_uri (info->last_subject);
-		path = g_file_get_path (file);
-
-		if (destination) {
-			dest_file = g_file_new_for_uri (destination);
-			dest_path = g_file_get_path (dest_file);
-		}
-
-		if (info->rdf_type) {
-			/* We ignore records that didn't have an <rdf:type> 
-			 * predicate. Those are just wrong anyway.
-			 */
-			switch (task) {
-			case REMOVAL:
-				tracker_data_update_delete_service_by_path (path, info->rdf_type);
-				break;
-			case MOVE:
-				data = tracker_module_metadata_get_hash_table (info->metadata);
-				tracker_data_update_delete_service_by_path (path, info->rdf_type);
-				tracker_data_update_replace_service (dest_path,
-								     info->rdf_type,
-								     data);
-				g_hash_table_destroy (data);
-				break;
-			case REPLACE:
-			default:
-				data = tracker_module_metadata_get_hash_table (info->metadata);
-				tracker_data_update_replace_service (path,
-								     info->rdf_type,
-								     data);
-				g_hash_table_destroy (data);
-				break;
-			}
+		switch (task) {
+		    case REMOVAL:
+			tracker_data_delete_resource (info->last_subject);
+		    break;
+		    case MOVE:
+			tracker_data_delete_resource (info->last_subject);
+			tracker_data_update_replace_service (destination, 
+							     info->metadata);
+		    break;
+		    default:
+		    case REPLACE:
+			tracker_data_update_replace_service (info->last_subject, 
+							     info->metadata);
+		    break;
 		}
 
 		info->amount++;
 
-		g_object_unref (info->metadata);
-		g_object_unref (file);
-
-		if (dest_file) {
-			g_object_unref (dest_file);
-		}
-
-		g_free (path);
-		g_free (dest_path);
+		g_hash_table_destroy (info->metadata);
 		g_free (info->last_subject);
-		g_free (info->rdf_type);
-
 		info->last_subject = NULL;
 		info->metadata = NULL;
-		info->rdf_type = NULL;
 	}
 
-	/* We commit per transaction of 100 here, and then we also iterate the
-	 * mainloop so that the state-machine gets the opportunity to run for a
-	 * moment */
+	/* We commit per transaction of TRACKER_INDEXER_TRANSACTION_MAX here, 
+	 * and then we also iterate the mainloop so that the state-machine 
+	 * gets the opportunity to run for a moment */
 
 	if (may_flush && info->amount > TRACKER_INDEXER_TRANSACTION_MAX) {
 		tracker_indexer_transaction_commit (info->indexer);
@@ -156,28 +105,16 @@ commit_turtle_parse_info_storer (TurtleStorerInfo *info,
 	}
 }
 
-static gchar *
-get_uri_with_trailing_slash (GFile *file)
-{
-	gchar *uri, *str;
-
-	uri = g_file_get_uri (file);
-	str = g_strdup_printf ("%s/", uri);
-	g_free (uri);
-
-	return str;
-}
-
 static void
-consume_triple_storer (void                   *user_data, 
-		       const raptor_statement *triple) 
+consume_triple_storer (const gchar *subject,
+                       const gchar *predicate,
+                       const gchar *object,
+                       void        *user_data) 
 {
 	TurtleStorerInfo *info = user_data;
-	gchar            *subject;
-
-	/* TODO: cope with multi-value values like User:Keywords */
 
-	subject = (gchar *) raptor_uri_as_string ((raptor_uri *) triple->subject);
+	if (!object || !predicate)
+		return;
 
 	if (!info->last_subject || g_strcmp0 (subject, info->last_subject) != 0) {
 
@@ -186,72 +123,41 @@ consume_triple_storer (void                   *user_data,
 
 		/* Install next subject */
 		info->last_subject = g_strdup (subject);
-		info->metadata = tracker_module_metadata_new ();
+		info->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
+							(GDestroyNotify) g_free,
+							(GDestroyNotify) g_free);
 	}
 
-	if (triple->object_type == RAPTOR_IDENTIFIER_TYPE_LITERAL) {
-		gchar *predicate;
-
-		predicate = g_strdup ((const gchar *) raptor_uri_as_string ((raptor_uri *) triple->predicate));
-
-		if (g_strcmp0 (predicate, "rdf:type") == 0) {
-			g_free (info->rdf_type);
-
-			/* TODO: ontology */
-			/* Change this when Files and Emails becomes File and Email */
-
-			info->rdf_type = g_strdup_printf ("%ss", (gchar *) triple->object);
-		} else {
-			tracker_module_metadata_add_string (info->metadata,
-							    predicate,
-							    triple->object);
-		}
-
-	} else if (triple->object_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE) {
-		GFile *file;
-		gchar *key;
-
-		file = g_file_new_for_path (info->base);
-		key = get_uri_with_trailing_slash (file);
-
-		if (g_strcmp0 (key, triple->object) == 0 &&
-		    g_strcmp0 (key, triple->predicate) == 0) {
-			/* <URI> <rdf:type> "Type" ;                    *
-			 *       <> <>  -  is a removal of the resource */
-
-			/* We commit this subject as a removal, the last_subject
-			 * field will be cleared for the next subject to be set
-			 * ready first next process loop. */
-
-			commit_turtle_parse_info_storer (info, FALSE, REMOVAL, NULL);
-		} else if (g_strcmp0 (key, triple->object) == 0 &&
-			   g_strcmp0 (key, triple->predicate) != 0) {
-			gchar        *predicate;
-
-			/* <URI> <rdf:type> "Type" ;                             *
-			 *       <Pfx:Predicate> <>  -  is a removal of the      * 
-			 *                              resource's Pfx:Predicate */
-
-			predicate = (gchar *) raptor_uri_as_string ((raptor_uri *) triple->predicate);
-
-			/* We put NULL here, so that a null value goes into 
-			 * SQLite. Perhaps we should change this? If so, Why? */
-
-			tracker_module_metadata_add_string (info->metadata,
-							    predicate,
-							    NULL);
-
-		} else if (g_strcmp0 (key, triple->object) != 0 &&
-			   g_strcmp0 (key, triple->predicate) == 0) {
-			gchar        *object;
-			/* <URI> <> <to-URI>  -  is a move of the subject */
-			object = (gchar *) raptor_uri_as_string ((raptor_uri *) triple->object);
-			commit_turtle_parse_info_storer (info, FALSE, MOVE, object);
-
-		}
-
-		g_free (key);
-		g_object_unref (file);
+	
+	if (object[0] == '\0' && predicate[0] == '\0') {
+		/* <URI> <rdf:type> "Type" ;                    *
+		 *       <> <>  -  is a removal of the resource */
+
+		/* We commit this subject as a removal, the last_subject
+		 * field will be cleared for the next subject to be set
+		 * ready first next process loop. */
+
+		commit_turtle_parse_info_storer (info, FALSE, REMOVAL, NULL);
+	} else
+	if (object[0] == '\0' && predicate[0] != '\0') {
+		/* <URI> <rdf:type> "Type" ;                             *
+		 *       <Pfx:Predicate> <>  -  is a removal of the      * 
+		 *                              resource's Pfx:Predicate */
+
+		/* We put NULL here, so that a null value goes into 
+		 * SQLite. Perhaps we should change this? If so, Why? */
+
+		g_hash_table_replace (info->metadata,
+				      g_strdup (predicate),
+				      NULL);
+	} else
+	if (object[0] != '\0' && predicate[0] == '\0') {
+		/* <URI> <> <to-URI>  -  is a move of the subject */
+		commit_turtle_parse_info_storer (info, FALSE, MOVE, object);
+	} else {
+		g_hash_table_replace  (info->metadata,
+				       g_strdup (predicate),
+				       g_strdup (object));
 	}
 }
 
@@ -287,43 +193,42 @@ tracker_removable_device_load (TrackerIndexer *indexer,
 				     NULL);
 
 	if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
-		TurtleStorerInfo *info;
-		GFile            *file;
-		gchar            *base_uri;
-
-		info = g_slice_new0 (TurtleStorerInfo);
+		TurtleStorerInfo  info;
+		gchar            *base_uri, *tmp;
+		GFile            *mountp_file;
 
-		info->indexer = g_object_ref (indexer);
-		info->amount = 0;
+		info.indexer = g_object_ref (indexer);
+		info.amount = 0;
 
-		info->base = g_strdup (mount_point);
+		info.base = g_strdup (mount_point);
 
 		/* We need to open the transaction, during the parsing will the
 		 * transaction be committed and reopened */
 
-		tracker_indexer_transaction_open (info->indexer);
+		tracker_indexer_transaction_open (info.indexer);
 
-		file = g_file_new_for_path (mount_point);
-		base_uri = get_uri_with_trailing_slash (file);
+		mountp_file = g_file_new_for_path (mount_point);
+		tmp = g_file_get_uri (mountp_file);
+		base_uri = g_strconcat (tmp, "/", NULL);
 
-		tracker_turtle_process (filename, base_uri, consume_triple_storer, info);
+		tracker_turtle_process (filename, base_uri, consume_triple_storer, &info);
 
-		g_object_unref (file);
 		g_free (base_uri);
+		g_free (tmp);
+		g_object_unref (mountp_file);
 
 		/* Commit final subject (our loop doesn't handle the very last) 
 		 * It can't be a REMOVAL nor MOVE as those happen immediately. */
 
-		commit_turtle_parse_info_storer (info, FALSE, REPLACE, NULL);
+		commit_turtle_parse_info_storer (&info, FALSE, REPLACE, NULL);
 
 		/* We will (always) be left in open state, so we commit the 
 		 * last opened transaction */
 
-		tracker_indexer_transaction_commit (info->indexer);
+		tracker_indexer_transaction_commit (info.indexer);
 
-		g_free (info->base);
-		g_object_unref (info->indexer);
-		g_slice_free (TurtleStorerInfo, info);
+		g_free (info.base);
+		g_object_unref (info.indexer);
 	}
 
 	g_free (filename);
@@ -334,72 +239,85 @@ set_metadata (const gchar *key,
 	      const gchar *value, 
 	      gpointer     user_data)
 {
-	raptor_statement    *statement;
+	raptor_statement     statement;
 	AddMetadataInfo     *item = user_data;
 	const gchar         *about_uri = item->about_uri;
 	raptor_serializer   *serializer = item->serializer;
 
-	statement = g_new0 (raptor_statement, 1);
+	statement.subject = (void *) raptor_new_uri ((const guchar *) about_uri);
+	statement.subject_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
 
-	statement->subject = (void *) raptor_new_uri ((const unsigned char *) about_uri);
-	statement->subject_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
-
-	statement->predicate = (void *) raptor_new_uri ((const guchar *) (key ? key : ""));
-	statement->predicate_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
+	statement.predicate = (void *) raptor_new_uri ((const guchar *) (key?key:""));
+	statement.predicate_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
 
 	if (value) {
-		statement->object = (unsigned char *) g_strdup (value);
-		statement->object_type = RAPTOR_IDENTIFIER_TYPE_LITERAL;
+		statement.object = (unsigned char *) g_strdup (value);
+		statement.object_type = RAPTOR_IDENTIFIER_TYPE_LITERAL;
 	} else {
-		statement->object = (void *) raptor_new_uri ((const guchar *) (""));
-		statement->object_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
+		statement.object = (void *) raptor_new_uri ((const guchar *) (""));
+		statement.object_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
 	}
 
 	raptor_serialize_statement (serializer, 
-				    statement);
+				    &statement);
 
-	raptor_free_uri ((raptor_uri *) statement->subject);
-	raptor_free_uri ((raptor_uri *) statement->predicate);
+	raptor_free_uri ((raptor_uri *) statement.subject);
+	raptor_free_uri ((raptor_uri *) statement.predicate);
 
 	if (value) {
-		g_free ((unsigned char *) statement->object);
-	} else {
-		raptor_free_uri ((raptor_uri *) statement->object);
+		g_free ((unsigned char *) statement.object);
+	} else  {
+		raptor_free_uri ((raptor_uri *) statement.object);
 	}
-
-	g_free (statement);
 }
 
-/* TODO URI branch: path -> uri */
 static void
-foreach_in_metadata_set_metadata (TrackerProperty *field,
-				  gpointer      value,
+foreach_in_metadata_set_metadata (const gchar     *subject,
+				  const gchar     *key,
+				  const gchar     *value,
 				  gpointer      user_data)
 {
-	if (!tracker_property_get_multiple_values (field)) {
-		set_metadata (tracker_property_get_name (field), value, user_data);
-	} else {
-		GList *l;
+	raptor_statement     statement;
+	AddMetadataInfo     *item = user_data;
+	raptor_serializer   *serializer = item->serializer;
 
-		for (l = value; l; l = l->next) {
-			set_metadata (tracker_property_get_name (field), l->data, user_data);
-		}
+	statement.subject = (void *) raptor_new_uri ((const guchar *) subject);
+	statement.subject_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
+
+	statement.predicate = (void *) raptor_new_uri ((const guchar *) (key?key:""));
+	statement.predicate_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
+
+	if (value) {
+		statement.object = (unsigned char *) g_strdup (value);
+		statement.object_type = RAPTOR_IDENTIFIER_TYPE_LITERAL;
+	} else {
+		statement.object = (void *) raptor_new_uri ((const guchar *) (""));
+		statement.object_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
 	}
 
+	raptor_serialize_statement (serializer, 
+				    &statement);
+
+	raptor_free_uri ((raptor_uri *) statement.subject);
+	raptor_free_uri ((raptor_uri *) statement.predicate);
+
+	if (value)
+		g_free ((unsigned char *) statement.object);
+	else 
+		raptor_free_uri ((raptor_uri *) statement.object);
 }
 
 void
 tracker_removable_device_add_metadata (TrackerIndexer        *indexer, 
 				       const gchar           *mount_point, 
-				       const gchar           *path,
-				       const gchar           *rdf_type,
+				       const gchar           *uri,
 				       TrackerModuleMetadata *metadata)
 {
-	AddMetadataInfo *info;
-	gchar           *filename, *muri;
+	AddMetadataInfo  info;
+	gchar           *filename, *muri, *tmp;
 	FILE            *target_file;
 	raptor_uri      *suri;
-	GFile           *file, *base_file;
+	GFile           *mountp_file;
 
 	filename = g_build_filename (mount_point, 
 				     ".cache",
@@ -414,72 +332,71 @@ tracker_removable_device_add_metadata (TrackerIndexer        *indexer,
 				     "metadata.ttl", 
 				     NULL);
 
-	target_file = tracker_file_open (filename, "a+", FALSE);
+	target_file = fopen (filename, "a");
+	/* Similar to a+ */
+	if (!target_file) 
+		target_file = fopen (filename, "w");
 	g_free (filename);
 
 	if (!target_file) {
 		return;
 	}
 
-	info = g_slice_new (AddMetadataInfo);
+	info.serializer = raptor_new_serializer ("turtle");
 
-	info->serializer = raptor_new_serializer ("turtle");
-	info->about_uri = g_strdup (path + strlen (mount_point) + 1);
+	/* TODO: paths to URIs: this is wrong */
+	info.about_uri = g_strdup (uri+strlen (mount_point)+1+7);
 
-	raptor_serializer_set_feature (info->serializer, 
+	raptor_serializer_set_feature (info.serializer, 
 				       RAPTOR_FEATURE_WRITE_BASE_URI, 0);
 
-	raptor_serializer_set_feature (info->serializer, 
+	raptor_serializer_set_feature (info.serializer, 
 				       RAPTOR_FEATURE_ASSUME_IS_RDF, 1);
 
-	raptor_serializer_set_feature (info->serializer, 
+	raptor_serializer_set_feature (info.serializer, 
 				       RAPTOR_FEATURE_ALLOW_NON_NS_ATTRIBUTES, 1);
 
-	file = g_file_new_for_path (mount_point);
-	base_file = g_file_get_child (file, "base");
-	muri = g_file_get_uri (base_file);
 
-	suri = raptor_new_uri ((const unsigned char *) muri);
+	mountp_file = g_file_new_for_path (mount_point);
+	tmp = g_file_get_uri (mountp_file);
+	muri = g_strconcat (tmp, "/base", NULL);
+
+	suri = raptor_new_uri ((const guchar *) muri);
 
-	g_object_unref (file);
-	g_object_unref (base_file);
 	g_free (muri);
+	g_free (tmp);
+	g_object_unref (mountp_file);
 
-	raptor_serialize_start_to_file_handle (info->serializer, 
-					       suri, 
+	raptor_serialize_start_to_file_handle (info.serializer, 
+					       suri,
 					       target_file);
 
-	set_metadata ("rdf:type", rdf_type, info);
-
 	tracker_module_metadata_foreach (metadata, 
 					 foreach_in_metadata_set_metadata,
-					 info);
+					 &info);
 
-	g_free (info->about_uri);
+	g_free (info.about_uri);
 
-	raptor_serialize_end (info->serializer);
-	raptor_free_serializer (info->serializer);
+	raptor_serialize_end (info.serializer);
+	raptor_free_serializer (info.serializer);
 	raptor_free_uri (suri);
 
-	g_slice_free (AddMetadataInfo, info);
-
-	tracker_file_close (target_file, FALSE);
+	fclose (target_file);
 }
 
 /* TODO URI branch: path -> uri */
 
 void
 tracker_removable_device_add_removal (TrackerIndexer *indexer, 
-				      const gchar    *mount_point, 
-				      const gchar    *path,
-				      const gchar    *rdf_type)
+				      const gchar *mount_point, 
+				      const gchar *uri)
 {
-	gchar               *filename, *about_uri, *muri;
+	gchar               *filename, *about_uri, *muri, *tmp;
 	FILE                *target_file;
 	raptor_uri          *suri;
 	raptor_serializer   *serializer;
-	AddMetadataInfo     *info;
-	GFile               *file, *base_file;
+	AddMetadataInfo      info;
+	GFile               *mountp_file;
 
 	filename = g_build_filename (mount_point,
 				     ".cache",
@@ -493,7 +410,10 @@ tracker_removable_device_add_removal (TrackerIndexer *indexer,
 				     "metadata.ttl", 
 				     NULL);
 
-	target_file = tracker_file_open (filename, "a+", FALSE);
+	target_file = fopen (filename, "a");
+	/* Similar to a+ */
+	if (!target_file) 
+		target_file = fopen (filename, "w");
 	g_free (filename);
 
 	if (!target_file) {
@@ -501,60 +421,56 @@ tracker_removable_device_add_removal (TrackerIndexer *indexer,
 	}
 
 	serializer = raptor_new_serializer ("turtle");
-	about_uri = g_strdup (path + strlen (mount_point) + 1);
+
+	/* TODO: paths to URIs: this is wrong */
+	about_uri = g_strdup (uri+strlen (mount_point)+1+7);
 
 	raptor_serializer_set_feature (serializer, 
 				       RAPTOR_FEATURE_WRITE_BASE_URI,
 				       0);
 
-	file = g_file_new_for_path (mount_point);
-	base_file = g_file_get_child (file, "base");
+	mountp_file = g_file_new_for_path (mount_point);
+	tmp = g_file_get_uri (mountp_file);
+	muri = g_strconcat (tmp, "/base", NULL);
 
-	muri = g_file_get_uri (base_file);
 	suri = raptor_new_uri ((const unsigned char *) muri);
 
-	g_object_unref (base_file);
-	g_object_unref (file);
 	g_free (muri);
+	g_free (tmp);
+	g_object_unref (mountp_file);
 
 	raptor_serialize_start_to_file_handle (serializer, 
 					       suri, 
 					       target_file);
 
-	info = g_slice_new (AddMetadataInfo);
-
-	info->serializer = serializer;
-	info->about_uri = about_uri;
+	info.serializer = serializer;
+	info.about_uri = about_uri;
 
-	set_metadata ("rdf:type", rdf_type, info);
-	set_metadata (NULL, NULL, info);
+	set_metadata (NULL, NULL, &info);
 
 	raptor_free_uri (suri);
-
-	g_slice_free (AddMetadataInfo, info);
 	g_free (about_uri);
 
 	raptor_serialize_end (serializer);
 	raptor_free_serializer (serializer);
 
-	tracker_file_close (target_file, FALSE);
+	fclose (target_file);
 }
 
 /* TODO URI branch: path -> uri */
 
 void
 tracker_removable_device_add_move (TrackerIndexer *indexer, 
-				   const gchar    *mount_point, 
-				   const gchar    *from_path, 
-				   const gchar    *to_path,
-				   const gchar    *rdf_type)
+				   const gchar *mount_point, 
+				   const gchar *from_uri, 
+				   const gchar *to_uri)
 {
-	gchar               *filename, *about_uri, *to_uri, *muri;
+	gchar               *filename, *about_uri, *to_urip, *muri, *tmp;
 	FILE                *target_file;
 	raptor_uri          *suri;
 	raptor_serializer   *serializer;
-	AddMetadataInfo     *info;
-	GFile               *file;
+	AddMetadataInfo      info;
+	GFile               *mountp_file;
 
 	filename = g_build_filename (mount_point,
 				     ".cache",
@@ -569,7 +485,10 @@ tracker_removable_device_add_move (TrackerIndexer *indexer,
 				     "metadata.ttl", 
 				     NULL);
 
-	target_file = tracker_file_open (filename, "a+", FALSE);
+	target_file = fopen (filename, "a");
+	/* Similar to a+ */
+	if (!target_file) 
+		target_file = fopen (filename, "w");
 	g_free (filename);
 
 	if (!target_file) {
@@ -581,38 +500,37 @@ tracker_removable_device_add_move (TrackerIndexer *indexer,
 	raptor_serializer_set_feature (serializer, 
 				       RAPTOR_FEATURE_WRITE_BASE_URI, 0);
 
-	about_uri = g_strdup (from_path + strlen (mount_point) + 1);
-	to_uri = g_strdup (to_path + strlen (mount_point) + 1);
+	/* TODO: paths to URIs: this is wrong */
+	about_uri = g_strdup (from_uri+strlen (mount_point)+1+7);
+	/* TODO: paths to URIs: this is wrong */
+	to_urip = g_strdup (to_uri+strlen (mount_point)+1+7);
 
-	file = g_file_new_for_path (mount_point);
-	muri = get_uri_with_trailing_slash (file);
-	suri = raptor_new_uri ((const unsigned char *) muri);
+	mountp_file = g_file_new_for_path (mount_point);
+	tmp = g_file_get_uri (mountp_file);
+	muri = g_strconcat (tmp, "/", NULL);
+
+	suri = raptor_new_uri ((const guchar *) muri);
 
-	g_object_unref (file);
 	g_free (muri);
+	g_free (tmp);
+	g_object_unref (mountp_file);
 
 	raptor_serialize_start_to_file_handle (serializer, 
 					       suri,
 					       target_file);
 
-	info = g_slice_new (AddMetadataInfo);
-
-	info->serializer = serializer;
-	info->about_uri = about_uri;
-
-	set_metadata ("rdf:type", rdf_type, info);
-	set_metadata (NULL, to_uri, info);
-
-	g_slice_free (AddMetadataInfo, info);
+	info.serializer = serializer;
+	info.about_uri = about_uri;
 
+	set_metadata (NULL, to_urip, &info);
 
 	g_free (about_uri);
-	g_free (to_uri);
+	g_free (to_urip);
 
 	raptor_serialize_end (serializer);
 	raptor_free_serializer (serializer);
 	raptor_free_uri (suri);
 
-	tracker_file_close (target_file, FALSE);
+	fclose (target_file);
 }
 
diff --git a/src/tracker-indexer/tracker-removable-device.h b/src/tracker-indexer/tracker-removable-device.h
index d04d8af..07fee0b 100644
--- a/src/tracker-indexer/tracker-removable-device.h
+++ b/src/tracker-indexer/tracker-removable-device.h
@@ -23,8 +23,6 @@
 #ifndef __TRACKER_REMOVABLE_DEVICE_H__
 #define __TRACKER_REMOVABLE_DEVICE_H__
 
-#include <libtracker-data/tracker-data-metadata.h>
-
 #include "tracker-module-metadata.h"
 #include "tracker-indexer.h"
 
@@ -36,18 +34,15 @@ void    tracker_removable_device_optimize     (TrackerIndexer *indexer,
 					       const gchar *mount_point);
 void    tracker_removable_device_add_metadata (TrackerIndexer *indexer, 
 					       const gchar *mount_point,
-					       const gchar *path,
-					       const gchar *rdf_type,
+					       const gchar *uri,
 					       TrackerModuleMetadata *metadata);
 void    tracker_removable_device_add_removal  (TrackerIndexer *indexer, 
 					       const gchar *mount_point, 
-					       const gchar *path,
-					       const gchar *rdf_type);
+					       const gchar *uri);
 void    tracker_removable_device_add_move     (TrackerIndexer *indexer, 
 					       const gchar *mount_point, 
-					       const gchar *from_path, 
-					       const gchar *to_path,
-					       const gchar *rdf_type);
+					       const gchar *from_uri, 
+					       const gchar *to_uri);
 
 G_END_DECLS
 
diff --git a/src/tracker-search-tool/tracker-search-tool-callbacks.c b/src/tracker-search-tool/tracker-search-tool-callbacks.c
index 9f78152..b35bdcf 100644
--- a/src/tracker-search-tool/tracker-search-tool-callbacks.c
+++ b/src/tracker-search-tool/tracker-search-tool-callbacks.c
@@ -506,6 +506,7 @@ get_large_icon (const gchar * local_uri,
 void
 tracker_update_metadata_tile (GSearchWindow *gsearch)
 {
+#if 0
 	GtkTreeModel * model;
 	GList * list, * tmp;
 	ServiceType type;
@@ -557,6 +558,7 @@ tracker_update_metadata_tile (GSearchWindow *gsearch)
 
 	g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
 	g_list_free (list);
+#endif
 }
 
 void
@@ -603,7 +605,7 @@ open_file_cb (GtkAction * action,
 				    COLUMN_NO_FILES_FOUND, &no_files_found,
 				    -1);
 
-
+#if 0
 		if (gsearch->type == SERVICE_EMAILS) {
 			if (strstr (mime, "Evolution")) {
 				exec = g_strdup_printf ("evolution \"%s\"", uri);
@@ -659,6 +661,7 @@ open_file_cb (GtkAction * action,
 			}
 			g_object_unref (file);
 		}
+#endif
 		g_free (uri);
 
 	}
diff --git a/src/tracker-search-tool/tracker-search-tool.c b/src/tracker-search-tool/tracker-search-tool.c
index d6c2bfd..79ddff8 100644
--- a/src/tracker-search-tool/tracker-search-tool.c
+++ b/src/tracker-search-tool/tracker-search-tool.c
@@ -82,7 +82,9 @@ typedef struct _GSearchOptionTemplate GSearchOptionTemplate;
 typedef struct {
 	GSearchWindow * gsearch;
 	char  *uri;
+#if 0
 	ServiceType type;
+#endif
 
 } SnippetRow;
 
@@ -132,7 +134,8 @@ static char *search_service_types[] = {
 NULL
 };
 
-static service_info_t services[17] = {
+static service_info_t services[] = {
+#if 0
 	{ "Emails",	   N_("Emails"),       "stock_mail",		   NULL, SERVICE_EMAILS,	    NULL, FALSE, 0, 0},
 	{ "EvolutionEmails",
 			   N_("Emails"),       "stock_mail",		   NULL, SERVICE_EMAILS,	    NULL, FALSE, 0, 0},
@@ -152,6 +155,8 @@ static service_info_t services[17] = {
 	{ "Applications",  N_("Applications"), "system-run",		   NULL, SERVICE_APPLICATIONS,	    NULL, FALSE, 0, 0},
 	{ "WebHistory",    N_("WebHistory"),	"text-html",		   NULL, SERVICE_WEBHISTORY,	    NULL, FALSE, 0, 0},
 	{ NULL,		   NULL,	       NULL,			   NULL, -1,			    NULL, FALSE, 0, 0},
+#endif
+	{ NULL,		   NULL,	       NULL,			   NULL,			    NULL, FALSE, 0, 0},
 };
 
 static GSearchOptionTemplate GSearchOptionTemplates[] = {
@@ -332,7 +337,9 @@ process_snippets (GSearchWindow * gsearch)
 
 	SnippetRow *snippet = g_queue_pop_head (gsearch->snippet_queue);
 
+#if 0
 	tracker_search_get_snippet_async (tracker_client, snippet->type, snippet->uri, gsearch->search_term, set_snippet, snippet);
+#endif
 
 	return FALSE;
 }
@@ -476,7 +483,9 @@ add_email_to_search_results (const gchar * uri,
 			    COLUMN_NAME, subject,
 			    COLUMN_PATH, sender,
 			    COLUMN_MIME, mime,
+#if 0
 			    COLUMN_TYPE, SERVICE_EMAILS,
+#endif
 			    COLUMN_NO_FILES_FOUND, FALSE,
 			    -1);
 
@@ -493,7 +502,9 @@ add_email_to_search_results (const gchar * uri,
 	snippet_row = g_new (SnippetRow, 1);
 	snippet_row->gsearch = gsearch;
 	snippet_row->uri = g_strdup (uri);
+#if 0
 	snippet_row->type = SERVICE_EMAILS;
+#endif
 
 	g_queue_push_tail (gsearch->snippet_queue, snippet_row);
 	//tracker_search_get_snippet_async (tracker_client, SERVICE_EMAILS, uri, search_term, set_snippet, snippet_row);
@@ -501,7 +512,9 @@ add_email_to_search_results (const gchar * uri,
 
 static void
 add_file_to_search_results (const gchar * file_path,
+#if 0
 			    ServiceType service_type,
+#endif
 			    const gchar * mime,
 			    GtkListStore * store,
 			    GtkTreeIter * iter,
@@ -548,10 +561,13 @@ add_file_to_search_results (const gchar * file_path,
 	                    COLUMN_NAME, base_name,
 	                    COLUMN_PATH, dir_name,
 	                    COLUMN_MIME, description,
+#if 0
 	                    COLUMN_TYPE, service_type,
+#endif
 	                    COLUMN_NO_FILES_FOUND, FALSE,
 	                    -1);
 	
+#if 0
 	if (gsearch->search_term  &&
 	    (service_type == SERVICE_DOCUMENTS ||
 	     service_type == SERVICE_TEXT_FILES ||
@@ -567,6 +583,7 @@ add_file_to_search_results (const gchar * file_path,
 		
 		g_queue_push_tail (gsearch->snippet_queue, snippet_row);
 	}
+#endif
 	
 	g_object_unref (file);
 	g_object_unref (file_info);
@@ -617,7 +634,9 @@ add_application_to_search_results (const gchar * uri,
 			    COLUMN_NAME, display_name,
 			    COLUMN_PATH, _("Application"),
 			    COLUMN_MIME, "",
+#if 0
 			    COLUMN_TYPE, SERVICE_APPLICATIONS,
+#endif
 			    COLUMN_EXEC, exec,
 			    COLUMN_NO_FILES_FOUND, FALSE,
 			    -1);
@@ -1461,6 +1480,7 @@ get_meta_table_data (gpointer value,
 
 	meta = (char **)value;
 
+#if 0
 	if (gsearch->type == SERVICE_EMAILS) {
 
 		if (meta[0] && meta[1] && meta[2]) {
@@ -1501,7 +1521,7 @@ get_meta_table_data (gpointer value,
 			}
 		}
 	}
-
+#endif
 }
 
 static gint
@@ -1653,12 +1673,14 @@ get_hit_count (GPtrArray *out_array,
 
 		g_free (label_str);
 
+#if 0
 		if (gsearch->old_type == service->service_type) {
 			first_service = TRUE;
 			gsearch->current_service = service;
 			gsearch->type = service->service_type;
 			init_tab (gsearch, service);
 		}
+#endif
 	}
 
 	if (!first_service) {
@@ -1675,6 +1697,7 @@ get_hit_count (GPtrArray *out_array,
 		}
 
 		/* old category not found so go to first one with hits */
+#if 0
 		for (service = services; service->service; ++service) {
 			if (service->hit_count == 0) {
 				continue;
@@ -1687,6 +1710,7 @@ get_hit_count (GPtrArray *out_array,
 
 			break;
 		}
+#endif
 	}
 
 	gsearch->page_setup_mode = FALSE;
@@ -1723,7 +1747,9 @@ select_category (GtkTreeSelection * treeselection,
 	}
 
 	gsearch->current_service = service;
+#if 0
 	gsearch->type = service->service_type;
+#endif
 
 	g_queue_foreach (gsearch->snippet_queue, (GFunc) free_snippet, NULL);
 	g_queue_free (gsearch->snippet_queue);
@@ -1788,12 +1814,14 @@ end_refresh_count (int count, GError * error, gpointer user_data)
 	GSearchWindow *gsearch = user_data;
 	service_info_t	* service;
 
+#if 0
 	for (service = services; service->service; ++service) {
 		if (service->service_type == gsearch->current_service->service_type) {
 			service->hit_count = count;
 			break;
 		}
 	}
+#endif
 
 	update_page_count_label (gsearch);
 
diff --git a/src/tracker-search-tool/tracker-search-tool.h b/src/tracker-search-tool/tracker-search-tool.h
index 7139aff..f102744 100644
--- a/src/tracker-search-tool/tracker-search-tool.h
+++ b/src/tracker-search-tool/tracker-search-tool.h
@@ -99,7 +99,9 @@ typedef struct {
 	gchar		*display_name;
 	gchar		*icon_name;
 	GdkPixbuf	*pixbuf;
+#if 0
 	ServiceType	service_type;
+#endif
 	GtkListStore	*store;
 	gboolean	has_hits;
 	gint		hit_count;
diff --git a/src/tracker-utils/.gitignore b/src/tracker-utils/.gitignore
index e2e28c9..3cf2682 100644
--- a/src/tracker-utils/.gitignore
+++ b/src/tracker-utils/.gitignore
@@ -1,7 +1,10 @@
+tracker-files
 tracker-info
+tracker-meta-folder
 tracker-processes
 tracker-query
 tracker-search
+tracker-services
 tracker-stats
 tracker-status
 tracker-tag
diff --git a/src/tracker-utils/Makefile.am b/src/tracker-utils/Makefile.am
index 3f67376..b817ac8 100644
--- a/src/tracker-utils/Makefile.am
+++ b/src/tracker-utils/Makefile.am
@@ -19,12 +19,12 @@ libs = 									\
 	$(GCOV_LIBS)							\
 	$(GLIB2_LIBS)
 
-bin_PROGRAMS = 								\
-	tracker-search 							\
-	tracker-stats							\
-	tracker-tag							\
-	tracker-status							\
-	tracker-info							\
+bin_PROGRAMS = 							\
+	tracker-search 						\
+	tracker-stats						\
+	tracker-tag						\
+	tracker-status						\
+	tracker-info						\
 	tracker-processes
 
 tracker_search_SOURCES = tracker-search.c
diff --git a/src/tracker-utils/tracker-info.c b/src/tracker-utils/tracker-info.c
index ff54fe6..efdca89 100644
--- a/src/tracker-utils/tracker-info.c
+++ b/src/tracker-utils/tracker-info.c
@@ -89,7 +89,6 @@ int
 main (int argc, char **argv)
 {
 	TrackerClient	*client;
-	ServiceType	 type;
 	GFile           *file;
 	gchar           *summary;
 	gchar           *path;
@@ -159,6 +158,8 @@ main (int argc, char **argv)
 		return EXIT_FAILURE;
 	}
 
+	/* TODO: Port to SPARQL */
+#if 0
 	if (!service) {
 		g_print (_("Defaulting to 'files' service"));
 		g_print ("\n");
@@ -175,8 +176,6 @@ main (int argc, char **argv)
 
 	count = g_strv_length (uris);
 
-	/* TODO: Port to SPARQL */
-#if 0
 	if (count > 1 && metadata != NULL) {
 		gchar     **strv;
 		GPtrArray  *results;
diff --git a/src/tracker-utils/tracker-search.c b/src/tracker-utils/tracker-search.c
index b2943ed..2dacd71 100644
--- a/src/tracker-utils/tracker-search.c
+++ b/src/tracker-utils/tracker-search.c
@@ -98,7 +98,6 @@ int
 main (int argc, char **argv)
 {
 	TrackerClient	*client;
-	ServiceType	 type;
 	GOptionContext	*context;
 	GError		*error = NULL;
 	gchar		*search;
@@ -176,6 +175,8 @@ main (int argc, char **argv)
 		limit = 512;
 	}
 
+	/* TODO: Port to SPARQL */
+#if 0
 	if (!service) {
 		g_print ("%s\n",
 			 _("Defaulting to 'files' service"));
@@ -192,8 +193,6 @@ main (int argc, char **argv)
 
 	search = g_strjoinv (" ", terms);
 
-	/* TODO: Port to SPARQL */
-#if 0
 	if (detailed) {
 		array = tracker_search_text_detailed (client,
 						      time (NULL),
diff --git a/src/tracker-utils/tracker-tag.c b/src/tracker-utils/tracker-tag.c
index 0ba8df2..aaf8ec8 100644
--- a/src/tracker-utils/tracker-tag.c
+++ b/src/tracker-utils/tracker-tag.c
@@ -224,7 +224,6 @@ main (int argc, char **argv)
 		for (i = 0; files_resolved[i] != NULL; i++) {
 			if (rm_all) {
 				tracker_keywords_remove_all (client,
-							     SERVICE_FILES,
 							     files_resolved[i],
 							     &error);
 
@@ -243,7 +242,6 @@ main (int argc, char **argv)
 
 			if (tags_to_add) {
 				tracker_keywords_add (client,
-						      SERVICE_FILES,
 						      files_resolved[i],
 						      tags_to_add,
 						      &error);
@@ -263,7 +261,6 @@ main (int argc, char **argv)
 
 			if (tags_to_remove) {
 				tracker_keywords_remove (client,
-							 SERVICE_FILES,
 							 files_resolved[i],
 							 tags_to_remove,
 							 &error);
@@ -288,7 +285,6 @@ main (int argc, char **argv)
 		GPtrArray *array;
 
 		array = tracker_keywords_get_list (client,
-						   SERVICE_FILES,
 						   &error);
 
 		if (error) {
@@ -316,7 +312,6 @@ main (int argc, char **argv)
 			gchar **tags;
 
 			tags = tracker_keywords_get (client,
-						     SERVICE_FILES,
 						     files_resolved[i],
 						     &error);
 
@@ -347,7 +342,7 @@ main (int argc, char **argv)
 	}
 
 	if (search) {
-		gchar **results;
+		gchar **results = NULL;
 
 		search_resolved = g_new0 (gchar*, g_strv_length (search) + 1);
 
@@ -360,12 +355,14 @@ main (int argc, char **argv)
 
 		search_resolved[j] = NULL;
 
+		/* TODO
 		results = tracker_keywords_search (client, -1,
-						   SERVICE_FILES,
+						   SERVICE_RESOURCES,
 						   search_resolved,
 						   offset,
 						   limit,
 						   &error);
+		*/
 
 		if (error) {
 			error_str = g_strdup (_("Could not search tags"));
diff --git a/src/trackerd/Makefile.am b/src/trackerd/Makefile.am
index 62bb361..97ceed2 100644
--- a/src/trackerd/Makefile.am
+++ b/src/trackerd/Makefile.am
@@ -47,6 +47,8 @@ trackerd_SOURCES =							\
 	tracker-marshal-main.c						\
 	tracker-monitor.c						\
 	tracker-monitor.h						\
+	tracker-resources.c						\
+	tracker-resources.h						\
 	tracker-search.c						\
 	tracker-search.h						\
 	tracker-status.c						\
@@ -102,6 +104,7 @@ marshal_sources =                                         		\
 dbus_sources = 								\
 	tracker-backup-glue.h						\
 	tracker-daemon-glue.h						\
+	tracker-resources-glue.h					\
 	tracker-search-glue.h						\
 	tracker-indexer-client.h
 
diff --git a/src/trackerd/tracker-backup.c b/src/trackerd/tracker-backup.c
index c184ffd..aae97b0 100644
--- a/src/trackerd/tracker-backup.c
+++ b/src/trackerd/tracker-backup.c
@@ -64,7 +64,10 @@ tracker_backup_save (TrackerBackup          *object,
 				  path);
 
 	g_message ("Backing up metadata");
+	/* TODO: Port to SPARQL */
+#if 0
 	tracker_data_backup_save (path, &err);
+#endif
 
 	if (err) {
 		GError *actual_error = NULL;
diff --git a/src/trackerd/tracker-daemon.c b/src/trackerd/tracker-daemon.c
index 703a552..cf3038e 100644
--- a/src/trackerd/tracker-daemon.c
+++ b/src/trackerd/tracker-daemon.c
@@ -204,11 +204,7 @@ tracker_daemon_init (TrackerDaemon *object)
 {
 	TrackerDaemonPrivate *priv;
 	TrackerDBInterface   *iface;
-	TrackerDBResultSet   *result_set;
 	DBusGProxy           *proxy;
-	GHashTable           *values;
-	GHashTableIter        iter;
-	gpointer              key, value;
 
 	priv = TRACKER_DAEMON_GET_PRIVATE (object);
 
@@ -228,7 +224,7 @@ tracker_daemon_init (TrackerDaemon *object)
 				     object,
 				     NULL);
 
-	iface = tracker_db_manager_get_db_interface (TRACKER_DB_COMMON);
+	iface = tracker_db_manager_get_db_interface ();
 
 	/* Prepare cache */
 	priv->stats_cache = g_hash_table_new_full (g_str_hash,
@@ -236,23 +232,6 @@ tracker_daemon_init (TrackerDaemon *object)
 						   g_free, 
 						   NULL);
 
-	result_set = tracker_data_manager_exec_proc (iface, "GetServices", 0);
-	values = tracker_dbus_query_result_to_hash_table (result_set);
-
-	if (result_set) {
-		g_object_unref (result_set);
-	}
-
-	g_hash_table_iter_init (&iter, values);
-
-	while (g_hash_table_iter_next (&iter, &key, &value)) {
-		g_hash_table_replace (priv->stats_cache, 
-				      g_strdup (key), 
-				      GINT_TO_POINTER (0));
-	}
-
-	g_hash_table_destroy (values);
-
 	/* First time update */
 	stats_cache_update (object);
 
@@ -372,55 +351,38 @@ tracker_daemon_get_status (TrackerDaemon	  *object,
 	tracker_dbus_request_unblock_hooks ();
 }
 
+static TrackerDBResultSet *
+db_get_stats (void)
+{
+	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
+	TrackerDBResultSet *result_set;
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	/* FIXME Slow query, switch to SELECT COUNT(*) FROM each class to improve performance */
+	stmt = tracker_db_interface_create_statement (iface, "SELECT Uri, COUNT(*) FROM \"rdfs:Resource_rdf:type\" JOIN \"rdfs:Resource\" ON \"rdf:type\" = \"rdfs:Resource\".ID GROUP BY \"rdf:type\"");
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
+
+	return result_set;
+}
+
 static void
 stats_cache_update (TrackerDaemon *object)
 {
 	TrackerDaemonPrivate *priv;
 	TrackerDBResultSet   *result_set;
-	GPtrArray            *stats, *parent_stats;
 	GPtrArray            *values;
 	guint                 i;
-	const gchar          *services_to_fetch[3] = { 
-		TRACKER_DB_FOR_FILE_SERVICE, 
-		TRACKER_DB_FOR_EMAIL_SERVICE, 
-		NULL 
-	};
 
 	priv = TRACKER_DAEMON_GET_PRIVATE (object);
 
-	values = g_ptr_array_new ();
-
-	for (i = 0; services_to_fetch[i]; i++) {
-		TrackerDBInterface *iface;
-		gint                j;
+	result_set = db_get_stats ();
+	values = tracker_dbus_query_result_to_ptr_array (result_set);
 
-		iface = tracker_db_manager_get_db_interface_by_service (services_to_fetch[i]);
-
-		result_set = tracker_data_manager_exec_proc (iface, "GetStats", 0);
-		stats = tracker_dbus_query_result_to_ptr_array (result_set);
-
-		if (result_set) {
-			g_object_unref (result_set);
-		}
-
-		result_set = tracker_data_manager_exec_proc (iface, "GetStatsForParents", 0);
-		parent_stats = tracker_dbus_query_result_to_ptr_array (result_set);
-
-		if (result_set) {
-			g_object_unref (result_set);
-		}
-
-		/* Concatenate stats */
-		for (j = 0; j < stats->len; j++) {
-			g_ptr_array_add (values, g_ptr_array_index (stats, j));
-		}
-		
-		for (j = 0; j < parent_stats->len; j++) {
-			g_ptr_array_add (values, g_ptr_array_index (parent_stats, j));
-		}
-
-		g_ptr_array_free (parent_stats, TRUE);
-		g_ptr_array_free (stats, TRUE);
+	if (result_set) {
+		g_object_unref (result_set);
 	}
 
 	/* Update local cache */
@@ -741,56 +703,19 @@ tracker_daemon_signal_statistics (void)
 	GObject		     *daemon;
 	TrackerDaemonPrivate *priv;
 	TrackerDBResultSet   *result_set;
-	GPtrArray	     *stats, *parent_stats;
 	GPtrArray            *values;
 	gint                  i;
-	const gchar          *services_to_fetch[3] = {
-		TRACKER_DB_FOR_FILE_SERVICE, 
-		TRACKER_DB_FOR_EMAIL_SERVICE, 
-		NULL
-	};
 
 	daemon = tracker_dbus_get_object (TRACKER_TYPE_DAEMON);
 	priv = TRACKER_DAEMON_GET_PRIVATE (daemon);
 
-	values = g_ptr_array_new ();
-
 	g_message ("Requesting statistics from database for an accurate signal");
 
-	for (i = 0; services_to_fetch[i]; i++) {		
-		TrackerDBInterface *iface;
-		gint                j;
-
-		iface = tracker_db_manager_get_db_interface_by_service (services_to_fetch[i]);
+	result_set = db_get_stats ();
+	values = tracker_dbus_query_result_to_ptr_array (result_set);
 
-		/* GetStats has asc in its query. Therefore we don't have to
-		 * lookup the in a to compare in b, just compare index based.
-		 * Maybe we want to change this nonetheless later?
-		 */
-		result_set = tracker_data_manager_exec_proc (iface, "GetStats", 0);
-		stats = tracker_dbus_query_result_to_ptr_array (result_set);
-
-		if (result_set) {
-			g_object_unref (result_set);
-		}
-
-		result_set = tracker_data_manager_exec_proc (iface, "GetStatsForParents", 0);
-		parent_stats = tracker_dbus_query_result_to_ptr_array (result_set);
-
-		if (result_set) {
-			g_object_unref (result_set);
-		}
-		
-		for (j = 0; j < stats->len; j++) {
-			g_ptr_array_add (values, g_ptr_array_index (stats, j));
-		}
-
-		for (j = 0; j < parent_stats->len; j++) {
-			g_ptr_array_add (values, g_ptr_array_index (parent_stats, j));
-		}
-
-		g_ptr_array_free (parent_stats, TRUE);
-		g_ptr_array_free (stats, TRUE);
+	if (result_set) {
+		g_object_unref (result_set);
 	}
 
 	/* There are 3 situations here:
diff --git a/src/trackerd/tracker-dbus.c b/src/trackerd/tracker-dbus.c
index 764fc03..e85c169 100644
--- a/src/trackerd/tracker-dbus.c
+++ b/src/trackerd/tracker-dbus.c
@@ -33,6 +33,8 @@
 #include "tracker-dbus.h"
 #include "tracker-daemon.h"
 #include "tracker-daemon-glue.h"
+#include "tracker-resources.h"
+#include "tracker-resources-glue.h"
 #include "tracker-search.h"
 #include "tracker-search-glue.h"
 #include "tracker-backup.h"
@@ -254,16 +256,14 @@ tracker_dbus_shutdown (void)
 gboolean
 tracker_dbus_register_objects (TrackerConfig	*config,
 			       TrackerLanguage	*language,
-			       TrackerDBIndex	*file_index,
-			       TrackerDBIndex	*email_index,
+			       TrackerDBIndex	*resources_index,
 			       TrackerProcessor *processor)
 {
 	gpointer object;
 
 	g_return_val_if_fail (TRACKER_IS_CONFIG (config), FALSE);
 	g_return_val_if_fail (TRACKER_IS_LANGUAGE (language), FALSE);
-	g_return_val_if_fail (TRACKER_IS_DB_INDEX (file_index), FALSE);
-	g_return_val_if_fail (TRACKER_IS_DB_INDEX (email_index), FALSE);
+	g_return_val_if_fail (TRACKER_IS_DB_INDEX (resources_index), FALSE);
 
 	if (!connection || !gproxy) {
 		g_critical ("DBus support must be initialized before registering objects!");
@@ -284,8 +284,22 @@ tracker_dbus_register_objects (TrackerConfig	*config,
 			      TRACKER_DAEMON_PATH);
 	objects = g_slist_prepend (objects, object);
 
+	/* Add org.freedesktop.Tracker.Resources */
+	object = tracker_resources_new ();
+	if (!object) {
+		g_critical ("Could not create TrackerResources object to register");
+		return FALSE;
+	}
+
+	dbus_register_object (connection,
+			      gproxy,
+			      G_OBJECT (object),
+			      &dbus_glib_tracker_resources_object_info,
+			      TRACKER_RESOURCES_PATH);
+	objects = g_slist_prepend (objects, object);
+
 	/* Add org.freedesktop.Tracker.Search */
-	object = tracker_search_new (config, language, file_index, email_index);
+	object = tracker_search_new (config, language, resources_index);
 	if (!object) {
 		g_critical ("Could not create TrackerSearch object to register");
 		return FALSE;
@@ -312,7 +326,6 @@ tracker_dbus_register_objects (TrackerConfig	*config,
 			      TRACKER_BACKUP_PATH);
 	objects = g_slist_prepend (objects, object);
 
-
 	/* Reverse list since we added objects at the top each time */
 	objects = g_slist_reverse (objects);
 
diff --git a/src/trackerd/tracker-dbus.h b/src/trackerd/tracker-dbus.h
index 45ee45e..331fb28 100644
--- a/src/trackerd/tracker-dbus.h
+++ b/src/trackerd/tracker-dbus.h
@@ -41,8 +41,7 @@ gboolean    tracker_dbus_init                    (TrackerConfig    *config);
 void        tracker_dbus_shutdown                (void);
 gboolean    tracker_dbus_register_objects        (TrackerConfig    *config,
 						  TrackerLanguage  *language,
-						  TrackerDBIndex   *file_index,
-						  TrackerDBIndex   *email_index,
+						  TrackerDBIndex   *resources_index,
 						  TrackerProcessor *processor);
 GObject    *tracker_dbus_get_object              (GType             type);
 void        tracker_dbus_indexer_check_is_paused (void);
diff --git a/src/trackerd/tracker-main.c b/src/trackerd/tracker-main.c
index 2a2fbc7..b036481 100644
--- a/src/trackerd/tracker-main.c
+++ b/src/trackerd/tracker-main.c
@@ -617,10 +617,13 @@ shutdown_databases (void)
 
 	private = g_static_private_get (&private_key);
 
+	/* TODO port backup support */
+#if 0
 	/* If we are reindexing, save the user metadata  */
 	if (private->reindex_on_shutdown) {
 		tracker_data_backup_save (private->ttl_backup_file, NULL);
 	}
+#endif
 	/* Reset integrity status as threads have closed cleanly */
 	tracker_data_manager_set_db_option_int ("IntegrityCheck", 0);
 }
@@ -657,8 +660,7 @@ get_ttl_backup_filename (void)
 static void
 backup_user_metadata (TrackerConfig *config, TrackerLanguage *language)
 {
-	TrackerDBIndex		   *file_index;
-	TrackerDBIndex		   *email_index;
+	TrackerDBIndex		   *index;
 	gboolean                    is_first_time_index;
 
 	g_message ("Saving metadata in %s", get_ttl_backup_filename ());
@@ -666,33 +668,24 @@ backup_user_metadata (TrackerConfig *config, TrackerLanguage *language)
 	/*
 	 *  Init the DB stack to get the user metadata
 	 */
-	tracker_db_manager_init (0, &is_first_time_index, TRUE);
-
+	tracker_data_manager_init (config, language, 0, 0, NULL, &is_first_time_index);
+	
 	/*
 	 * If some database is missing or the dbs dont exists, we dont need
 	 * to backup anything.
 	 */
 	if (is_first_time_index) {
-		tracker_db_manager_shutdown ();
+		tracker_data_manager_shutdown ();
 		return;
 	}
-	
-	tracker_db_index_manager_init (0,
-				       tracker_config_get_min_bucket_count (config),
-				       tracker_config_get_max_bucket_count (config));
-	
-	file_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_FILE);
-	email_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_EMAIL);
-	
-	tracker_data_manager_init (config, language, file_index, email_index);
+
+	index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_RESOURCES);
 	
 	/* Actual save of the metadata */
 	tracker_data_backup_save (get_ttl_backup_filename (), NULL);
 	
 	/* Shutdown the DB stack */
 	tracker_data_manager_shutdown ();
-	tracker_db_index_manager_shutdown ();
-	tracker_db_manager_shutdown ();
 }
 
 /*
@@ -833,8 +826,7 @@ main (gint argc, gchar *argv[])
 	TrackerConfig		   *config;
 	TrackerLanguage		   *language;
 	TrackerHal		   *hal;
-	TrackerDBIndex		   *file_index;
-	TrackerDBIndex		   *email_index;
+	TrackerDBIndex		   *resources_index;
 	TrackerRunningLevel	    runtime_level;
 	TrackerDBManagerFlags	    flags = 0;
 	TrackerDBIndexManagerFlags  index_flags = 0;
@@ -981,7 +973,8 @@ main (gint argc, gchar *argv[])
 	index_flags |= TRACKER_DB_INDEX_MANAGER_READONLY;
 
 	if (force_reindex) {
-		backup_user_metadata (config, language);
+		/* TODO port backup support
+		backup_user_metadata (config, language); */
 
 		flags |= TRACKER_DB_MANAGER_FORCE_REINDEX;
 		index_flags |= TRACKER_DB_INDEX_MANAGER_FORCE_REINDEX;
@@ -991,14 +984,9 @@ main (gint argc, gchar *argv[])
 		flags |= TRACKER_DB_MANAGER_LOW_MEMORY_MODE;
 	}
 
-	tracker_db_manager_init (flags, &is_first_time_index, TRUE);
-	tracker_status_set_is_first_time_index (is_first_time_index);
+	tracker_data_manager_init (config, language, flags, index_flags, NULL, &is_first_time_index);
 
-	if (!tracker_db_index_manager_init (index_flags,
-					    tracker_config_get_min_bucket_count (config),
-					    tracker_config_get_max_bucket_count (config))) {
-		return EXIT_FAILURE;
-	}
+	tracker_status_set_is_first_time_index (is_first_time_index);
 
 	/*
 	 * Check instances running
@@ -1024,16 +1012,13 @@ main (gint argc, gchar *argv[])
 		return EXIT_FAILURE;
 	}
 
-	file_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_FILE);
-	email_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_EMAIL);
+	resources_index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_RESOURCES);
 
-	if (!TRACKER_IS_DB_INDEX (file_index) ||
-	    !TRACKER_IS_DB_INDEX (email_index)) {
-		g_critical ("Could not create indexer for all indexes (file, email)");
+	if (!TRACKER_IS_DB_INDEX (resources_index)) {
+		g_critical ("Could not create indexer for resource index");
 		return EXIT_FAILURE;
 	}
 
-	tracker_data_manager_init (config, language, file_index, email_index);
 	tracker_volume_cleanup_init ();
 
 #ifdef HAVE_HAL
@@ -1050,8 +1035,7 @@ main (gint argc, gchar *argv[])
 	/* Make Tracker available for introspection */
 	if (!tracker_dbus_register_objects (config,
 					    language,
-					    file_index,
-					    email_index,
+					    resources_index,
 					    private->processor)) {
 		return EXIT_FAILURE;
 	}
@@ -1123,8 +1107,6 @@ main (gint argc, gchar *argv[])
 
 	tracker_volume_cleanup_shutdown ();
 	tracker_dbus_shutdown ();
-	tracker_db_manager_shutdown ();
-	tracker_db_index_manager_shutdown ();
 	tracker_data_manager_shutdown ();
 	tracker_module_config_shutdown ();
 	tracker_nfs_lock_shutdown ();
diff --git a/src/trackerd/tracker-marshal.list b/src/trackerd/tracker-marshal.list
index f5c00a5..a6a9254 100644
--- a/src/trackerd/tracker-marshal.list
+++ b/src/trackerd/tracker-marshal.list
@@ -1,19 +1,13 @@
 VOID:STRING,UINT,UINT,UINT,UINT
 VOID:STRING,STRING,INT,INT,INT,DOUBLE
-VOID:STRING,STRING,STRING
 VOID:STRING,BOOLEAN
+VOID:STRING,STRING
 VOID:STRING,BOOLEAN,BOOLEAN,BOOLEAN,BOOLEAN,BOOLEAN,BOOLEAN
 VOID:STRING,OBJECT,BOOLEAN
 VOID:STRING,OBJECT,OBJECT,BOOLEAN,BOOLEAN
 VOID:STRING,OBJECT
 VOID:BOXED
 
-# XESAM signals -- HitsRemoved, HitsModified
-VOID:STRING,BOXED
-
-# XESAM signals -- HitsAdded
-VOID:STRING,UINT
-
 # Indexer signals
 VOID:DOUBLE,UINT,UINT,BOOL
 VOID:DOUBLE,STRING,UINT,UINT,UINT
diff --git a/src/trackerd/tracker-processor.c b/src/trackerd/tracker-processor.c
index c80941c..a07321c 100644
--- a/src/trackerd/tracker-processor.c
+++ b/src/trackerd/tracker-processor.c
@@ -1123,10 +1123,7 @@ indexer_status_cb (DBusGProxy  *proxy,
 	 * module_name->index type so we don't do this for both
 	 * every time:
 	 */
-	index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_FILE);
-	tracker_db_index_set_reload (index, TRUE);
-
-	index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_EMAIL);
+	index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_RESOURCES);
 	tracker_db_index_set_reload (index, TRUE);
 
 	/* Message to the console about state */
@@ -1182,10 +1179,7 @@ indexer_finished_cb (DBusGProxy  *proxy,
 	 * module_name->index type so we don't do this for both
 	 * every time:
 	 */
-	index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_FILE);
-	tracker_db_index_set_reload (index, TRUE);
-
-	index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_EMAIL);
+	index = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_RESOURCES);
 	tracker_db_index_set_reload (index, TRUE);
 
 	/* Message to the console about state */
diff --git a/src/trackerd/tracker-resources.c b/src/trackerd/tracker-resources.c
new file mode 100644
index 0000000..c066564
--- /dev/null
+++ b/src/trackerd/tracker-resources.c
@@ -0,0 +1,183 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
+ * Copyright (C) 2008, Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <libtracker-common/tracker-dbus.h>
+#include <libtracker-common/tracker-log.h>
+#include <libtracker-common/tracker-utils.h>
+#include <libtracker-common/tracker-type-utils.h>
+
+#include <libtracker-db/tracker-db-dbus.h>
+
+#include <libtracker-data/tracker-data-manager.h>
+#include <libtracker-data/tracker-data-query.h>
+#include <libtracker-data/tracker-data-search.h>
+
+#include "tracker-indexer-client.h"
+#include "tracker-dbus.h"
+#include "tracker-marshal.h"
+#include "tracker-resources.h"
+
+G_DEFINE_TYPE(TrackerResources, tracker_resources, G_TYPE_OBJECT)
+
+static void
+tracker_resources_class_init (TrackerResourcesClass *klass)
+{
+}
+
+static void
+tracker_resources_init (TrackerResources *object)
+{
+}
+
+TrackerResources *
+tracker_resources_new (void)
+{
+	return g_object_new (TRACKER_TYPE_RESOURCES, NULL);
+}
+
+/*
+ * Functions
+ */
+
+void
+tracker_resources_insert (TrackerResources	     *self,
+			  const gchar                *subject,
+			  const gchar                *predicate,
+			  const gchar                *object,
+			  DBusGMethodInvocation      *context,
+			  GError		    **error)
+{
+	guint		    request_id;
+	GError		   *actual_error = NULL;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (subject != NULL, context);
+	tracker_dbus_async_return_if_fail (predicate != NULL, context);
+	tracker_dbus_async_return_if_fail (object != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to insert statement: "
+				  "'%s' '%s' '%s'",
+				  subject, predicate, object);
+
+	org_freedesktop_Tracker_Indexer_insert_statement (tracker_dbus_indexer_get_proxy (),
+							  subject,
+							  predicate,
+							  object,
+							  &actual_error);
+	if (actual_error) {
+		tracker_dbus_request_failed (request_id, &actual_error, NULL);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	dbus_g_method_return (context);
+
+	tracker_dbus_request_success (request_id);
+}
+
+void
+tracker_resources_delete (TrackerResources	     *self,
+			  const gchar                *subject,
+			  const gchar                *predicate,
+			  const gchar                *object,
+			  DBusGMethodInvocation      *context,
+			  GError		    **error)
+{
+	guint		    request_id;
+	GError		   *actual_error = NULL;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (subject != NULL, context);
+	tracker_dbus_async_return_if_fail (predicate != NULL, context);
+	tracker_dbus_async_return_if_fail (object != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to delete statement: "
+				  "'%s' '%s' '%s'",
+				  subject, predicate, object);
+
+	org_freedesktop_Tracker_Indexer_delete_statement (tracker_dbus_indexer_get_proxy (),
+							  subject,
+							  predicate,
+							  object,
+							  &actual_error);
+	if (actual_error) {
+		tracker_dbus_request_failed (request_id, &actual_error, NULL);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	dbus_g_method_return (context);
+
+	tracker_dbus_request_success (request_id);
+}
+
+void
+tracker_resources_load (TrackerResources	 *object,
+			const gchar		 *uri,
+			DBusGMethodInvocation	 *context,
+			GError			**error)
+{
+	guint		    request_id;
+	GFile  *file;
+	gchar  *path;
+	GError		   *actual_error = NULL;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (uri != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to load turtle file "
+				  "'%s'",
+				  uri);
+
+	file = g_file_new_for_uri (uri);
+	path = g_file_get_path (file);
+
+	org_freedesktop_Tracker_Indexer_turtle_add (tracker_dbus_indexer_get_proxy (),
+						    path,
+						    &actual_error);
+
+	g_free (path);
+	g_object_unref (file);
+
+	if (actual_error) {
+		tracker_dbus_request_failed (request_id, &actual_error, NULL);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	dbus_g_method_return (context);
+
+	tracker_dbus_request_success (request_id);
+}
+
diff --git a/src/trackerd/tracker-resources.h b/src/trackerd/tracker-resources.h
new file mode 100644
index 0000000..61d0316
--- /dev/null
+++ b/src/trackerd/tracker-resources.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
+ * Copyright (C) 2008, Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __TRACKERD_RESOURCES_H__
+#define __TRACKERD_RESOURCES_H__
+
+#include <glib-object.h>
+
+#include <libtracker-db/tracker-db-index.h>
+
+#define TRACKER_RESOURCES_SERVICE	 "org.freedesktop.Tracker"
+#define TRACKER_RESOURCES_PATH		 "/org/freedesktop/Tracker/Resources"
+#define TRACKER_RESOURCES_INTERFACE	 "org.freedesktop.Tracker.Resources"
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_RESOURCES		 (tracker_resources_get_type ())
+#define TRACKER_RESOURCES(object)	 (G_TYPE_CHECK_INSTANCE_CAST ((object), TRACKER_TYPE_RESOURCES, TrackerResources))
+#define TRACKER_RESOURCES_CLASS(klass)	 (G_TYPE_CHECK_CLASS_CAST ((klass), TRACKER_TYPE_RESOURCES, TrackerResourcesClass))
+#define TRACKER_IS_RESOURCES(object)	 (G_TYPE_CHECK_INSTANCE_TYPE ((object), TRACKER_TYPE_RESOURCES))
+#define TRACKER_IS_RESOURCES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TRACKER_TYPE_RESOURCES))
+#define TRACKER_RESOURCES_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TRACKER_TYPE_RESOURCES, TrackerResourcesClass))
+
+typedef struct TrackerResources	    TrackerResources;
+typedef struct TrackerResourcesClass TrackerResourcesClass;
+
+struct TrackerResources {
+	GObject parent;
+};
+
+struct TrackerResourcesClass {
+	GObjectClass parent;
+};
+
+GType		 tracker_resources_get_type		 (void);
+TrackerResources *tracker_resources_new			 (void);
+void		 tracker_resources_insert		 (TrackerResources	 *self,
+							  const gchar		 *subject,
+							  const gchar		 *predicate,
+							  const gchar		 *object,
+							  DBusGMethodInvocation  *context,
+							  GError		**error);
+void		 tracker_resources_delete		 (TrackerResources	 *self,
+							  const gchar		 *subject,
+							  const gchar		 *predicate,
+							  const gchar		 *object,
+							  DBusGMethodInvocation  *context,
+							  GError		**error);
+void		 tracker_resources_load			 (TrackerResources	 *object,
+							  const gchar		 *uri,
+							  DBusGMethodInvocation  *context,
+							  GError		**error);
+
+G_END_DECLS
+
+#endif /* __TRACKERD_RESOURCES_H__ */
diff --git a/src/trackerd/tracker-search.c b/src/trackerd/tracker-search.c
index 1593dfb..448a82d 100644
--- a/src/trackerd/tracker-search.c
+++ b/src/trackerd/tracker-search.c
@@ -30,6 +30,7 @@
 #include <libtracker-common/tracker-ontology.h>
 #include <libtracker-common/tracker-parser.h>
 #include <libtracker-common/tracker-utils.h>
+#include <libtracker-common/tracker-type-utils.h>
 
 #include <libtracker-db/tracker-db-dbus.h>
 #include <libtracker-db/tracker-db-index.h>
@@ -51,14 +52,14 @@
 typedef struct {
 	TrackerConfig	   *config;
 	TrackerLanguage    *language;
-	TrackerDBIndex	   *file_index;
-	TrackerDBIndex	   *email_index;
+	TrackerDBIndex	   *resources_index;
 } TrackerSearchPrivate;
 
 static void tracker_search_finalize (GObject *object);
 
 G_DEFINE_TYPE(TrackerSearch, tracker_search, G_TYPE_OBJECT)
 
+
 static void
 tracker_search_class_init (TrackerSearchClass *klass)
 {
@@ -83,8 +84,7 @@ tracker_search_finalize (GObject *object)
 
 	priv = TRACKER_SEARCH_GET_PRIVATE (object);
 
-	g_object_unref (priv->email_index);
-	g_object_unref (priv->file_index);
+	g_object_unref (priv->resources_index);
 	g_object_unref (priv->language);
 	g_object_unref (priv->config);
 
@@ -94,16 +94,14 @@ tracker_search_finalize (GObject *object)
 TrackerSearch *
 tracker_search_new (TrackerConfig   *config,
 		    TrackerLanguage *language,
-		    TrackerDBIndex  *file_index,
-		    TrackerDBIndex  *email_index)
+		    TrackerDBIndex  *resources_index)
 {
 	TrackerSearch	     *object;
 	TrackerSearchPrivate *priv;
 
 	g_return_val_if_fail (TRACKER_IS_CONFIG (config), NULL);
 	g_return_val_if_fail (TRACKER_IS_LANGUAGE (language), NULL);
-	g_return_val_if_fail (TRACKER_IS_DB_INDEX (file_index), NULL);
-	g_return_val_if_fail (TRACKER_IS_DB_INDEX (email_index), NULL);
+	g_return_val_if_fail (TRACKER_IS_DB_INDEX (resources_index), NULL);
 
 	object = g_object_new (TRACKER_TYPE_SEARCH, NULL);
 
@@ -111,15 +109,12 @@ tracker_search_new (TrackerConfig   *config,
 
 	priv->config = g_object_ref (config);
 	priv->language = g_object_ref (language);
-	priv->file_index = g_object_ref (file_index);
-	priv->email_index = g_object_ref (email_index);
+	priv->resources_index = g_object_ref (resources_index);
 
 	return object;
 }
 
-/*
- * Functions
- */
+
 static const gchar *
 search_utf8_p_from_offset_skipping_decomp (const gchar *str,
 					   gint		offset)
@@ -400,8 +395,7 @@ search_get_snippet (const gchar  *text,
 
 void
 tracker_search_get_snippet (TrackerSearch	   *object,
-			    const gchar		   *service,
-			    const gchar		   *id,
+			    const gchar		   *uri,
 			    const gchar		   *search_text,
 			    DBusGMethodInvocation  *context,
 			    GError		  **error)
@@ -411,31 +405,18 @@ tracker_search_get_snippet (TrackerSearch	   *object,
 	GError		   *actual_error = NULL;
 	guint		    request_id;
 	gchar		   *snippet = NULL;
-	gchar		   *service_id;
+	guint32		    resource_id;
 
 	request_id = tracker_dbus_get_next_request_id ();
 
-	tracker_dbus_async_return_if_fail (service != NULL, context);
-	tracker_dbus_async_return_if_fail (id != NULL, context);
+	tracker_dbus_async_return_if_fail (uri != NULL, context);
 	tracker_dbus_async_return_if_fail (search_text != NULL, context);
 
 	tracker_dbus_request_new (request_id,
 				  "DBus request to get snippet, "
-				  "service:'%s', search text:'%s', id:'%s'",
-				  service,
+				  "search text:'%s', id:'%s'",
 				  search_text,
-				  id);
-
-	if (!tracker_ontology_service_is_valid (service)) {
-		g_set_error (&actual_error,
-			     TRACKER_DBUS_ERROR,
-			     0,
-			     "Service '%s' is invalid or has not been implemented yet",
-			     service);
-		dbus_g_method_return_error (context, actual_error);
-		g_error_free (actual_error);
-		return;
-	}
+				  uri);
 
 	if (tracker_is_empty_string (search_text)) {
 		g_set_error (&actual_error,
@@ -447,25 +428,26 @@ tracker_search_get_snippet (TrackerSearch	   *object,
 		return;
 	}
 
-	iface = tracker_db_manager_get_db_interface_by_service (service);
+	iface = tracker_db_manager_get_db_interface ();
 
-	service_id = tracker_data_query_file_id_as_string (service, id);
-	if (!service_id) {
+	resource_id = tracker_data_query_resource_id (uri);
+	if (!resource_id) {
 		g_set_error (&actual_error,
 			     TRACKER_DBUS_ERROR,
 			     0,
 			     "Service URI '%s' not found",
-			     id);
+			     uri);
 		dbus_g_method_return_error (context, actual_error);
 		g_error_free (actual_error);
 		return;
 	}
 
+	/* TODO: Port to SPARQL */
+#if 0
 	result_set = tracker_data_manager_exec_proc (iface,
 					   "GetAllContents",
-					   service_id,
+					   tracker_guint_to_string (resource_id),
 					   NULL);
-	g_free (service_id);
 
 	if (result_set) {
 		TrackerSearchPrivate  *priv;
@@ -488,6 +470,7 @@ tracker_search_get_snippet (TrackerSearch	   *object,
 		g_free (text);
 		g_object_unref (result_set);
 	}
+#endif
 
 	/* Sanity check snippet, using NULL will crash */
 	if (!snippet || !g_utf8_validate (snippet, -1, NULL) ) {
@@ -525,16 +508,9 @@ tracker_search_suggest (TrackerSearch	       *object,
 
 	priv = TRACKER_SEARCH_GET_PRIVATE (object);
 
-	/* First we try the file index */
-	value = tracker_db_index_get_suggestion (priv->file_index,
+	value = tracker_db_index_get_suggestion (priv->resources_index,
 						 search_text,
 						 max_dist);
-	if (!value) {
-		/* Second we try the email index */
-		value = tracker_db_index_get_suggestion (priv->email_index,
-							 search_text,
-							 max_dist);
-	}
 
 	if (!value) {
 		g_set_error (&actual_error,
diff --git a/src/trackerd/tracker-search.h b/src/trackerd/tracker-search.h
index 10a6f21..911efb3 100644
--- a/src/trackerd/tracker-search.h
+++ b/src/trackerd/tracker-search.h
@@ -55,10 +55,8 @@ struct TrackerSearchClass {
 GType	       tracker_search_get_type		(void);
 TrackerSearch *tracker_search_new		(TrackerConfig		*config,
 						 TrackerLanguage	*language,
-						 TrackerDBIndex		*file_index,
-						 TrackerDBIndex		*email_index);
+						 TrackerDBIndex		*resources_index);
 void	       tracker_search_get_snippet	(TrackerSearch		*object,
-						 const gchar		*service,
 						 const gchar		*id,
 						 const gchar		*search_text,
 						 DBusGMethodInvocation	*context,
diff --git a/src/trackerd/tracker-volume-cleanup.c b/src/trackerd/tracker-volume-cleanup.c
index e387267..79230b1 100644
--- a/src/trackerd/tracker-volume-cleanup.c
+++ b/src/trackerd/tracker-volume-cleanup.c
@@ -24,9 +24,12 @@
 
 #include <gio/gio.h>
 
+#include <libtracker-common/tracker-thumbnailer.h>
+#include <libtracker-common/tracker-utils.h>
+#include <libtracker-common/tracker-type-utils.h>
 #include <libtracker-db/tracker-db-manager.h>
 #include <libtracker-data/tracker-data-update.h>
-#include <libtracker-common/tracker-thumbnailer.h>
+#include <libtracker-data/tracker-data-query.h>
 
 #include "tracker-volume-cleanup.h"
 
@@ -34,6 +37,7 @@
  * sessions).
  */
 #define SECONDS_PER_DAY (60 * 60 * 24)
+#define THREE_DAYS_OF_SECONDS (SECONDS_PER_DAY * 3)
 
 typedef struct {
 	guint timeout_id;
@@ -60,56 +64,58 @@ check_for_volumes_to_cleanup (gpointer user_data)
 {
 	TrackerDBInterface *iface;
 	TrackerDBResultSet *result_set;
+	gchar *query;
+	time_t three_days_ago;
+	gchar *three_days_ago_as_string;
+
+	three_days_ago = (time (NULL) - THREE_DAYS_OF_SECONDS);
+	three_days_ago_as_string = tracker_date_to_string (three_days_ago);
 
 	g_message ("Checking for stale volumes in the database...");
 
-	iface = tracker_db_manager_get_db_interface (TRACKER_DB_COMMON);
+	iface = tracker_db_manager_get_db_interface ();
+
+	query = g_strdup_printf ("SELECT ?o ?m WHERE { "
+				   "?o a tracker:Volume ; "
+				   "tracker:mountPoint ?m ; "
+				   "tracker:unmountDate ?z ; "
+				   "tracker:isMounted false . "
+				 "FILTER (?z < \"%s\") }",
+				 three_days_ago_as_string);
+
+	result_set = tracker_data_query_sparql (query, NULL);
 
-	/* The stored statements of volume management have the "every
-	 * one that is older than three days since their last unmount
-	 * time" logic embedded in the SQL statements. Take a look at
-	 * sqlite-stored-procs.sql.
-	 */
-	result_set = 
-		tracker_db_interface_execute_procedure (iface, NULL,
-							"GetVolumesToClean",
-							NULL);
-	
 	if (result_set) {
 		gboolean is_valid = TRUE;
 
 		while (is_valid) {
 			GValue       value = { 0, };
-			const gchar *mount_point_path;
-			gint         volume_id;
-
-			_tracker_db_result_set_get_value (result_set, 0, &value);
+			const gchar *mount_point_uri;
+			const gchar *volume_uri;
 
-			mount_point_path = g_value_get_string (&value);
+			_tracker_db_result_set_get_value (result_set, 1, &value);
 
-			/* Add cleanup items here */
-			if (mount_point_path) {
-				GFile *file;
-				gchar *mount_point_uri;
+			mount_point_uri = g_value_get_string (&value);
 
-				file = g_file_new_for_path (mount_point_path);
-				mount_point_uri = g_file_get_uri (file);
+			/* mount_point_uri is indeed different than volume_uri,
+			 * volume_uri is the datasource URN built using the UDI,
+			 * mount_point_uri is like <file:///media/USBStick> */
 
+			if (mount_point_uri) {
 				g_message ("  Cleaning up volumes with mount point:'%s'", 
 					   mount_point_uri);
-				tracker_thumbnailer_cleanup (mount_point_uri);
 
-				g_free (mount_point_uri);
-				g_object_unref (file);
+				/* Add cleanup items here */
+				tracker_thumbnailer_cleanup (mount_point_uri);
 			}
 
 			g_value_unset (&value);
 
 			/* Reset volume date */
-			_tracker_db_result_set_get_value (result_set, 1, &value);
+			_tracker_db_result_set_get_value (result_set, 0, &value);
 
-			volume_id = g_value_get_int (&value); 
-			tracker_data_update_reset_volume (volume_id);
+			volume_uri = g_value_get_string (&value); 
+			tracker_data_update_reset_volume (volume_uri);
 
 			g_value_unset (&value);
 
@@ -121,6 +127,9 @@ check_for_volumes_to_cleanup (gpointer user_data)
 		g_message ("  No volumes to clean up");
 	}
 
+	g_free (three_days_ago_as_string);
+	g_free (query);
+
 	return TRUE;
 }
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c0118ee..72de412 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,6 +4,5 @@ SUBDIRS = 			\
 	common 			\
 	libtracker-common	\
 	libtracker-db 		\
-	scripts 		\
 	tracker-indexer		\
 	tracker-extract
diff --git a/tests/libtracker-common/Makefile.am b/tests/libtracker-common/Makefile.am
index 0c9830f..44aa4c8 100644
--- a/tests/libtracker-common/Makefile.am
+++ b/tests/libtracker-common/Makefile.am
@@ -15,7 +15,6 @@ noinst_PROGRAMS = $(TEST_PROGS)
 #
 
 TEST_PROGS += 								\
-	tracker-ontology 						\
 	tracker-dbus 							\
 	tracker-type-utils 						\
 	tracker-file-utils
@@ -33,17 +32,6 @@ INCLUDES = 								\
 	$(PANGO_CFLAGS)							\
 	$(DBUS_CFLAGS)
 
-tracker_ontology_SOURCES = 						\
-	tracker-ontology-test.c 
-
-tracker_ontology_LDADD =						\
-	$(top_builddir)/src/libtracker-common/libtracker-common.la 	\
-	$(top_builddir)/tests/common/libtracker-testcommon.la 		\
-	$(GMODULE_LIBS)							\
-	$(GCOV_LIBS)							\
-	$(GTHREAD_LIBS)							\
-	$(GLIB2_LIBS)							
-
 tracker_dbus_SOURCES = 							\
 	tracker-dbus-test.c
 
diff --git a/tests/libtracker-common/tracker-dbus-test.c b/tests/libtracker-common/tracker-dbus-test.c
index f8589bc..f66592f 100644
--- a/tests/libtracker-common/tracker-dbus-test.c
+++ b/tests/libtracker-common/tracker-dbus-test.c
@@ -171,10 +171,12 @@ main (int argc, char **argv) {
 	g_thread_init (NULL);
 	g_test_init (&argc, &argv, NULL);
 
+	/* disabled non-UTF-8 tests to not break test report generation */
+
 	g_test_add_func ("/libtracker-common/tracker-dbus/slist_to_strv_ok", test_slist_to_strv);
-	g_test_add_func ("/libtracker-common/tracker-dbus/slist_to_strv_nonutf8", test_slist_to_strv_nonutf8);
+	/* g_test_add_func ("/libtracker-common/tracker-dbus/slist_to_strv_nonutf8", test_slist_to_strv_nonutf8); */
 	g_test_add_func ("/libtracker-common/tracker-dbus/async_queue_to_strv_ok", test_async_queue_to_strv);
-	g_test_add_func ("/libtracker-common/tracker-dbus/async_queue_to_strv_nonutf8", test_async_queue_to_strv_nonutf8);
+	/* g_test_add_func ("/libtracker-common/tracker-dbus/async_queue_to_strv_nonutf8", test_async_queue_to_strv_nonutf8); */
 	g_test_add_func ("/libtracker-common/tracker-dbus/free_ptr_array", test_results_ptr_array_free);
 	g_test_add_func ("/libtracker-common/tracker-dbus/dbus_request_failed", test_dbus_request_failed);
 
diff --git a/tests/libtracker-common/tracker-field-test.c b/tests/libtracker-common/tracker-field-test.c
index a533e37..cfc37d4 100644
--- a/tests/libtracker-common/tracker-field-test.c
+++ b/tests/libtracker-common/tracker-field-test.c
@@ -1,5 +1,5 @@
 #include <glib.h>
-#include <libtracker-common/tracker-property.h>
+#include <libtracker-common/tracker-field.h>
 #include <tracker-test-helpers.h>
 
 static void
@@ -44,7 +44,7 @@ test_type_to_string ()
 	result = tracker_property_type_to_string (type);
 	g_assert (tracker_test_helpers_cmpstr_equal (result, "struct"));
 
-	type =	TRACKER_PROPERTY_TYPE_LINK;
+	type =	TRACKER_PROPERTY_TYPE_RESOURCE;
 	result = tracker_property_type_to_string (type);
 	g_assert (tracker_test_helpers_cmpstr_equal (result, "link"));
 
diff --git a/tests/libtracker-common/tracker-file-utils-test.c b/tests/libtracker-common/tracker-file-utils-test.c
index 02057d0..cb7f8d8 100644
--- a/tests/libtracker-common/tracker-file-utils-test.c
+++ b/tests/libtracker-common/tracker-file-utils-test.c
@@ -171,7 +171,7 @@ test_file_get_mime_type (void)
 	dir = g_file_new_for_path (dir_name);
 	g_file_make_directory (dir, NULL, NULL);
 
-	result = tracker_file_get_mime_type (dir_name);
+	result = tracker_file_get_mime_type (dir);
 
 	g_assert (tracker_test_helpers_cmpstr_equal (result, "inode/directory"));
 
@@ -181,55 +181,6 @@ test_file_get_mime_type (void)
 	g_free (dir_name);
 }
 
-static void
-test_file_get_path_and_name ()
-{
-
-	gchar *name = NULL;
-	gchar *path = NULL;
-
-	tracker_file_get_path_and_name ("/home/ivan/test/file.txt",
-					&path,
-					&name);
-
-	g_assert_cmpint (g_strcmp0 (name, "file.txt"), ==, 0);
-	g_assert_cmpint (g_strcmp0 (path, "/home/ivan/test"), ==, 0);
-
-	g_free (name);
-	g_free (path);
-	name = NULL;
-	path = NULL;
-
-	tracker_file_get_path_and_name ("/home/ivan//test/file.txt",
-					&path,
-					&name);
-
-	g_assert_cmpint (g_strcmp0 (name, "file.txt"), ==, 0);
-	g_assert_cmpint (g_strcmp0 (path, "/home/ivan/test"), ==, 0);
-
-	g_free (name);
-	g_free (path);
-	name = NULL;
-	path = NULL;
-/*
- *	TODO: Fix this case
- *
-	tracker_file_get_path_and_name ("file:///home/ivan//test/file.txt",
-					&path,
-					&name);
-
-	g_assert_cmpint (g_strcmp0 (name, "file.txt"), ==, 0);
-	g_print ("%s\n", path);
-	g_assert_cmpint (g_strcmp0 (path, "file:///home/ivan/test"), ==, 0);
-
-	g_free (name);
-	g_free (path);
-	name = NULL;
-	path = NULL;
-*/
-
-}
-
 int
 main (int argc, char **argv)
 {
@@ -248,9 +199,6 @@ main (int argc, char **argv)
 	g_test_add_func ("/tracker/libtracker-common/tracker-file-utils/file_get_mime_type",
 			 test_file_get_mime_type);
 
-	g_test_add_func ("/libtracker_common/tracker-file-utils/file_get_path_and_name",
-			 test_file_get_path_and_name);
-
 	result = g_test_run ();
 
 	return result;
diff --git a/tests/libtracker-common/tracker-ontology-test.c b/tests/libtracker-common/tracker-ontology-test.c
deleted file mode 100644
index dea1c15..0000000
--- a/tests/libtracker-common/tracker-ontology-test.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/* -*- 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 <libtracker-common/tracker-class.h>
-#include <libtracker-common/tracker-property.h>
-#include <libtracker-common/tracker-ontology.h>
-
-#include <tracker-test-helpers.h>
-
-typedef struct {
-	TrackerClass *service;
-	TrackerClass *parent_service;
-} ExpectedResults;
-
-static ExpectedResults *expected_results = NULL;
-
-static gboolean
-test_cmp_service_equals (TrackerClass *one,
-			 TrackerClass *two)
-{
-	if (one && !two) {
-		return FALSE;
-	}
-
-	if (!one && two) {
-		return FALSE;
-	}
-
-	if (!one && one == two) {
-		return TRUE;
-	}
-
-	return 
-		tracker_class_get_id (one) == tracker_class_get_id (two) &&
-		tracker_test_helpers_cmpstr_equal (tracker_class_get_name (one),
-						   tracker_class_get_name (two)) &&
-		tracker_test_helpers_cmpstr_equal (tracker_class_get_parent (one),
-						   tracker_class_get_parent (two)) &&
-		tracker_class_get_db_type (one) == tracker_class_get_db_type (two) &&
-		tracker_class_get_embedded (one) == tracker_class_get_embedded (two);
-}
-
-static gboolean
-element_in_list (GSList *list, gchar *element)
-{
-	return g_slist_find_custom (list, element, (GCompareFunc) strcmp) != NULL;
-}
-
-static GSList *
-array_to_list (char **array)
-{
-	GSList	*list = NULL;
-	int	i;
-
-	for (i = 0; array[i] != NULL; i++) {
-		list = g_slist_prepend (list, g_strdup (array[i]));
-	}
-
-	return list;
-}
-
-static TrackerProperty *
-create_field_definition (const gchar *id,
-			 const gchar *name,
-			 TrackerPropertyType data_type,
-			 const gchar *field_name,
-			 gboolean multiple_values,
-			 GSList *child_ids)
-{
-	TrackerProperty *field;
-
-	field = tracker_property_new ();
-
-	tracker_property_set_id (field, id);
-	tracker_property_set_name (field, name);
-	tracker_property_set_data_type (field, data_type);
-	tracker_property_set_field_name (field, field_name);
-	tracker_property_set_multiple_values (field, multiple_values);
-	tracker_property_set_child_ids (field, child_ids);
-
-	return field;
-}
-
-static TrackerClass *
-create_service_definition (gint		id,
-			   const gchar *name,
-			   const gchar *parent,
-			   const gchar *prefix,
-			   gboolean	embedded)
-{
-	TrackerClass *service;
-
-	/* array_to_list use prepend, so use reverse order here  */
-	gchar *key_metadata [] = {
-		"Key:Metadata2",
-		"Key:MetaData1",
-		NULL
-	};
-
-	service = tracker_class_new ();
-	tracker_class_set_id (service, id);
-	tracker_class_set_name (service, name);
-	tracker_class_set_parent (service, parent);
-	tracker_class_set_property_prefix (service, prefix);
-	tracker_class_set_db_type (service, TRACKER_DB_TYPE_CONTENT);
-	tracker_class_set_enabled (service, FALSE);
-	tracker_class_set_embedded (service, embedded);
-	tracker_class_set_has_thumbs (service, TRUE);
-	tracker_class_set_has_full_text (service, TRUE);
-	tracker_class_set_has_metadata (service, FALSE);
-	tracker_class_set_key_metadata (service, array_to_list (key_metadata));
-
-	return service;
-}
-
-static void
-tracker_services_general_setup (void)
-{
-	TrackerClass *service, *parent_service, *other_service;
-	TrackerClass *conv_service, *gaim_service, *gossip_service, *new_gaim_service;
-	TrackerProperty *field_title;
-	GSList *mimes, *mime_prefixes;
-	gchar *m[] = {"application/rtf", "text/joke", "test/1", NULL};
-	gchar *mp[] = {"images/", "video/", "other.mimes.", NULL};
-
-	service = create_service_definition (0, "Test service", "Parent service", NULL, TRUE);
-	parent_service = create_service_definition (1, "Parent service", NULL, NULL, FALSE);
-	other_service = create_service_definition (2, "Applications", NULL, "App", FALSE);
-	conv_service = create_service_definition (3, "Conversations", NULL, NULL, FALSE);
-	gaim_service = create_service_definition (4, "GaimConversations", "Conversations", NULL, FALSE);
-	gossip_service = create_service_definition (5, "GossipConversations", "Conversations", NULL, FALSE);
-	new_gaim_service = create_service_definition (6, "NewGaimConversations", "GaimConversations", NULL, FALSE);
-
-	field_title = create_field_definition ("0",
-					       "App.Title",
-					       TRACKER_PROPERTY_TYPE_INDEX,
-					       "Title",
-					       TRUE,
-					       NULL);
-
-	mimes = array_to_list (m);
-
-	mime_prefixes = array_to_list (mp);
-	tracker_ontology_init ();
-
-	expected_results = g_new0 (ExpectedResults, 1);
-	expected_results->service = service;
-	expected_results->parent_service = parent_service;
-
-	tracker_ontology_service_add (service, NULL, NULL);
-	tracker_ontology_service_add (parent_service, mimes, mime_prefixes);
-	tracker_ontology_service_add (other_service, NULL, NULL);
-	tracker_ontology_service_add (conv_service, NULL, NULL);
-	tracker_ontology_service_add (gaim_service, NULL, NULL);
-	tracker_ontology_service_add (gossip_service, NULL, NULL);
-	tracker_ontology_service_add (new_gaim_service, NULL, NULL);
-
-	tracker_ontology_field_add (field_title);
-
-	g_slist_free (mimes);
-	g_slist_free (mime_prefixes);
-}
-
-static void
-test_get_id_for_service (void)
-{
-	gint result_int;
-
-	result_int = tracker_ontology_get_service_id_by_name ("Test service");
-	g_assert_cmpint (result_int, ==, 0);
-
-	result_int = tracker_ontology_get_service_id_by_name ("trash");
-	g_assert_cmpint (result_int, ==, -1);
-}
-
-static void
-test_get_service_by_id (void)
-{
-	const gchar *result_string;
-
-	result_string = tracker_ontology_get_service_by_id (0);
-	g_assert (g_str_equal (result_string, "Test service"));
-
-	result_string = tracker_ontology_get_service_by_id (20);
-	g_assert (!result_string);
-}
-
-static void
-test_get_parent_service_by_id (void)
-{
-	gchar *result_string;
-
-	result_string = tracker_ontology_get_service_parent_by_id (0);
-	g_assert (g_str_equal (result_string, "Parent service"));
-	g_free (result_string);
-
-	result_string = tracker_ontology_get_service_parent_by_id (1);
-	g_assert (!result_string);
-	g_free (result_string);
-}
-
-static void
-test_get_parent_id_for_service_id (void)
-{
-	gint result_int;
-
-	result_int = tracker_ontology_get_service_parent_id_by_id (0);
-	g_assert_cmpint (result_int, ==, 1);
-
-	result_int = tracker_ontology_get_service_parent_id_by_id (1);
-	g_assert_cmpint (result_int, ==, -1);
-}
-
-static void
-test_get_parent_service (void)
-{
-	gchar *result_string;
-
-	result_string = tracker_ontology_get_service_parent ("Test service");
-	g_assert (g_str_equal (result_string, "Parent service"));
-	g_free (result_string);
-
-	result_string = tracker_ontology_get_service_parent ("Parent service");
-	g_assert (!result_string);
-	g_free (result_string);
-}
-
-static void
-test_get_service_type_for_mime (void)
-{
-	const gchar *value;
-
-	value = tracker_ontology_get_service_by_mime ("application/rtf");
-	g_assert (g_str_equal ("Parent service", value));
-
-	value = tracker_ontology_get_service_by_mime ("images/jpeg");
-	g_assert (g_str_equal ("Parent service", value));
-
-	value = tracker_ontology_get_service_by_mime ("noexists/bla");
-	g_assert (g_str_equal ("Other", value));
-}
-
-static void
-test_get_service (void)
-{
-	TrackerClass *service;
-
-	service = tracker_ontology_get_service_by_name ("Test service");
-	g_assert (test_cmp_service_equals (service, expected_results->service));
-
-	service = tracker_ontology_get_service_by_name ("No no no");
-	g_assert (!test_cmp_service_equals (service, expected_results->service));
-
-	service = tracker_ontology_get_service_by_name ("Parent service");
-	g_assert (test_cmp_service_equals (service, expected_results->parent_service));
-}
-
-static void
-test_get_db_for_service (void)
-{
-	TrackerDBType result_db;
-
-	result_db = tracker_ontology_get_service_db_by_name ("Test service");
-	g_assert (result_db == TRACKER_DB_TYPE_FILES); // ????? HARDCODED IN tracker-ontology!!!!!
-
-	result_db = tracker_ontology_get_service_db_by_name ("trash");
-	g_assert (result_db == TRACKER_DB_TYPE_FILES);
-}
-
-static void
-test_is_service_embedded (void)
-{
-	g_assert (tracker_ontology_service_has_embedded ("Test service"));
-	g_assert (!tracker_ontology_service_has_embedded ("Parent service"));
-	g_assert (!tracker_ontology_service_has_embedded ("Trash"));
-}
-
-static void
-test_has_thumbnails (void)
-{
-	g_assert (tracker_ontology_service_has_thumbnails ("Test service"));
-	g_assert (!tracker_ontology_service_has_thumbnails ("trash"));
-}
-
-static void
-test_has_text (void)
-{
-	g_assert (tracker_ontology_service_has_text ("Test service"));
-	g_assert (!tracker_ontology_service_has_text ("trash"));
-}
-
-static void
-test_has_metadata (void)
-{
-	g_assert (!tracker_ontology_service_has_metadata ("Test service"));
-	g_assert (!tracker_ontology_service_has_metadata ("trash"));
-}
-
-static void
-test_field_in_ontology (void)
-{
-	TrackerProperty *field;
-
-	field = tracker_ontology_get_field_by_name ("App.Title");
-	g_assert (field);
-	g_assert (!tracker_ontology_get_field_by_name ("nooooo"));
-}
-
-static void
-test_get_registered_service_types (void)
-{
-	GSList *service_types;
-
-	service_types = tracker_ontology_get_service_names_registered ();
-	g_assert_cmpint (7, ==, g_slist_length (service_types));
-	g_assert (element_in_list (service_types, "Applications"));
-
-	g_slist_foreach (service_types, (GFunc)g_free, NULL);
-	g_slist_free (service_types);
-}
-
-static void
-test_get_registered_field_types (void)
-{
-	GSList *field_types;
-
-	/* All registered field types */
-	field_types = tracker_ontology_get_field_names_registered (NULL);
-
-	g_assert_cmpint (1 ,==, g_slist_length (field_types));
-
-	g_assert (element_in_list (field_types, "App.Title"));
-
-	g_slist_foreach (field_types, (GFunc)g_free, NULL);
-	g_slist_free (field_types);
-
-	/* Music field types */
-	field_types = tracker_ontology_get_field_names_registered ("Music");
-	g_assert (!field_types);
-
-	/* App field types */
-	field_types = tracker_ontology_get_field_names_registered ("Applications");
-	g_assert_cmpint (1 ,==, g_slist_length (field_types));
-	g_assert (element_in_list (field_types, "App.Title"));
-
-	g_slist_foreach (field_types, (GFunc)g_free, NULL);
-	g_slist_free (field_types);
-}
-
-static void
-test_metadata_key_in_service (void)
-{
-	gint key;
-
-	key = tracker_ontology_service_get_key_metadata ("Applications",
-							 "Key:MetaData1");
-	g_assert_cmpint (key, ==, 1);
-
-	key = tracker_ontology_service_get_key_metadata ("Applications",
-							 "Key:MetaDataUnknown");
-	g_assert_cmpint (key, ==, 0);
-}
-
-static void
-test_get_subcategories (void)
-{
-	GArray *result;
-
-	result = tracker_ontology_get_subcategory_ids ("Applications");
-	g_assert (result != NULL);
-	g_assert_cmpint (result->len, ==, 1);
-	
-	result = tracker_ontology_get_subcategory_ids ("Conversations");
-	g_assert (result != NULL);
-	g_assert_cmpint (result->len, ==, 3);
-	
-	result = tracker_ontology_get_subcategory_ids ("*");
-	g_assert (result != NULL);
-	g_assert_cmpint (result->len, ==, 7);
-}
-
-int
-main (int argc, char **argv)
-{
-	gint result;
-
-	g_type_init ();
-	g_test_init (&argc, &argv, NULL);
-
-	tracker_services_general_setup ();
-
-	g_test_add_func ("/libtracker-common/tracker-ontology/get_id_for_service",
-			 test_get_id_for_service);
-	g_test_add_func ("/libtracker-common/tracker-ontology/get_service_for_id",
-			 test_get_service_by_id);
-	g_test_add_func ("/libtracker-common/tracker-ontology/get_parent_service_by_id",
-			  test_get_parent_service_by_id);
-	g_test_add_func ("/libtracker-common/tracker-ontology/get_parent_id_for_service_id",
-			 test_get_parent_id_for_service_id);
-	g_test_add_func ("/libtracker-common/tracker-ontology/get_parent_service",
-			 test_get_parent_service);
-	g_test_add_func ("/libtracker-common/tracker-ontology/get_service_type_for_mime",
-			 test_get_service_type_for_mime);
-	g_test_add_func ("/libtracker-common/tracker-ontology/get_service",
-			 test_get_service);
-	g_test_add_func ("/libtracker-common/tracker-ontology/get_db_for_service",
-			 test_get_db_for_service);
-	g_test_add_func ("/libtracker-common/tracker-ontology/is_service_embedded",
-			 test_is_service_embedded);
-	g_test_add_func ("/libtracker-common/tracker-ontology/has_thumbnails",
-			 test_has_thumbnails);
-	g_test_add_func ("/libtracker-common/tracker-ontology/has_text",
-			 test_has_text);
-	g_test_add_func ("/libtracker-common/tracker-ontology/has_metadata",
-			 test_has_metadata);
-	g_test_add_func ("/libtracker-common/tracker-ontology/test_field_in_ontology",
-			 test_field_in_ontology);
-
-	g_test_add_func ("/libtracker-common/tracker-ontology/test_get_all_registered_service_types",
-			 test_get_registered_service_types);
-	g_test_add_func ("/libtracker-common/tracker-ontology/test_get_all_registered_field_types",
-			 test_get_registered_field_types);
-
-	g_test_add_func ("/libtracker-common/tracker-ontology/test_metadata_key_in_service",
-			 test_metadata_key_in_service);
-
-	g_test_add_func ("/libtracker-common/tracker-ontology/test_get_subcategories",
-			 test_get_subcategories);
-
-	result = g_test_run ();
-
-	tracker_ontology_shutdown ();
-
-	return result;
-}
diff --git a/tests/libtracker-db/tracker-db-manager-test-attach.c b/tests/libtracker-db/tracker-db-manager-test-attach.c
index f1c2c89..b7ee257 100644
--- a/tests/libtracker-db/tracker-db-manager-test-attach.c
+++ b/tests/libtracker-db/tracker-db-manager-test-attach.c
@@ -87,7 +87,6 @@ test_creation_common_db_no_reindex ()
 }
 
 
-
 static void
 test_creation_file_meta_db_no_reindex ()
 {
diff --git a/tests/libtracker-db/tracker-db-manager-test-custom.c b/tests/libtracker-db/tracker-db-manager-test-custom.c
index 7c30914..6fa8f2d 100644
--- a/tests/libtracker-db/tracker-db-manager-test-custom.c
+++ b/tests/libtracker-db/tracker-db-manager-test-custom.c
@@ -44,7 +44,6 @@ test_custom_common_filemeta_filecontents ()
 }
 
 
-
 int
 main (int argc, char **argv) {
 
diff --git a/tests/libtracker-db/tracker-db-manager-test-unattach.c b/tests/libtracker-db/tracker-db-manager-test-unattach.c
index 5164e9b..9123040 100644
--- a/tests/libtracker-db/tracker-db-manager-test-unattach.c
+++ b/tests/libtracker-db/tracker-db-manager-test-unattach.c
@@ -37,7 +37,7 @@ test_creation_common_db ()
 static void
 test_creation_cache_db ()
 {
-	test_assert_tables_in_db (TRACKER_DB_CACHE, "SELECT * FROM FilePending");
+	test_assert_tables_in_db (TRACKER_DB_CACHE, "SELECT * FROM SearchResults1");
 }
 
 static void
@@ -82,7 +82,6 @@ main (int argc, char **argv) {
 	g_test_add_func ("/libtracker-db/tracker-db-manager/unattach/common_db_tables",
 			test_creation_common_db);
 
-
 	g_test_add_func ("/libtracker-db/tracker-db-manager/unattach/cache_db_tables",
 			test_creation_cache_db);
 
diff --git a/tests/libtracker-db/tracker-index-writer-test.c b/tests/libtracker-db/tracker-index-writer-test.c
index 3fe8631..83e4877 100644
--- a/tests/libtracker-db/tracker-index-writer-test.c
+++ b/tests/libtracker-db/tracker-index-writer-test.c
@@ -42,7 +42,7 @@ insert_in_index (TrackerDBIndex *index,
 	pieces = g_strsplit (text, " ", -1);
 
 	for (i = 0; pieces[i] != NULL; i++) {
-		tracker_db_index_add_word (index, pieces[i], service_id, 1, 1);
+		tracker_db_index_add_word (index, pieces[i], service_id, 1);
 	}
 
 	g_strfreev (pieces);
@@ -61,7 +61,7 @@ remove_in_index (TrackerDBIndex *index,
 	pieces = g_strsplit (text, " ", -1);
 
 	for (i = 0; pieces[i] != NULL; i++) {
-		tracker_db_index_add_word (index, pieces[i], service_id, 1, -1);
+		tracker_db_index_add_word (index, pieces[i], service_id, -1);
 	}
 
 	g_strfreev (pieces);
@@ -132,7 +132,7 @@ test_add_one_word (void)
 	g_remove (indexname);
 	index = tracker_db_index_new (indexname, MIN_BUCKET_COUNT, MAX_BUCKET_COUNT, FALSE);
 
-	tracker_db_index_add_word (index, "word1", 1, 1, 1);
+	tracker_db_index_add_word (index, "word1", 1, 1);
 	tracker_db_index_flush (index);
 	g_object_unref (index);
 
@@ -155,7 +155,7 @@ test_add_n_words (void)
 
 	for ( i = 0; i < 20; i++) {
 		word = g_strdup_printf ("word%d", i);
-		tracker_db_index_add_word (index, word, 1, 1, 1);
+		tracker_db_index_add_word (index, word, 1, 1);
 		g_free (word);
 	}
 
@@ -178,7 +178,7 @@ test_add_word_n_times (void)
 	index = tracker_db_index_new (indexname, MIN_BUCKET_COUNT, MAX_BUCKET_COUNT, FALSE);
 
 	for ( i = 0; i < 20; i++) {
-		tracker_db_index_add_word (index, "test-word", i, 1, 1);
+		tracker_db_index_add_word (index, "test-word", i, 1);
 	}
 
 	tracker_db_index_flush (index);
@@ -201,7 +201,7 @@ test_add_word_multiple_occurrences (void)
 	index = tracker_db_index_new (indexname, MIN_BUCKET_COUNT, MAX_BUCKET_COUNT, FALSE);
 
 	for ( i = 0; i < 20; i++) {
-		tracker_db_index_add_word (index, "test-word", 1, 1, 1);
+		tracker_db_index_add_word (index, "test-word", 1, 1);
 	}
 
 	tracker_db_index_flush (index);
diff --git a/tests/scripts/.gitignore b/tests/scripts/.gitignore
deleted file mode 100644
index ec78f0b..0000000
--- a/tests/scripts/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-dummy_data_start.sh
-dummy_data_stop.sh
diff --git a/tests/scripts/Makefile.am b/tests/scripts/Makefile.am
deleted file mode 100644
index 8022ab6..0000000
--- a/tests/scripts/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-include $(top_srcdir)/Makefile.decl
-
-noinst_SCRIPTS = dummy_data_start.sh dummy_data_stop.sh
diff --git a/tests/scripts/data/common.sql b/tests/scripts/data/common.sql
deleted file mode 100644
index 92f1712..0000000
--- a/tests/scripts/data/common.sql
+++ /dev/null
@@ -1,609 +0,0 @@
-BEGIN TRANSACTION;
-ANALYZE sqlite_master;
-CREATE TABLE Options (	
-	OptionKey 	Text COLLATE NOCASE not null,	
-	OptionValue	Text COLLATE NOCASE
-);
-INSERT INTO "Options" VALUES('DBVersion','20');
-INSERT INTO "Options" VALUES('Sequence','1');
-INSERT INTO "Options" VALUES('EventSequence','1');
-INSERT INTO "Options" VALUES('UpdateCount','0');
-INSERT INTO "Options" VALUES('1','IntegrityCheck');
-INSERT INTO "Options" VALUES('1','InitialIndex');
-CREATE TABLE Volumes
-(
-	VolumeID 	Integer primary key AUTOINCREMENT not null,
-	UDI		Text,
-	VolumeName	Text,
-	MountPath	Text,
-	Enabled		Integer default 0
-
-);
-DELETE FROM sqlite_sequence;
-INSERT INTO "sqlite_sequence" VALUES('MetaDataTypes',117);
-INSERT INTO "sqlite_sequence" VALUES('ServiceTypes',23);
-CREATE TABLE ServiceLinks
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	MetadataID		Integer not null,
-	SourcePath		Text,
-	SourceName		Text,
-	DestPath		Text,
-	DestName		Text
-);
-CREATE TABLE BackupServices
-(
-	ID            		Integer primary key AUTOINCREMENT not null,
-	Path 			Text  not null, 
-	Name	 		Text,
-
-	unique (Path, Name)
-
-);
-CREATE TABLE BackupMetaData
-(
-	ID			Integer primary key  AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer  not null,
-	UserValue		Text
-	
-	 
-);
-CREATE TABLE KeywordImages
-(
-	Keyword 	Text primary key,
-	Image		Text
-);
-CREATE TABLE VFolders
-(
-	Path			Text  not null,
-	Name			Text  not null,
-	Query			text not null,
-	RDF			text,
-	Type			Integer default 0,
-	active			Integer,
-
-	primary key (Path, Name)
-
-);
-CREATE TABLE MetaDataTypes 
-(
-	ID	 		Integer primary key AUTOINCREMENT not null,
-	MetaName		Text not null  COLLATE NOCASE, 
-	DataTypeID		Integer default 1,    /* 0=Keyword, 1=indexable, 2=Clob (compressed indexable text),  3=String, 4=Integer, 5=Double,  6=DateTime, 7=Blob, 8=Struct, 9=ServiceLink */
-	DisplayName		text,
-	Description		text default ' ',
-	Enabled			integer default 1, /* used to prevent use of this metadata type */
-	UIVisible		integer default 0, /* should this metadata type be visible in a search criteria UI  */
-	WriteExec		text default ' ', /* used to specify an external program that can write an *embedded* metadata to a file */
-	Alias			text default ' ', /* alternate name for this type (XESAM specs?) */
-	FieldName		text default ' ', /* filedname if present in the services table */
-	Weight			Integer default 1, /* weight of metdata type in ranking */
-	Embedded		Integer default 1, /* 1 if metadata extracted from the file by the indexer and is not updateable by the user. 0 - this metadata can be updated by the user and is external to the file */
-	MultipleValues		Integer default 0, /* 0= type cannot have multiple values per entity, 1= type can have more than 1 value per entity */
-	Delimited		Integer default 0, /* if 1, extra delimiters (hyphen and underscore) are used to break word */
-	Filtered		Integer default 1, /* if 1, words are filtered for numerics (if numeric indexing is disabled), stopwords and min length */
-	Abstract		Integer default 0, /* if 0, can be used for storing metadata - Abstract type classes cannot store metadata and can only be used for searching its decendants */
-	StemMetadata		Integer default 1, /* 1 if metadata should be stemmed */
-	SideCar			Integer default 0, /* should this metadata be backed up in an xmp sidecar file */
-	FileName		Text default ' ',
-
-	Unique (MetaName)
-);
-INSERT INTO "MetaDataTypes" VALUES(1,'default',1,NULL,' ',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(2,'DC:Contributor',1,'Contributor','Contributors to the resource (other than the authors)',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(3,'DC:Coverage',1,'Coverage','The extent or scope of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(4,'DC:Creator',1,'Author','The authors of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(5,'DC:Date',6,'Date','Date that something interesting happened to the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(6,'DC:Description',1,'Description','A textual description of the content of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(7,'DC:Format',0,'Format','The file format(mime) or type used when saving the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(8,'DC:Identifier',1,'Identifier','Unique identifier of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(9,'DC:Language',1,'Langauge','Language used in the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(10,'DC:Publishers',1,'Publishers','Publishers of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(11,'DC:Relation',1,'Relationship','Relationships to other resources',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(12,'DC:Rights',1,'Rights','Informal rights statement of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(13,'DC:Source',1,'Source','Unique identifier of the work from which this resource was derived',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(14,'DC:Subject',1,'Subject','specifies the topic of the content of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(15,'DC:Keywords',0,'Keywords','Keywords that are used to tag a resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(16,'DC:Title',1,'Title','specifies the topic of the content of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(17,'DC:Type',1,'Type','specifies the type of the content of the resource',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(18,'User:Rank',4,'Rank','User settable rank or score of the resource',1,0,' ',' ','Rank',1,0,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(19,'User:Keywords',0,'Keywords','User settable keywords which are used to tag a resource',1,0,' ',' ',' ',50,0,1,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(20,'File:Name',1,'Filename','Name of File',1,0,' ',' ','Name',10,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(21,'File:Ext',1,'Extension','File extension',1,0,' ',' ',' ',15,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(22,'File:Path',1,'Path','File Path',1,0,' ',' ','Path',1,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(23,'File:NameDelimited',1,'Keywords','Name of File',1,0,' ',' ',' ',5,1,0,1,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(24,'File:Contents',2,'Contents','File Contents',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(25,'File:Link',1,'Link','File Link',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(26,'File:Mime',0,'Mime Type','File Mime Type',1,0,' ',' ','Mime',10,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(27,'File:Size',4,'Size','File size in bytes',1,0,' ',' ','Size',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(28,'File:License',1,'License','File License Type',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(29,'File:Copyright',1,'Copyright','Copyright owners of the file',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(30,'File:Modified',6,'Modified','Last modified date',1,0,' ',' ','IndexTime',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(31,'File:Accessed',6,'Accessed','Last acessed date',1,0,' ',' ','Accessed',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(32,'File:Other',1,'Other','Other details about a file',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(33,'Audio:Title',1,'Title','Track title',1,0,' ',' ',' ',20,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(34,'Audio:Artist',1,'Artist','Track artist',1,0,' ',' ',' ',15,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(35,'Audio:Album',1,'Title','Track title',1,0,' ',' ',' ',10,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(36,'Audio:Genre',0,'Genre','The type or genre of the music track',1,0,' ',' ',' ',5,1,1,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(37,'Audio:Duration',4,'Duration','The length in seconds of the music track',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(38,'Audio:ReleaseDate',6,'Release date','The date the track was released',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(39,'Audio:AlbumArtist',1,'Album artist',' ',1,0,' ',' ',' ',10,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(40,'Audio:AlbumTrackCount',4,'Album track count','The number of tracks in the album',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(41,'Audio:TrackNo',4,'Track number','The position of the track relative to the others',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(42,'Audio:DiscNo',4,'Disc number','On which disc the track is located',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(43,'Audio:Performer',1,'Performer','The individual or group performing the track',1,0,' ',' ',' ',5,1,1,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(44,'Audio:TrackGain',5,'Track gain','The amount of gain needed for the track',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(45,'Audio:PeakTrackGain',5,'Peak track gain','The peak amount of gain needed for the track',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(46,'Audio:AlbumGain',5,'Album gain','The amount of gain needed for the entire album',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(47,'Audio:AlbumPeakGain',5,'Peak album gain','The peak amount of gain needed for the entire album',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(48,'Audio:Comment',1,'Comments','General purpose comments',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(49,'Audio:Codec',1,'Codec','Codec name',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(50,'Audio:CodecVersion',3,'Codec version','Codec version string',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(51,'Audio:Samplerate',5,'Sample rate','Sample rate of track in Hz',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(52,'Audio:Bitrate',5,'Bitrate','Bitrate in bits/sec',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(53,'Audio:Channels',4,'Channels','The number of channels in the track',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(54,'Audio:LastPlay',6,'Last Played','The date and time the track was last played',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(55,'Audio:PlayCount',4,'Play Count','Number of times the track has been played',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(56,'Audio:DateAdded',6,'Date Added','Date track was first added',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(57,'Audio:Lyrics',1,'Lyrics','Lyrics of the track',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(58,'Audio:MBAlbumID',3,'MusicBrainz album ID','The MusicBrainz album ID for the track',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(59,'Audio:MBArtistID',3,'MusicBrainz artist ID','The MusicBrainz artist ID for the track',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(60,'Audio:MBAlbumArtistID',3,'MusicBrainz album artist ID','The MusicBrainz album artist ID for the track',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(61,'Audio:MBTrackID',3,'MusicBrainz track ID','The MusicBrainz track ID',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(62,'App:Name',1,'Name','Application name',1,0,' ',' ',' ',25,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(63,'App:DisplayName',1,'Display name','Application display name',1,0,' ',' ',' ',10,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(64,'App:GenericName',1,'Generic name','Application generic name',1,0,' ',' ',' ',10,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(65,'App:Comment',1,'Comments','Application comments',1,0,' ',' ',' ',5,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(66,'App:Exec',3,'Name','Application name',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(67,'App:Icon',3,'Icon','Application icon name',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(68,'App:MimeType',0,'Mime type','Application supported mime types',1,0,' ',' ',' ',1,1,1,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(69,'App:Categories',0,'Categories','Application categories',1,0,' ',' ',' ',5,1,1,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(70,'Doc:Title',1,'Title','The title of the document',1,0,' ',' ',' ',25,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(71,'Doc:Subject',1,'Subject','The subject or topic of the document',1,0,' ',' ',' ',20,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(72,'Doc:Author',1,'Author','The author of the document',1,0,' ',' ',' ',20,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(73,'Doc:Keywords',0,'Keywords','keywords embedded in the document',1,0,' ',' ',' ',25,1,0,1,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(74,'Doc:Comments',1,'Comments','The comments embedded in the document',1,0,' ',' ',' ',10,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(75,'Doc:PageCount',4,'Page count','Number of pages in the document',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(76,'Doc:WordCount',4,'Word count','Number of words in the document',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(77,'Doc:Created',6,'Created','Date document was created',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(78,'Doc:URL',1,'URL','URL to this Doc',1,0,' ',' ',' ',20,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(79,'Email:Recipient',1,'Recipient','The recepient of an email',1,0,' ',' ',' ',1,1,0,0,1,1,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(80,'Email:Body',1,'Body','The body contents of the email',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(81,'Email:Date',1,'Date','Date email was sent',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(82,'Email:Sender',1,'Sender','The sender of the email',1,0,' ',' ',' ',10,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(83,'Email:Subject',1,'Subject','The subject of the email',1,0,' ',' ',' ',20,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(84,'Email:SentTo',1,'Sent to','The group of people the email was sent to',1,0,' ',' ',' ',10,1,1,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(85,'Email:CC',1,'CC','The CC recipients of the email',1,0,' ',' ',' ',5,1,1,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(86,'Email:Attachments',1,'Attachments','The names of the attachments',1,0,' ',' ',' ',5,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(87,'Email:AttachmentsDelimited',1,'AttachmentsDelimited','The names of the attachments with extra delimiting',1,0,' ',' ',' ',5,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(88,'Image:Title',1,'Title','The title of the image',1,0,' ',' ',' ',10,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(89,'Image:Keywords',1,'Keywords','The keywords embedded in the image',1,0,' ',' ',' ',20,1,0,1,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(90,'Image:Height',1,'Height','Height in pixels of the image',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(91,'Image:Width',1,'Width','Width in pixels of the image',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(92,'Image:Album',1,'Album','The name of the album in which the image resides',1,0,' ',' ',' ',5,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(93,'Image:Date',1,'Created','Date image was created or shot',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(94,'Image:Creator',1,'Creator','The person who created the image',1,0,' ',' ',' ',10,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(95,'Image:Comments',1,'Comments','The comments embedded in the image',1,0,' ',' ',' ',5,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(96,'Image:Description',1,'Description','The description embedded in the image',1,0,' ',' ',' ',5,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(97,'Image:Software',1,'Software','The software used to create the image',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(98,'Image:CameraMake',1,'Camera make','The camera used to create the image',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(99,'Image:CameraModel',1,'Camera model','The model number of the camera used to create the image',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(100,'Image:Orientation',1,'Orientation','The Orientation mode of the image (portrait/landscape)',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(101,'Image:ExposureProgram',1,'Exposure program','The class of the program used by the camera to set exposure when the picture is taken',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(102,'Image:ExposureTime',1,'Exposure time','Exposure time in seconds',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(103,'Image:FNumber',1,'F number','The F number',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(104,'Image:Flash',1,'Flash','Indicates the status of flash when the image was shot (0=off, 1=on)',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(105,'Image:FocalLength',1,'Focal length','The actual focal length of the lens in mm',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(106,'Image:ISOSpeed',1,'ISO speed','Indicates the ISO Speed and ISO Latitude of the camera or input device as specified in ISO 12232.',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(107,'Image:MeteringMode',1,'Metering mode','The metering mode',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(108,'Image:WhiteBalance',1,'White balance','Indicates the white balance mode set when the image was shot (auto/manual)',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(109,'Video:Title',1,'Title','Video title',1,0,' ',' ',' ',20,1,0,0,0,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(110,'Video:Author',1,'Author','Video author',1,0,' ',' ',' ',15,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(111,'Video:Height',4,'Height','The height in pixels',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(112,'Video:Width',4,'Width','The width in pixels',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(113,'Video:Duration',4,'Duration','Duration in number of seconds',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(114,'Video:Comments',1,'Comments','General purpose comments',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(115,'Video:FrameRate',5,'Frame rate','Number of frames per seconds',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(116,'Video:Codec',3,'Codec','Codec used for the video',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-INSERT INTO "MetaDataTypes" VALUES(117,'Video:Bitrate',5,'Bitrate','Bitrate in bits/sec',1,0,' ',' ',' ',1,1,0,0,1,0,1,0,' ');
-CREATE TABLE MetaDataChildren
-(
-	MetaDataID		integer not null,
-	ChildID			integer not null,
-
-	primary key (MetaDataID, ChildID)
-
-);
-INSERT INTO "MetaDataChildren" VALUES(15,19);
-INSERT INTO "MetaDataChildren" VALUES(8,20);
-INSERT INTO "MetaDataChildren" VALUES(8,22);
-INSERT INTO "MetaDataChildren" VALUES(11,25);
-INSERT INTO "MetaDataChildren" VALUES(7,26);
-INSERT INTO "MetaDataChildren" VALUES(12,28);
-INSERT INTO "MetaDataChildren" VALUES(12,29);
-INSERT INTO "MetaDataChildren" VALUES(5,30);
-INSERT INTO "MetaDataChildren" VALUES(5,31);
-INSERT INTO "MetaDataChildren" VALUES(16,33);
-INSERT INTO "MetaDataChildren" VALUES(4,34);
-INSERT INTO "MetaDataChildren" VALUES(17,36);
-INSERT INTO "MetaDataChildren" VALUES(5,38);
-INSERT INTO "MetaDataChildren" VALUES(4,39);
-INSERT INTO "MetaDataChildren" VALUES(2,43);
-INSERT INTO "MetaDataChildren" VALUES(6,48);
-INSERT INTO "MetaDataChildren" VALUES(5,54);
-INSERT INTO "MetaDataChildren" VALUES(8,58);
-INSERT INTO "MetaDataChildren" VALUES(8,59);
-INSERT INTO "MetaDataChildren" VALUES(8,60);
-INSERT INTO "MetaDataChildren" VALUES(8,61);
-INSERT INTO "MetaDataChildren" VALUES(16,70);
-INSERT INTO "MetaDataChildren" VALUES(14,71);
-INSERT INTO "MetaDataChildren" VALUES(4,72);
-INSERT INTO "MetaDataChildren" VALUES(15,73);
-INSERT INTO "MetaDataChildren" VALUES(6,74);
-INSERT INTO "MetaDataChildren" VALUES(5,77);
-INSERT INTO "MetaDataChildren" VALUES(5,81);
-INSERT INTO "MetaDataChildren" VALUES(4,82);
-INSERT INTO "MetaDataChildren" VALUES(14,83);
-INSERT INTO "MetaDataChildren" VALUES(79,84);
-INSERT INTO "MetaDataChildren" VALUES(79,85);
-INSERT INTO "MetaDataChildren" VALUES(16,88);
-INSERT INTO "MetaDataChildren" VALUES(15,89);
-INSERT INTO "MetaDataChildren" VALUES(5,93);
-INSERT INTO "MetaDataChildren" VALUES(4,94);
-INSERT INTO "MetaDataChildren" VALUES(6,95);
-INSERT INTO "MetaDataChildren" VALUES(6,96);
-INSERT INTO "MetaDataChildren" VALUES(16,109);
-INSERT INTO "MetaDataChildren" VALUES(4,110);
-INSERT INTO "MetaDataChildren" VALUES(6,114);
-CREATE TABLE MetaDataGroup
-(
-	MetaDataGroupID		integer not null,
-	ChildID			integer not null,
-
-	primary key (MetaDataGroupID, ChildID)
-
-);
-CREATE TABLE MetadataOptions
-(
-	MetaDataID		Integer not null,
-	OptionName		Text not null,
-	OptionValue		Text default ' ',
-
-	primary key (MetaDataID, OptionName)
-);
-CREATE TABLE ServiceTypes
-(
-	TypeID 			Integer primary key AUTOINCREMENT not null,
-	TypeName		Text COLLATE NOCASE not null,
-
-	TypeCount		Integer default 0,
-
-	DisplayName		Text default ' ',
-	Parent			Text default ' ',
-	Enabled			Integer default 1, 
-	Embedded		Integer default 1, /* service is created by the indexer if embedded. User or app defined services are not embedded */
-	ChildResource		Integer default 0, /* service is a child service */
-	
-	CreateDesktopFile	Integer default 0, /* used by a UI to indicate whether it should create a desktop file for the service if its copied (using the ViewerExec field + uri) */
-
-	/* useful for a UI when determining what actions a hit can have */
-	CanCopy			Integer default 1, 
-	CanDelete		Integer default 1,
-
-	ShowServiceFiles	Integer default 0,
-	ShowServiceDirectories  Integer default 0,
-
-	HasMetadata		Integer default 1,
-	HasFullText		Integer default 1,
-	HasThumbs		Integer default 1,
-	
-	ContentMetadata		Text default ' ', /* the content field is the one most likely to be used for showing a search snippet */ 
-
-	KeyMetadata1		Text default ' ', /* the most commonly requested metadata (especially for tables/grid views) is cached int he services table for extra fast retrieval */
-	KeyMetadata2		Text default ' ',
-	KeyMetadata3		Text default ' ',
-	KeyMetadata4		Text default ' ',
-	KeyMetadata5		Text default ' ',
-	KeyMetadata6		Text default ' ',
-	KeyMetadata7		Text default ' ',
-	KeyMetadata8		Text default ' ',
-	KeyMetadata9		Text default ' ',
-	KeyMetadata10		Text default ' ',
-	KeyMetadata11		Text default ' ',
-
-	UIVisible		Integer default 0,	/* should service appear in a search GUI? */
-	UITitle			Text default ' ',	/* title format as displayed in the metadata tile */
-	UIMetadata1		Text default ' ',	/*UI fields to show in GUI for a hit - if not set then Name,Path,Mime are used */
-	UIMetadata2		Text default ' ',
-	UIMetadata3		Text default ' ',
-	UIView			Text default 'default',
-
-	Description		Text default ' ',
-	Database		integer default 0, /* 0 = DB_FILES, 1 = DB_EMAILS, 2 = DB_MISC, 3 = DB_USER */
-	Icon			Text default ' ',
-
-	IndexerExec		Text default ' ',
-	IndexerOutput		Text default 'stdout',
-	ThumbExec		Text default ' ',
-	ViewerExec		Text default ' ',
-
-	WatchFolders		Text default ' ',
-	IncludeGlob		Text default ' ',
-	ExcludeGlob		Text default ' ',
-
-	FileName		Text default ' ',
-
-	unique (TypeName)
-);
-INSERT INTO "ServiceTypes" VALUES(1,'default',0,' ',' ',1,1,0,0,1,1,0,0,1,1,1,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default',' ',0,' ',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(2,'Files',0,'All Files',' ',1,1,0,0,1,1,1,1,1,1,1,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','icon','All files in the filesystem',0,'system-file-manager',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(3,'Folders',0,'Folders','Files',1,1,0,0,1,1,1,1,1,1,1,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','icon','Folders in the filesystem',0,'folder',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(4,'Documents',0,'Documents','Files',1,1,0,0,1,1,1,1,1,1,1,'File:Contents','Doc:Title','Doc:Author','Doc:Created',' ',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','default','Office and PDF based files',0,'x-office-document',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(5,'WebHistory',0,'Web History',' ',1,1,0,0,1,1,0,0,1,1,1,' ','Doc:Title','Doc:URL','Doc:Keywords','User:Keywords',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','default','Web History',0,'x-office-document',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(6,'Images',0,'Images','Files',1,1,0,0,1,1,1,1,1,0,1,' ','Image:Title','Image:Height','Image:Width','Image:Date','Image:Software','Image:Creator',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','icon','Image based files',0,'image-x-generic',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(7,'Music',0,'Music','Files',1,1,0,0,1,1,1,1,1,0,0,' ','Audio:Title','Audio:Artist','Audio:Album','Audio:Genre','Audio:Duration','Audio:ReleaseDate','Audio:TrackNo','Audio:Bitrate','Audio:PlayCount','Audio:DateAdded','Audio:LastPlay',1,' ',' ',' ',' ','tabular','Music based files',0,'audio-x-generic',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(8,'Videos',0,'Videos','Files',1,1,0,0,1,1,1,1,1,0,1,' ','Video:Title','Video:Author','Video:Height','Video:Width','Video:Duration','Audio:Bitrate',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','icon','Video based files',0,'video-x-generic',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(9,'Text',0,'Text','Files',1,1,0,0,1,1,1,1,0,1,0,'File:Contents',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','default','Text based files',0,'text-x-generic',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(10,'Development',0,'Development','Files',1,1,0,0,1,1,1,1,0,1,0,'File:Contents',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','default','Development and source code files',0,'applications-development',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(11,'Other',0,'Other Files','Files',1,1,0,0,1,1,1,1,1,1,1,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','All other files that do not belong in any other category',0,' ',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(12,'Emails',0,'Emails',' ',1,1,0,0,1,1,0,0,1,1,1,'Email:Body',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',1,' ','Email:Subject','Email:Sender',' ','default','All Emails',0,'stock_mail-open',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(13,'EvolutionEmails',0,'Evolution Emails','Emails',1,1,0,0,1,1,0,0,1,1,1,'Email:Body','Email:Subject','Email:Sender','Email:Date',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','Evolution based emails',0,' ',' ','stdout',' ','evolution "%1"',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(14,'ModestEmails',0,'Modest Emails','Emails',1,1,0,0,1,1,0,0,1,1,1,'Email:Body','Email:Subject','Email:Sender','Email:Date',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','Modest based emails',0,' ',' ','stdout',' ','modest-open "%1"',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(15,'ThunderbirdEmails',0,'Thunderbird Emails','Emails',1,1,0,0,1,1,0,0,1,1,1,'Email:Body','Email:Subject','Email:Sender','Email:Date',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','Thunderbird based emails',0,' ',' ','stdout',' ','thunderbird -viewtracker "%1"',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(16,'KMailEmails',0,'KMail Emails','Emails',1,1,0,0,1,1,0,0,1,1,1,'Email:Body','Email:Subject','Email:Sender','Email:Date',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','KMail based emails',0,' ',' ','stdout',' ','kmail "%1"',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(17,'EmailAttachments',0,'Email Attachments',' ',1,1,0,0,1,1,0,0,1,1,1,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','default','All files that are attached to an Email',0,'stock_attach',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(18,'EvolutionAttachments',0,'Evolution Email Attachments','EmailAttachments',1,1,0,0,1,1,0,0,1,1,1,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','All files that are attached to an Evolution Email',0,'stock_attach',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(19,'ModestAttachments',0,'Modest Email Attachments','EmailAttachments',1,1,0,0,1,1,0,0,1,1,1,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','All files that are attached to an Modest Email',0,'stock_attach',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(20,'KMailAttachments',0,'KMail Email Attachments','EmailAttachments',1,1,0,0,1,1,0,0,1,1,1,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','All files that are attached to an KMail Email',0,'stock_attach',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(21,'Conversations',0,'Conversations',' ',1,1,0,0,1,1,1,0,0,1,0,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','default','Conversation log files',0,'stock_help-chat',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(22,'GaimConversations',0,'Gaim Conversations','Conversations',1,1,0,0,1,1,1,0,0,1,0,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0,' ',' ',' ',' ','default','All Gaim Conversation logs',0,'stock_help-chat',' ','stdout',' ',' ',' ',' ',' ',' ');
-INSERT INTO "ServiceTypes" VALUES(23,'Applications',0,'Applications',' ',1,1,0,0,1,1,1,0,0,0,0,' ','App:DisplayName','App:Exec','App:Icon',' ',' ',' ',' ',' ',' ',' ',' ',1,' ',' ',' ',' ','default','Application files',0,'stock_active',' ','stdout',' ',' ',' ',' ',' ',' ');
-CREATE TABLE ServiceTileMetadata
-(
-	ServiceTypeID		Integer not null,
-	MetaName		Text not null,
-
-	primary key (ServiceTypeID, MetaName)
-);
-INSERT INTO "ServiceTileMetadata" VALUES(4,'Doc:Title');
-INSERT INTO "ServiceTileMetadata" VALUES(4,'Doc:Subject');
-INSERT INTO "ServiceTileMetadata" VALUES(4,'Doc:Author');
-INSERT INTO "ServiceTileMetadata" VALUES(4,'Doc:Created');
-INSERT INTO "ServiceTileMetadata" VALUES(4,'Doc:PageCount');
-INSERT INTO "ServiceTileMetadata" VALUES(4,'File:Size');
-INSERT INTO "ServiceTileMetadata" VALUES(5,'Doc:Title');
-INSERT INTO "ServiceTileMetadata" VALUES(5,'Doc:URL');
-INSERT INTO "ServiceTileMetadata" VALUES(5,'Doc:Subject');
-INSERT INTO "ServiceTileMetadata" VALUES(5,'Doc:Author');
-INSERT INTO "ServiceTileMetadata" VALUES(5,'Doc:Created');
-INSERT INTO "ServiceTileMetadata" VALUES(5,'Doc:PageCount');
-INSERT INTO "ServiceTileMetadata" VALUES(5,'File:Size');
-INSERT INTO "ServiceTileMetadata" VALUES(6,'Image:Title');
-INSERT INTO "ServiceTileMetadata" VALUES(6,'Image:Height');
-INSERT INTO "ServiceTileMetadata" VALUES(6,'Image:Width');
-INSERT INTO "ServiceTileMetadata" VALUES(6,'Image:Date');
-INSERT INTO "ServiceTileMetadata" VALUES(6,'Image:Creator');
-INSERT INTO "ServiceTileMetadata" VALUES(6,'Image:Software');
-INSERT INTO "ServiceTileMetadata" VALUES(6,'Image:Comments');
-INSERT INTO "ServiceTileMetadata" VALUES(7,'Audio:Title');
-INSERT INTO "ServiceTileMetadata" VALUES(7,'Audio:Artist');
-INSERT INTO "ServiceTileMetadata" VALUES(7,'Audio:Album');
-INSERT INTO "ServiceTileMetadata" VALUES(7,'Audio:Genre');
-INSERT INTO "ServiceTileMetadata" VALUES(7,'Audio:Duration');
-INSERT INTO "ServiceTileMetadata" VALUES(7,'Audio:ReleaseDate');
-INSERT INTO "ServiceTileMetadata" VALUES(8,'Video:Title');
-INSERT INTO "ServiceTileMetadata" VALUES(8,'Video:Author');
-INSERT INTO "ServiceTileMetadata" VALUES(8,'Video:Height');
-INSERT INTO "ServiceTileMetadata" VALUES(8,'Video:Width');
-INSERT INTO "ServiceTileMetadata" VALUES(8,'Video:Duration');
-INSERT INTO "ServiceTileMetadata" VALUES(8,'Video:Bitrate');
-INSERT INTO "ServiceTileMetadata" VALUES(12,'Email:Sender');
-INSERT INTO "ServiceTileMetadata" VALUES(12,'Email:Subject');
-INSERT INTO "ServiceTileMetadata" VALUES(12,'Email:Date');
-INSERT INTO "ServiceTileMetadata" VALUES(12,'Email:SentTo');
-INSERT INTO "ServiceTileMetadata" VALUES(12,'Email:CC');
-INSERT INTO "ServiceTileMetadata" VALUES(12,'Email:Attachments');
-INSERT INTO "ServiceTileMetadata" VALUES(13,'Email:Sender');
-INSERT INTO "ServiceTileMetadata" VALUES(13,'Email:Subject');
-INSERT INTO "ServiceTileMetadata" VALUES(13,'Email:Date');
-INSERT INTO "ServiceTileMetadata" VALUES(13,'Email:SentTo');
-INSERT INTO "ServiceTileMetadata" VALUES(13,'Email:CC');
-INSERT INTO "ServiceTileMetadata" VALUES(13,'Email:Attachments');
-INSERT INTO "ServiceTileMetadata" VALUES(14,'Email:Sender');
-INSERT INTO "ServiceTileMetadata" VALUES(14,'Email:Subject');
-INSERT INTO "ServiceTileMetadata" VALUES(14,'Email:Date');
-INSERT INTO "ServiceTileMetadata" VALUES(14,'Email:SentTo');
-INSERT INTO "ServiceTileMetadata" VALUES(14,'Email:CC');
-INSERT INTO "ServiceTileMetadata" VALUES(14,'Email:Attachments');
-INSERT INTO "ServiceTileMetadata" VALUES(15,'Email:Sender');
-INSERT INTO "ServiceTileMetadata" VALUES(15,'Email:Subject');
-INSERT INTO "ServiceTileMetadata" VALUES(15,'Email:Date');
-INSERT INTO "ServiceTileMetadata" VALUES(15,'Email:SentTo');
-INSERT INTO "ServiceTileMetadata" VALUES(15,'Email:CC');
-INSERT INTO "ServiceTileMetadata" VALUES(15,'Email:Attachments');
-INSERT INTO "ServiceTileMetadata" VALUES(16,'Email:Sender');
-INSERT INTO "ServiceTileMetadata" VALUES(16,'Email:Subject');
-INSERT INTO "ServiceTileMetadata" VALUES(16,'Email:Date');
-INSERT INTO "ServiceTileMetadata" VALUES(16,'Email:SentTo');
-INSERT INTO "ServiceTileMetadata" VALUES(16,'Email:CC');
-INSERT INTO "ServiceTileMetadata" VALUES(16,'Email:Attachments');
-INSERT INTO "ServiceTileMetadata" VALUES(23,'App:GenericName');
-INSERT INTO "ServiceTileMetadata" VALUES(23,'AppComment');
-INSERT INTO "ServiceTileMetadata" VALUES(23,'App:Categories');
-CREATE TABLE ServiceTabularMetadata
-(
-	ServiceTypeID		Integer not null,
-	MetaName		Text not null,
-
-	primary key (ServiceTypeID, MetaName)
-);
-INSERT INTO "ServiceTabularMetadata" VALUES(4,'File:Name');
-INSERT INTO "ServiceTabularMetadata" VALUES(4,'File:Mime');
-INSERT INTO "ServiceTabularMetadata" VALUES(4,'Doc:Title');
-INSERT INTO "ServiceTabularMetadata" VALUES(4,'Doc:Author');
-INSERT INTO "ServiceTabularMetadata" VALUES(4,'File:Size');
-INSERT INTO "ServiceTabularMetadata" VALUES(4,'File:Modified');
-INSERT INTO "ServiceTabularMetadata" VALUES(4,'Doc:Created');
-INSERT INTO "ServiceTabularMetadata" VALUES(5,'File:Name');
-INSERT INTO "ServiceTabularMetadata" VALUES(5,'File:Mime');
-INSERT INTO "ServiceTabularMetadata" VALUES(5,'Doc:Title');
-INSERT INTO "ServiceTabularMetadata" VALUES(5,'Doc:URL');
-INSERT INTO "ServiceTabularMetadata" VALUES(5,'Doc:Author');
-INSERT INTO "ServiceTabularMetadata" VALUES(5,'File:Size');
-INSERT INTO "ServiceTabularMetadata" VALUES(5,'File:Modified');
-INSERT INTO "ServiceTabularMetadata" VALUES(5,'Doc:Created');
-INSERT INTO "ServiceTabularMetadata" VALUES(6,'File:Name');
-INSERT INTO "ServiceTabularMetadata" VALUES(6,'Image:Height');
-INSERT INTO "ServiceTabularMetadata" VALUES(6,'Image:Width');
-INSERT INTO "ServiceTabularMetadata" VALUES(6,'Image:Date');
-INSERT INTO "ServiceTabularMetadata" VALUES(6,'File:Modified');
-INSERT INTO "ServiceTabularMetadata" VALUES(6,'Image:Creator');
-INSERT INTO "ServiceTabularMetadata" VALUES(6,'Image:Software');
-INSERT INTO "ServiceTabularMetadata" VALUES(7,'Audio:Title');
-INSERT INTO "ServiceTabularMetadata" VALUES(7,'Audio:Artist');
-INSERT INTO "ServiceTabularMetadata" VALUES(7,'Audio:Album');
-INSERT INTO "ServiceTabularMetadata" VALUES(7,'Audio:Genre');
-INSERT INTO "ServiceTabularMetadata" VALUES(7,'Audio:Duration');
-INSERT INTO "ServiceTabularMetadata" VALUES(7,'Audio:ReleaseDate');
-INSERT INTO "ServiceTabularMetadata" VALUES(8,'File:Name');
-INSERT INTO "ServiceTabularMetadata" VALUES(8,'Video:Title');
-INSERT INTO "ServiceTabularMetadata" VALUES(8,'Video:Author');
-INSERT INTO "ServiceTabularMetadata" VALUES(8,'Video:Height');
-INSERT INTO "ServiceTabularMetadata" VALUES(8,'Video:Width');
-INSERT INTO "ServiceTabularMetadata" VALUES(8,'Video:Duration');
-INSERT INTO "ServiceTabularMetadata" VALUES(8,'Video:Bitrate');
-INSERT INTO "ServiceTabularMetadata" VALUES(12,'Email:Sender');
-INSERT INTO "ServiceTabularMetadata" VALUES(12,'Email:Subject');
-INSERT INTO "ServiceTabularMetadata" VALUES(12,'Email:Date');
-INSERT INTO "ServiceTabularMetadata" VALUES(13,'Email:Sender');
-INSERT INTO "ServiceTabularMetadata" VALUES(13,'Email:Subject');
-INSERT INTO "ServiceTabularMetadata" VALUES(13,'Email:Date');
-INSERT INTO "ServiceTabularMetadata" VALUES(14,'Email:Sender');
-INSERT INTO "ServiceTabularMetadata" VALUES(14,'Email:Subject');
-INSERT INTO "ServiceTabularMetadata" VALUES(14,'Email:Date');
-INSERT INTO "ServiceTabularMetadata" VALUES(15,'Email:Sender');
-INSERT INTO "ServiceTabularMetadata" VALUES(15,'Email:Subject');
-INSERT INTO "ServiceTabularMetadata" VALUES(15,'Email:Date');
-INSERT INTO "ServiceTabularMetadata" VALUES(16,'Email:Sender');
-INSERT INTO "ServiceTabularMetadata" VALUES(16,'Email:Subject');
-INSERT INTO "ServiceTabularMetadata" VALUES(16,'Email:Date');
-CREATE TABLE ServiceTypeOptions
-(
-	ServiceTypeID		Integer not null,
-	OptionName		Text not null,
-	OptionValue		Text default ' ',
-
-	primary key (ServiceTypeID, OptionName)
-);
-CREATE TABLE FileMimes
-(
-	Mime			Text primary key not null,
-	ServiceTypeID		Integer default 0,
-	ThumbExec		Text default ' ',
-	MetadataExec		Text default ' ',
-	FullTextExec		Text default ' '
-
-);
-INSERT INTO "FileMimes" VALUES('application/rtf',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/richtext',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/msword',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/pdf',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/postscript',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-dvi',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/vnd.ms-excel',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('vnd.ms-powerpoint',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-abiword',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/html',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/sgml',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-tex',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-mswrite',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-applix-word',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/docbook+xml',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-kword',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-kword-crypt',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-lyx',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/vnd.lotus-1-2-3',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-applix-spreadsheet',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-gnumeric',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-kspread',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-kspread-crypt',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-quattropro',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-sc',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-siag',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-magicpoint',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-kpresenter',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/illustrator',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/vnd.corel-draw',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/vnd.stardivision.draw',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/vnd.oasis.opendocument.graphics',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-dia-diagram',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-karbon',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-killustrator',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-kivio',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-kontour',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-wpg',4,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/vnd.oasis.opendocument.image',6,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-krita',6,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/ogg',7,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/plain',9,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-authors',9,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-changelog',9,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-copying',9,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-credits',9,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-install',9,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-readme',9,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-perl',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-shellscript',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-php',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-java',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-javascript',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-glade',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-csh',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-class-file',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-awk',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-asp',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-ruby',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('application/x-m4',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-m4',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-c++',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-adasrc',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-c',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-c++hdr',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-chdr',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-csharp',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-c++src',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-csrc',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-dcl',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-dsrc',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-emacs-lisp',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-fortran',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-haskell',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-literate-haskell',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-java',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-java-source" ,text/x-makefile',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-objcsrc',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-pascal',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-patch',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-python',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-scheme',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-sql',10,' ',' ',' ');
-INSERT INTO "FileMimes" VALUES('text/x-tcl',10,' ',' ',' ');
-CREATE TABLE FileMimePrefixes
-(
-	MimePrefix		Text primary key not null,
-	ServiceTypeID		Integer default 0,
-	ThumbExec		Text default ' ',
-	MetadataExec		Text default ' ',
-	FullTextExec		Text default ' '
-
-);
-INSERT INTO "FileMimePrefixes" VALUES('application/vnd.oasis.opendocument',4,' ',' ',' ');
-INSERT INTO "FileMimePrefixes" VALUES('application/vnd.sun.xml',4,' ',' ',' ');
-INSERT INTO "FileMimePrefixes" VALUES('application/vnd.stardivision',4,' ',' ',' ');
-INSERT INTO "FileMimePrefixes" VALUES('image/',6,' ',' ',' ');
-INSERT INTO "FileMimePrefixes" VALUES('audio/',7,' ',' ',' ');
-INSERT INTO "FileMimePrefixes" VALUES('video/',8,' ',' ',' ');
-CREATE INDEX BackupMetaDataIndex1 ON BackupMetaData (ServiceID, MetaDataID);
-CREATE INDEX MetaDataTypesIndex1 ON MetaDataTypes (Alias);
-COMMIT;
diff --git a/tests/scripts/data/email-contents.sql b/tests/scripts/data/email-contents.sql
deleted file mode 100644
index 8b13789..0000000
--- a/tests/scripts/data/email-contents.sql
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tests/scripts/data/email-meta.sql b/tests/scripts/data/email-meta.sql
deleted file mode 100644
index a88223c..0000000
--- a/tests/scripts/data/email-meta.sql
+++ /dev/null
@@ -1,67 +0,0 @@
-BEGIN TRANSACTION;
-ANALYZE sqlite_master;
-CREATE TABLE ChildServices
-(
-	ParentID            		Integer not null,
-	ChildID				Integer not null,
-	MetaDataID			Integer not null,
-
-	primary key (ParentID, ChildID, MetaDataID)
-);
-CREATE TABLE ServiceMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer  not null,
-	MetaDataValue     	Text,
-	MetaDataDisplay		Text
-
-);
-DELETE FROM sqlite_sequence;
-CREATE TABLE ServiceKeywordMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer not null,
-	MetaDataValue		Text COLLATE NOCASE
-);
-CREATE TABLE ServiceNumericMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer not null,
-	MetaDataValue		Integer not null
-);
-CREATE TABLE MailSummary
-(
-	ID		Integer primary key AUTOINCREMENT not null,
-	MailApp		Integer not null,
-	MailType	Integer not null,
-	FileName	Text not null,
-	Path		Text not null,
-	UriPrefix	Text,
-	NeedsChecking	Integer default 0,
-	MailCount	Integer,
-	JunkCount	Integer,
-	DeleteCount	Integer,
-	Offset		Integer,
-	LastOffset	Integer,
-	MTime		integer,
-
-	unique (Path)
-);
-CREATE TABLE JunkMail
-(
-	UID			integer not null,
-	SummaryID		Integer not null,
-
-	primary key (UID, SummaryID)
-);
-CREATE INDEX ChildServicesIndex1 ON ChildServices (ChildID);
-CREATE INDEX ServiceMetaDataIndex1 ON ServiceMetaData (ServiceID);
-CREATE INDEX ServiceMetaDataIndex2 ON ServiceMetaData (MetaDataID);
-CREATE INDEX ServiceKeywordMetaDataIndex1 ON ServiceKeywordMetaData (MetaDataID, MetaDataValue);
-CREATE INDEX ServiceKeywordMetaDataIndex2 ON ServiceKeywordMetaData (ServiceID);
-CREATE INDEX ServiceNumericMetaDataIndex1 ON ServiceNumericMetaData (MetaDataID, MetaDataValue);
-CREATE INDEX ServiceNumericMetaDataIndex2 ON ServiceNumericMetaData (ServiceID);
-COMMIT;
diff --git a/tests/scripts/data/file-contents.sql b/tests/scripts/data/file-contents.sql
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/scripts/data/file-meta.sql b/tests/scripts/data/file-meta.sql
deleted file mode 100644
index 5081b73..0000000
--- a/tests/scripts/data/file-meta.sql
+++ /dev/null
@@ -1,42 +0,0 @@
-BEGIN TRANSACTION;
-ANALYZE sqlite_master;
-CREATE TABLE ChildServices
-(
-	ParentID            		Integer not null,
-	ChildID				Integer not null,
-	MetaDataID			Integer not null,
-
-	primary key (ParentID, ChildID, MetaDataID)
-);
-CREATE TABLE ServiceMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer  not null,
-	MetaDataValue     	Text,
-	MetaDataDisplay		Text
-
-);
-DELETE FROM sqlite_sequence;
-CREATE TABLE ServiceKeywordMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer not null,
-	MetaDataValue		Text COLLATE NOCASE
-);
-CREATE TABLE ServiceNumericMetaData 
-(
-	ID			Integer primary key AUTOINCREMENT not null,
-	ServiceID		Integer not null,
-	MetaDataID 		Integer not null,
-	MetaDataValue		Integer not null
-);
-CREATE INDEX ChildServicesIndex1 ON ChildServices (ChildID);
-CREATE INDEX ServiceMetaDataIndex1 ON ServiceMetaData (ServiceID);
-CREATE INDEX ServiceMetaDataIndex2 ON ServiceMetaData (MetaDataID);
-CREATE INDEX ServiceKeywordMetaDataIndex1 ON ServiceKeywordMetaData (MetaDataID, MetaDataValue);
-CREATE INDEX ServiceKeywordMetaDataIndex2 ON ServiceKeywordMetaData (ServiceID);
-CREATE INDEX ServiceNumericMetaDataIndex1 ON ServiceNumericMetaData (MetaDataID, MetaDataValue);
-CREATE INDEX ServiceNumericMetaDataIndex2 ON ServiceNumericMetaData (ServiceID);
-COMMIT;
diff --git a/tests/scripts/dummy_data_start.sh.in b/tests/scripts/dummy_data_start.sh.in
deleted file mode 100755
index 149b599..0000000
--- a/tests/scripts/dummy_data_start.sh.in
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /bin/sh
-
-SCRIPTS_DIR= top_srcdir@/tests/scripts
-SQLITE_EXEC= sqlite_exec@
-
-. $SCRIPTS_DIR/xdg_dirs.source
-
-mkdir -p $XDG_CACHE_HOME/tracker
-
-echo -n Creating   
-
-#
-## file-metadata.db
-#
-
-echo -n file-metadata.db, 
-
-$SQLITE_EXEC $XDG_CACHE_HOME/tracker/file-meta.db < $SCRIPTS_DIR/data/file-meta.sql
-
-#
-## file-contents.db
-#
-
-echo -n file-contents.db, 
-
-$SQLITE_EXEC $XDG_CACHE_HOME/tracker/file-contents.db < $SCRIPTS_DIR/data/file-contents.sql
-
-#
-## email-meta.db
-#
-
-echo -n email-meta.db, 
-
-$SQLITE_EXEC $XDG_CACHE_HOME/tracker/email-meta.db < $SCRIPTS_DIR/data/email-meta.sql
-
-#
-## email-contents.db
-#
-
-echo -n email-contents.db, 
-
-$SQLITE_EXEC $XDG_CACHE_HOME/tracker/email-contents.db < $SCRIPTS_DIR/data/email-contents.sql
-
-
-mkdir -p $XDG_DATA_HOME/tracker/data
-
-#
-## common.db
-#
-
-echo -n common.db, 
-
-$SQLITE_EXEC $XDG_DATA_HOME/tracker/data/common.db < $SCRIPTS_DIR/data/common.sql
-
-
-#
-## cache.db
-#
-
-echo cache.db .. done
-
-# Done by trackerd or tracker-indexer
-
diff --git a/tests/scripts/dummy_data_stop.sh.in b/tests/scripts/dummy_data_stop.sh.in
deleted file mode 100755
index 3f4aa81..0000000
--- a/tests/scripts/dummy_data_stop.sh.in
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /bin/sh
-
-SCRIPTS_DIR= top_srcdir@/tests/scripts
-
-. $SCRIPTS_DIR/xdg_dirs.source
-
-rm -rf $XDG_CACHE_HOME/tracker
-rm -rf $XDG_DATA_HOME/tracker
-
-. $SCRIPTS_DIR/xdg_dirs.unsource
-
diff --git a/tests/scripts/testing.txt b/tests/scripts/testing.txt
deleted file mode 100644
index b9d4bfb..0000000
--- a/tests/scripts/testing.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-./dummy_data_stop.sh
-./dummy_data_start
-source xdg_dirs.source
-
-run trackerd
-run cd /tmp/Tracker-test/.cache/
-run sqlite3 xesam.db
-run pidof trackerd
-$PID appears
-
-sqlite3> prompt appears
-ATTACH './email-meta.db' as 'email-meta';
-ATTACH './file-meta.db' as 'file-meta';
-ATTACH '../../.local/share/tracker/data/common.db' as 'common';
-ATTACH '/tmp/Tracker-pvanhoof.$PID/cache.db' as 'cache';
-
-./dummy_data_stop.sh
-
-
diff --git a/tests/scripts/xdg_dirs.source b/tests/scripts/xdg_dirs.source
deleted file mode 100644
index 5678f6e..0000000
--- a/tests/scripts/xdg_dirs.source
+++ /dev/null
@@ -1,2 +0,0 @@
-export XDG_CACHE_HOME=/tmp/Tracker-test/.cache
-export XDG_DATA_HOME=/tmp/Tracker-test/.local/share
diff --git a/tests/scripts/xdg_dirs.unsource b/tests/scripts/xdg_dirs.unsource
deleted file mode 100644
index c16a852..0000000
--- a/tests/scripts/xdg_dirs.unsource
+++ /dev/null
@@ -1,2 +0,0 @@
-export XDG_CACHE_HOME=
-export XDG_DATA_HOME=
diff --git a/tests/tracker-extract/Makefile.am b/tests/tracker-extract/Makefile.am
index b5b9c48..10f4f51 100644
--- a/tests/tracker-extract/Makefile.am
+++ b/tests/tracker-extract/Makefile.am
@@ -1,27 +1,27 @@
 include $(top_srcdir)/Makefile.decl
 
-modulesdir = $(libdir)/tracker/extract-modules
+modulesdir = $(libdir)/tracker-$(TRACKER_API_VERSION)/extract-modules
 
 noinst_PROGRAMS = $(TEST_PROGS)
 
-TEST_PROGS += 								\
-	test-tracker-extract-mp3					\
-	test-tracker-extract-png
+# TEST_PROGS += 								\
+# 	test-tracker-extract-mp3					\
+# 	test-tracker-extract-png
 
-if HAVE_GSTREAMER
-TEST_PROGS += 								\
-	test-tracker-extract-gstreamer
-endif
+# if HAVE_GSTREAMER
+# TEST_PROGS += 								\
+# 	test-tracker-extract-gstreamer
+# endif
 
-if HAVE_LIBJPEG
-TEST_PROGS += 								\
-	test-tracker-extract-jpeg
-endif
+# if HAVE_LIBJPEG
+# TEST_PROGS += 								\
+# 	test-tracker-extract-jpeg
+# endif
 
-if HAVE_LIBTIFF
-TEST_PROGS +=								\
-	test-tracker-extract-tiff
-endif
+# if HAVE_LIBTIFF
+# TEST_PROGS +=								\
+# 	test-tracker-extract-tiff
+# endif
 
 INCLUDES = 								\
 	-DG_LOG_DOMAIN=\"Tracker\"					\
diff --git a/tests/tracker-extract/tracker-extract-jpeg-test.c b/tests/tracker-extract/tracker-extract-jpeg-test.c
index eb10573..7561a41 100644
--- a/tests/tracker-extract/tracker-extract-jpeg-test.c
+++ b/tests/tracker-extract/tracker-extract-jpeg-test.c
@@ -65,10 +65,11 @@ main (int argc, char **argv) {
 	g_test_add_data_func ("/tracker-extract/tracker-extract-jpeg/exif_tags",
 			      data, test_tracker_extract_jpeg_exif_tags);
 
+	/*
 	if (g_test_perf()) {
 		g_test_add_data_func ("/tracker-extract/tracker-extract-jpeg/performance",
 				      data, test_tracker_extract_jpeg_performance);
-	}
+	}*/
 
 #endif
 
diff --git a/tests/tracker-extract/tracker-extract-mp3-test.c b/tests/tracker-extract/tracker-extract-mp3-test.c
index 3d7b48e..ef54562 100644
--- a/tests/tracker-extract/tracker-extract-mp3-test.c
+++ b/tests/tracker-extract/tracker-extract-mp3-test.c
@@ -53,8 +53,6 @@ main (int argc, char **argv) {
 	g_test_add_data_func ("/tracker-extract/tracker-extract-mp3/access",
 			      data, test_tracker_extract_mp3_access);	
 
-#if 1
-
 	g_test_add_data_func ("/tracker-extract/tracker-extract-mp3/id3v1_basic",
 			      data, test_tracker_extract_mp3_id3v1_basic);
 	g_test_add_data_func ("/tracker-extract/tracker-extract-mp3/id3v23_basic",
@@ -74,8 +72,6 @@ main (int argc, char **argv) {
 				      data, test_tracker_extract_mp3_performance);	
 	}
 
-#endif
-
 	result = g_test_run ();
 
 	return result;
diff --git a/tests/tracker-extract/tracker-extract-png-test.c b/tests/tracker-extract/tracker-extract-png-test.c
index 0b3b322..9095792 100644
--- a/tests/tracker-extract/tracker-extract-png-test.c
+++ b/tests/tracker-extract/tracker-extract-png-test.c
@@ -49,20 +49,16 @@ main (int argc, char **argv) {
 	g_test_add_data_func ("/tracker-extract/tracker-extract-png/check-extract-data",
 			      data, test_tracker_extract_check_extract_data);
 
-#if 0
 	g_test_add_data_func ("/tracker-extract/tracker-extract-png/basic_size",
 			      data, test_tracker_extract_png_basic_size);
 
 /* 	g_test_add_data_func ("/tracker-extract/tracker-extract-png/xmp_exif_orientation", */
 /* 			      data, test_tracker_extract_png_xmp_exif_orientation); */
 
-	if (g_test_perf()) {
+/*	if (g_test_perf()) {
 		g_test_add_data_func ("/tracker-extract/tracker-extract-png/performance",
 				      data, performance_tracker_extract_png);
-	}
-
-#endif
-
+	}*/
 
 	result = g_test_run ();
 
diff --git a/tests/tracker-extract/tracker-extract-test-utils.c b/tests/tracker-extract/tracker-extract-test-utils.c
index ba3cdd5..c524fdd 100644
--- a/tests/tracker-extract/tracker-extract-test-utils.c
+++ b/tests/tracker-extract/tracker-extract-test-utils.c
@@ -20,7 +20,9 @@
 
 #include <unistd.h>
 
+#include <glib.h>
 #include <glib/gstdio.h>
+#include <glib-object.h>
 #include <gmodule.h>
 
 #include "tracker-extract-test-utils.h"
@@ -108,9 +110,8 @@ parse_file (const gchar *filename)
 }
 
 static void
-dump_metadata_item (gpointer key,
-		    gpointer value,
-		    gpointer user_data)
+dump_metadata_item (const gchar *key,
+		    const gchar *value)
 {
 	gchar *value_utf8;
 
@@ -126,26 +127,56 @@ dump_metadata_item (gpointer key,
 }
 
 static void
-dump_metadata (GHashTable *metadata)
+dump_metadata (GPtrArray *metadata)
 {
+	guint i;
+
 	g_assert (metadata != NULL);
-	g_hash_table_foreach (metadata, dump_metadata_item, NULL);
+
+	for (i = 0; i < metadata->len; i++) {
+		GValueArray *statement;
+		const gchar *subject;
+		const gchar *predicate;
+		const gchar *object;
+
+		statement = metadata->pdata[i];
+		subject = g_value_get_string (&statement->values[0]);
+		predicate = g_value_get_string (&statement->values[1]);
+		object = g_value_get_string (&statement->values[2]);
+
+		dump_metadata_item (predicate, object);
+	}
 }
 
 static void
-check_metadata (GHashTable  *metadata, 
-		const gchar *key, 
+check_metadata (GPtrArray   *metadata,
+		const gchar *key,
 		const gchar *value)
 {
-	gchar *cvalue;
+	GValueArray *statement;
+	const gchar *subject, *predicate, *object;
+	gboolean found = FALSE;
+	guint i;
 
 	g_assert (metadata != NULL);
 	g_assert (key != NULL);
 	g_assert (value != NULL);
-	
-	cvalue = g_hash_table_lookup (metadata, key);
-	g_assert (cvalue != NULL);
-	g_assert_cmpstr (cvalue, ==, value);
+
+	for (i = 0; i < metadata->len; i++) {
+		statement = metadata->pdata[i];
+		subject = g_value_get_string (&statement->values[0]);
+		predicate = g_value_get_string (&statement->values[1]);
+		object = g_value_get_string (&statement->values[2]);
+
+		if (g_strcmp0 (key, predicate) == 0) {
+			found = TRUE;
+			break;
+		}
+	}
+
+	g_assert (found);
+	g_assert (object != NULL);
+	g_assert_cmpstr (value, ==, object);
 }
 
 TrackerExtractData *
@@ -200,15 +231,30 @@ tracker_test_extract_get_extract (const gchar *path, const gchar *mime)
 	return NULL;
 }
 
+static void 
+free_statements (GPtrArray *metadata)
+{
+	guint i;
+
+	for (i = 0; i < metadata->len; i++) {
+		GValueArray *statement;
+		statement = metadata->pdata[i];
+		g_value_array_free (statement);
+	}
+
+	g_ptr_array_free (metadata, TRUE);
+}
+
 void
 tracker_test_extract_file (const TrackerExtractData *data, 
 			   const gchar              *file, 
 			   const gchar              *test_data_file)
 {
-	GHashTable *metadata;
+	GPtrArray  *metadata;
 	GHashTable *test_data;
-	gchar *filename;	
-	gchar *test_data_filename;
+	gchar      *filename, *uri;
+	gchar      *test_data_filename;
+
 	GHashTableIter iter;
 	gpointer key, value;
 
@@ -219,12 +265,11 @@ tracker_test_extract_file (const TrackerExtractData *data,
 	filename = g_strconcat (TEST_DATA_DIR, file, NULL);
 	test_data_filename = g_strconcat (TEST_DATA_DIR, test_data_file, NULL);
 
-	metadata = g_hash_table_new_full (g_str_hash,
-					  g_str_equal,
-					  g_free,
-					  g_free);
+	metadata = g_ptr_array_new ();
 
-	(*data->extract) (filename, metadata);
+	uri = g_filename_to_uri (filename, NULL, NULL);
+	(*data->extract) (uri, metadata);
+	g_free (uri);
 
 	test_data = parse_file (test_data_filename);
 
@@ -238,7 +283,8 @@ tracker_test_extract_file (const TrackerExtractData *data,
 		check_metadata (metadata, key, value);
 	}
 
-	g_hash_table_destroy (metadata);
+	free_statements (metadata);
+
 	g_hash_table_destroy (test_data);
 }
 
@@ -257,16 +303,11 @@ tracker_test_extract_file_performance (const TrackerExtractData *data,
 	g_test_timer_start ();
 
 	for (i = 1; i <= file_count; i++) {
-		GHashTable *metadata;
-		gchar filename[256];
+		GPtrArray *metadata;
+		gchar filename[256], *uri;
 		gchar tmp[256];
 
-		metadata = g_hash_table_new_full (g_str_hash,
-						  g_str_equal,
-						  g_free,
-						  g_free);
-
-		
+		metadata = g_ptr_array_new ();
 
 		if (sprintf (tmp, "%s%s",TEST_DATA_DIR, file_match) < 0) {
 			g_assert_not_reached();
@@ -276,12 +317,15 @@ tracker_test_extract_file_performance (const TrackerExtractData *data,
 			g_assert_not_reached();
 		}
 
-		(*data->extract) (filename, metadata);
+		uri = g_filename_to_uri (filename, NULL, NULL);
+		(*data->extract) (uri, metadata);
+		g_free (uri);
+		
+		g_assert (metadata->len > 0);
 
-		g_assert (g_hash_table_size (metadata) > 0);
+		free_statements (metadata);
 
-		g_hash_table_destroy (metadata);
-	}		
+	}
 
 	perftime = g_test_timer_elapsed();
 
@@ -302,29 +346,29 @@ tracker_test_extract_file_access (const TrackerExtractData *data,
 	g_assert (file_count > 0);
 	
 	for (i = 1; i <= file_count; i++) {
-		GHashTable *metadata;
+		gchar *uri;
+		GPtrArray *metadata;
 		gchar filename[256];
 		gchar tmp[256];
 
-		metadata = g_hash_table_new_full (g_str_hash,
-						  g_str_equal,
-						  g_free,
-						  g_free);
+		metadata = g_ptr_array_new ();
 
-		if (sprintf (tmp, "%s%s", TEST_DATA_DIR, file_match) < 0) {
-			g_assert_not_reached ();
+		if (sprintf (tmp, "%s%s",TEST_DATA_DIR, file_match) < 0) {
+			g_assert_not_reached();
 		}
 
 		if (sprintf (filename, tmp, i) < 0) {
 			g_assert_not_reached ();
 		}
 
-		(*data->extract) (filename, metadata);
+		uri = g_filename_to_uri (filename, NULL, NULL);
+		(*data->extract) (uri, metadata);
+		g_free (uri);
 
-		g_assert (g_hash_table_size (metadata) > 0);
+		g_assert (metadata->len > 0);
 
-		g_hash_table_destroy (metadata);
-	}		
+		free_statements (metadata);
+	}
 }
 
 /* This is added because tracker-main.c includes this file and so
@@ -335,3 +379,5 @@ tracker_main_get_hal (void)
 {
 	return NULL;
 }
+
+
diff --git a/utils/qdbm/print-words.c b/utils/qdbm/print-words.c
index 44c7c7d..f32fb22 100644
--- a/utils/qdbm/print-words.c
+++ b/utils/qdbm/print-words.c
@@ -100,9 +100,8 @@ load_terms_from_index (gchar *filename)
 	    if (print_services) {
 		    results = get_word_hits (depot, key, &hits);
 		    for (i = 0; i < hits; i++) {
-			    g_print (" (id:%d  t:%d s:%d) ",
+			    g_print (" (id:%d  s:%d) ",
 				     tracker_db_index_item_get_id (&results[i]),
-				     tracker_db_index_item_get_service_type (&results[i]),
 				     tracker_db_index_item_get_score (&results[i]));
 		    }
 	    }
diff --git a/utils/qdbm/search-word.c b/utils/qdbm/search-word.c
index 45e9dc6..9fb8913 100644
--- a/utils/qdbm/search-word.c
+++ b/utils/qdbm/search-word.c
@@ -100,9 +100,8 @@ show_term_in_index (const gchar *filename,
     g_print (" - %s ", word);
 
     for (i = 0; i < hits; i++) {
-	    g_print (" (id:%d  t:%d) ",
-		     items[i].id,
-		     tracker_db_index_item_get_service_type (&items[i]));
+	    g_print (" (id:%d) ",
+		     items[i].id);
     }
 
     g_print ("\n");



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