[nautilus-actions] Able to import a pre-v2 action



commit d721ebddc1d4c237417ec07e2ff9a877b64d73ec
Author: Pierre Wieser <pwieser trychlos org>
Date:   Wed Feb 24 00:58:54 2010 +0100

    Able to import a pre-v2 action

 ChangeLog                                          |   48 +
 exports/config_11111111_action_v1.schemas          |  164 +++
 src/api/Makefile.am                                |    6 +-
 src/api/na-data-boxed.h                            |   97 ++
 .../{na-ifactory-object-str.h => na-data-def.h}    |   82 +-
 .../{na-ifactory-object-enum.h => na-data-types.h} |   68 +-
 src/api/na-gconf-utils.h                           |    2 +
 src/api/na-ifactory-object-data.h                  |   89 ++
 src/api/na-ifactory-object.h                       |   59 +-
 src/api/na-ifactory-provider.h                     |   44 +-
 src/api/na-iimporter.h                             |   37 +-
 src/api/na-object-api.h                            |  124 +-
 src/api/na-object-profile.h                        |    6 +-
 src/core/Makefile.am                               |   14 +-
 src/core/na-data-boxed.c                           | 1165 ++++++++++++++++++++
 src/core/na-data-element.c                         | 1051 ------------------
 src/core/na-data-element.h                         |   91 --
 src/core/na-factory-object.c                       | 1043 +++++++++++-------
 src/core/na-factory-object.h                       |   45 +-
 src/core/na-factory-provider.c                     |  147 +---
 src/core/na-factory-provider.h                     |   11 +-
 src/core/na-gconf-utils.c                          |   37 +
 src/core/na-ifactory-object.c                      |  123 ++-
 src/core/na-ifactory-provider-priv.h               |   61 -
 src/core/na-ifactory-provider.c                    |   83 +-
 src/core/na-importer.c                             |   37 +-
 src/core/na-importer.h                             |    2 +-
 src/core/na-io-provider.c                          |    2 +-
 src/core/na-object-action-enum.c                   |  154 ---
 src/core/na-object-action-factory.c                |  294 +++++
 src/core/na-object-action.c                        |  135 ++-
 ...{na-object-id-enum.c => na-object-id-factory.c} |   33 +-
 ...object-item-enum.c => na-object-item-factory.c} |   81 +-
 ...object-menu-enum.c => na-object-menu-factory.c} |   23 +-
 src/core/na-object-menu.c                          |   77 +-
 ...-profile-enum.c => na-object-profile-factory.c} |   99 +-
 src/core/na-object-profile.c                       |  123 ++-
 src/io-desktop/nadp-desktop-file.c                 |   95 ++-
 src/io-desktop/nadp-desktop-file.h                 |    9 +-
 src/io-desktop/nadp-desktop-provider.c             |  118 ++-
 src/io-desktop/nadp-keys.c                         |   16 +-
 src/io-desktop/nadp-keys.h                         |    6 +-
 src/io-desktop/nadp-reader.c                       |   24 +-
 src/io-gconf/nagp-gconf-provider.c                 |    4 +-
 src/io-xml/naxml-keys.h                            |   12 +-
 src/io-xml/naxml-provider.c                        |    8 +-
 src/io-xml/naxml-reader.c                          |  953 ++++++++++-------
 src/io-xml/naxml-reader.h                          |   16 +-
 src/nact/nact-assistant-import.c                   |   25 +-
 src/nact/nact-tree-model-dnd.c                     |   37 +-
 src/test/test-include.c                            |    2 +-
 src/test/test-reader.c                             |  141 +++-
 52 files changed, 4180 insertions(+), 3043 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7cb3a82..9eda59c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+2009-02-24 Pierre Wieser <pwieser trychlos org>
+
+	* src/api/Makefile.am:
+	* src/api/na-data-boxed.h:
+	* src/api/na-data-types.h:
+	* src/api/na-gconf-utils.h:
+	* src/api/na-ifactory-object-data.h:
+	* src/api/na-ifactory-object.h:
+	* src/api/na-ifactory-provider.h:
+	* src/api/na-iimporter.h:
+	* src/api/na-object-api.h:
+	* src/api/na-object-profile.h:
+	* src/core/Makefile.am:
+	* src/core/na-data-boxed.c:
+	* src/core/na-factory-object.c:
+	* src/core/na-factory-object.h:
+	* src/core/na-factory-provider.c:
+	* src/core/na-factory-provider.h:
+	* src/core/na-gconf-utils.c:
+	* src/core/na-ifactory-object.c:
+	* src/core/na-ifactory-provider.c:
+	* src/core/na-importer.c:
+	* src/core/na-importer.h:
+	* src/core/na-io-provider.c:
+	* src/core/na-object-action-factory.c:
+	* src/core/na-object-action.c:
+	* src/core/na-object-id-factory.c:
+	* src/core/na-object-item-factory.c:
+	* src/core/na-object-menu-factory.c:
+	* src/core/na-object-menu.c:
+	* src/core/na-object-profile-factory.c:
+	* src/core/na-object-profile.c:
+	* src/io-desktop/nadp-desktop-file.c:
+	* src/io-desktop/nadp-desktop-file.h:
+	* src/io-desktop/nadp-desktop-provider.c:
+	* src/io-desktop/nadp-keys.c:
+	* src/io-desktop/nadp-keys.h:
+	* src/io-desktop/nadp-reader.c:
+	* src/io-gconf/nagp-gconf-provider.c:
+	* src/io-xml/naxml-keys.h:
+	* src/io-xml/naxml-provider.c:
+	* src/io-xml/naxml-reader.c:
+	* src/io-xml/naxml-reader.h:
+	* src/nact/nact-assistant-import.c:
+	* src/nact/nact-tree-model-dnd.c:
+	* src/test/test-include.c:
+	* src/test/test-reader.c: Able to import a pre-v2 action.
+
 2009-02-22 Pierre Wieser <pwieser trychlos org>
 
 	* src/api/Makefile.am:
diff --git a/exports/config_11111111_action_v1.schemas b/exports/config_11111111_action_v1.schemas
new file mode 100644
index 0000000..1ab1ace
--- /dev/null
+++ b/exports/config_11111111_action_v1.schemas
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gconfschemafile>
+  <schemalist>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/version</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/version</applyto>
+      <type>string</type>
+      <locale name="C">
+        <short>The version of the configuration format</short>
+        <long>The version of the configuration format that will be used to manage backward compatibility</long>
+      </locale>
+      <default>1.0</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/label</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/label</applyto>
+      <type>string</type>
+      <locale name="C">
+        <default>Action version 1.0</default>
+        <short>The label of the menu item</short>
+        <long>The label of the menu item that will appear in the Nautilus popup menu when the selection matches the appearance condition settings</long>
+      </locale>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/tooltip</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/tooltip</applyto>
+      <type>string</type>
+      <locale name="C">
+        <default>Let us test read/import/export/NACT v1.0 action</default>
+        <short>The tooltip of the menu item</short>
+        <long>The tooltip of the menu item that will appear in the Nautilus statusbar when the user points to the Nautilus popup menu item with his/her mouse</long>
+      </locale>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/icon</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/icon</applyto>
+      <type>string</type>
+      <locale name="C">
+        <short>The icon of the menu item</short>
+        <long>The icon of the menu item that will appear next to the label in the Nautilus popup menu when the selection matches the appearance conditions settings</long>
+      </locale>
+      <default>gtk-justify-center</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/path</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/path</applyto>
+      <type>string</type>
+      <locale name="C">
+        <short>The path of the command</short>
+        <long>The path of the command to start when the user select the menu item in the Nautilus popup menu</long>
+      </locale>
+      <default>/bin/ls</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/parameters</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/parameters</applyto>
+      <type>string</type>
+      <locale name="C">
+        <short>The parameters of the command</short>
+        <long>The parameters of the command to start when the user selects the menu item in the Nautilus popup menu.
+
+The parameters can contain some special tokens which are replaced by Nautilus information before starting the command:
+
+%d: base folder of the selected file(s)
+%f: the name of the selected file or the first one if many are selected
+%h: hostname of the URI
+%m: space-separated list of the basenames of the selected file(s)/folder(s)
+%M: space-separated list of the selected file(s)/folder(s), with their full paths
+%s: scheme of the URI
+%u: URI
+%U: username of the URI
+%%: a percent sign</long>
+      </locale>
+      <default>%h %M</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/basenames</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/basenames</applyto>
+      <type>list</type>
+      <list_type>string</list_type>
+      <locale name="C">
+        <short>The list of pattern to match the selected file(s)/folder(s)</short>
+        <long>A list of strings with joker '*' or '?' to match the name of the selected file(s)/folder(s). Each selected items must match at least one of the filename patterns for the action to appear</long>
+      </locale>
+      <default>[*.c]</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/isfile</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/isfile</applyto>
+      <type>bool</type>
+      <locale name="C">
+        <short>'true' if the selection can have files, 'false' otherwise</short>
+        <long>This setting is tied in with the 'isdir' setting. The valid combinations are:
+
+isfile=TRUE and isdir=FALSE: the selection may hold only files
+isfile=FALSE and isdir=TRUE: the selection may hold only folders
+isfile=TRUE and isdir=TRUE: the selection may hold both files and folders
+isfile=FALSE and isdir=FALSE: this is an invalid combination (your configuration will never appear)</long>
+      </locale>
+      <default>true</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/isdir</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/isdir</applyto>
+      <type>bool</type>
+      <locale name="C">
+        <short>'true' if the selection can have folders, 'false' otherwise</short>
+        <long>This setting is tied in with the 'isfile' setting. The valid combinations are:
+
+isfile=TRUE and isdir=FALSE: the selection may hold only files
+isfile=FALSE and isdir=TRUE: the selection may hold only folders
+isfile=TRUE and isdir=TRUE: the selection may hold both files and folders
+isfile=FALSE and isdir=FALSE: this is an invalid combination (your configuration will never appear)</long>
+      </locale>
+      <default>false</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/accept-multiple-files</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/accept-multiple-files</applyto>
+      <type>bool</type>
+      <locale name="C">
+        <short>'true' if the selection can have several items, 'false' otherwise</short>
+        <long>If you need one or more files or folders to be selected, set this key to 'true'. If you want just one file or folder, set 'false'</long>
+      </locale>
+      <default>false</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/11111111/schemes</key>
+      <applyto>/apps/nautilus-actions/configurations/11111111/schemes</applyto>
+      <type>list</type>
+      <list_type>string</list_type>
+      <locale name="C">
+        <short>The list of schemes where the selected files should be located</short>
+        <long>Defines the list of valid schemes to be matched against the selected items. The scheme is the protocol used to access the files. The keyword to use is the one used in the URI.
+
+Examples of valid URI include:
+file:///tmp/foo.txt
+sftp:///root test example net/tmp/foo.txt
+
+The most common schemes are:
+
+'file': local files
+'sftp': files accessed via SSH
+'ftp': files accessed via FTP
+'smb': files accessed via Samba (Windows share)
+'dav': files accessed via WebDAV
+
+All schemes used by Nautilus can be used here.</long>
+      </locale>
+      <default>[smb]</default>
+      <owner>nautilus-actions</owner>
+    </schema>
+  </schemalist>
+</gconfschemafile>
diff --git a/src/api/Makefile.am b/src/api/Makefile.am
index 5a6773e..83a4ecf 100644
--- a/src/api/Makefile.am
+++ b/src/api/Makefile.am
@@ -39,12 +39,14 @@ api_include_HEADERS = \
 	na-iio-provider.h									\
 	\
 	na-core-utils.h										\
+	na-data-boxed.h										\
+	na-data-def.h										\
+	na-data-types.h										\
 	na-gconf-monitor.h									\
 	na-gconf-utils.h									\
 	na-iduplicable.h									\
 	na-ifactory-object.h								\
-	na-ifactory-object-enum.h							\
-	na-ifactory-object-str.h							\
+	na-ifactory-object-data.h							\
 	na-object-api.h										\
 	na-object.h											\
 	na-object-id.h										\
diff --git a/src/api/na-data-boxed.h b/src/api/na-data-boxed.h
new file mode 100644
index 0000000..86fe815
--- /dev/null
+++ b/src/api/na-data-boxed.h
@@ -0,0 +1,97 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NAUTILUS_ACTIONS_API_NA_DATA_BOXED_H__
+#define __NAUTILUS_ACTIONS_API_NA_DATA_BOXED_H__
+
+/**
+ * SECTION: na_data_boxed
+ * @short_description: #NADataBoxed class definition.
+ * @include: core/na-data-boxed.h
+ *
+ * The object which encapsulates an elementary data of #NAIFactoryObject.
+ * A #NADataBoxed object has a type and a value.
+ */
+
+#include <glib-object.h>
+
+#include "na-data-def.h"
+
+G_BEGIN_DECLS
+
+#define NA_DATA_BOXED_TYPE					( na_data_boxed_get_type())
+#define NA_DATA_BOXED( object )				( G_TYPE_CHECK_INSTANCE_CAST( object, NA_DATA_BOXED_TYPE, NADataBoxed ))
+#define NA_DATA_BOXED_CLASS( klass )		( G_TYPE_CHECK_CLASS_CAST( klass, NA_DATA_BOXED_TYPE, NADataBoxedClass ))
+#define NA_IS_DATA_BOXED( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NA_DATA_BOXED_TYPE ))
+#define NA_IS_DATA_BOXED_CLASS( klass )		( G_TYPE_CHECK_CLASS_TYPE(( klass ), NA_DATA_BOXED_TYPE ))
+#define NA_DATA_BOXED_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), NA_DATA_BOXED_TYPE, NADataBoxedClass ))
+
+typedef struct NADataBoxedPrivate      NADataBoxedPrivate;
+
+typedef struct {
+	GObject             parent;
+	NADataBoxedPrivate *private;
+}
+	NADataBoxed;
+
+typedef struct NADataBoxedClassPrivate NADataBoxedClassPrivate;
+
+typedef struct {
+	GObjectClass             parent;
+	NADataBoxedClassPrivate *private;
+}
+	NADataBoxedClass;
+
+GType        na_data_boxed_get_type( void );
+
+GParamSpec  *na_data_boxed_get_param_spec ( const NADataDef *def );
+
+NADataBoxed *na_data_boxed_new            ( const NADataDef *def );
+
+NADataDef   *na_data_boxed_get_data_def   ( const NADataBoxed *boxed );
+gboolean     na_data_boxed_are_equal      ( const NADataBoxed *a, const NADataBoxed *b );
+gboolean     na_data_boxed_is_valid       ( const NADataBoxed *boxed );
+void         na_data_boxed_dump           ( const NADataBoxed *boxed );
+
+void        *na_data_boxed_get_as_void    ( const NADataBoxed *boxed );
+void         na_data_boxed_get_as_value   ( const NADataBoxed *boxed, GValue *value );
+
+void         na_data_boxed_set_default    ( NADataBoxed *boxed );
+void         na_data_boxed_set_from_boxed ( NADataBoxed *boxed, const NADataBoxed *value );
+void         na_data_boxed_set_from_value ( NADataBoxed *boxed, const GValue *value );
+void         na_data_boxed_set_from_void  ( NADataBoxed *boxed, const void *value );
+
+/* -- */
+
+void         na_data_boxed_set_from_string( NADataBoxed *boxed, const gchar *value );
+
+G_END_DECLS
+
+#endif /* __NAUTILUS_ACTIONS_API_NA_DATA_BOXED_H__ */
diff --git a/src/api/na-ifactory-object-str.h b/src/api/na-data-def.h
similarity index 59%
rename from src/api/na-ifactory-object-str.h
rename to src/api/na-data-def.h
index fdf6147..0dc843d 100644
--- a/src/api/na-ifactory-object-str.h
+++ b/src/api/na-data-def.h
@@ -28,8 +28,8 @@
  *   ... and many others (see AUTHORS)
  */
 
-#ifndef __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_STR_H__
-#define __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_STR_H__
+#ifndef __NAUTILUS_ACTIONS_API_NA_FACTORY_DATA_DEF_H__
+#define __NAUTILUS_ACTIONS_API_NA_FACTORY_DATA_DEF_H__
 
 /**
  * SECTION: na_ifactory_object
@@ -42,63 +42,29 @@
 G_BEGIN_DECLS
 
 /**
- * Elementary data types
- * Each object data item must be typed as one of these
- * IFactoryProvider implementations should provide a primitive for reading
- * (resp. writing) a value for each of these elementary data types.
- *
- * IMPORTANT NOTE
- * Please note that this enumeration may  be compiled in by extensions.
- * They must so remain fixed, unless you want see strange effects (e.g.
- * an extension has been compiled with NADF_TYPE_STRING = 2, while you
- * have inserted another element, making it to 3 !) - or you know what
- * you are doing...
- */
-
-enum {
-	NADF_TYPE_STRING = 1,				/* an ASCII string */
-
-	NADF_TYPE_LOCALE_STRING,			/* a localized UTF-8 string */
-
-	NADF_TYPE_BOOLEAN,					/* a boolean
-										 * can be initialized with "true" or "false" (case insensitive) */
-
-	NADF_TYPE_STRING_LIST,				/* a list of ASCII strings */
-
-	NADF_TYPE_POINTER,					/* a ( void * ) pointer
-										 * should be initialized to NULL */
-
-	NADF_TYPE_UINT,						/* an unsigned integer */
-};
-
-/* attach here a xml document root with the corresponding node for the data
- */
-typedef struct {
-	gchar *doc_id;
-	gchar *key;
-}
-	NadfDocKey;
-
-/**
- * The structure which fully describe an elementary data
+ * The structure which fully describes an elementary factory data
  * Each #NAIFactoryObject item definition may include several groups of
  * this structure
  */
 typedef struct {
-	guint     id;						/* the id of the object data item
-										 * must only be unique inside of the given group */
-
-	gchar    *name;						/* canonical name, used when getting/setting properties */
+	gchar    *name;						/* both the id and the canonical name
+										 * used when getting/setting properties
+										 * must be globally unique
+										 * must also be an invariant as it is known from plugin extensions */
 
 	gboolean  serializable;				/* whether the data is serializable
 										 * if FALSE, then no attempt will be made to read/write it
-										 * and the data will must be set dynamically */
+										 * and the data will must be set dynamically
+										 * when a data has been set serializable once, it remains so
+										 * even if it has becomen obsolete (for backward compatibility) */
 
-	gchar    *short_label;				/* short descriptive name, used in GParamSpec */
+	gchar    *short_label;				/* short descriptive name
+										 * used in GParamSpec and in schemas */
 
-	gchar    *long_label;				/* long, if not complete, description, used in GParamSpec */
+	gchar    *long_label;				/* long, if not complete, description
+										 * used in GParamSpec and in schemas */
 
-	guint     type;						/* the elementary NADF_TYPE_xxx data type */
+	guint     type;						/* the elementary NAFD_TYPE_xxx data type */
 
 	gchar    *default_value;			/* the default to assign when creating a new object
 										 * this default is also displayed in command-line help
@@ -129,20 +95,24 @@ typedef struct {
 										 *
 										 * This may be used mainly when POINTER type is used
 										 * to cast e.g. a GList of items */
+
+	gboolean  obsoleted;				/* whether this data has been obsoleted ?
+										 * if TRUE, then no property will be defined for it
+										 * and the data will not be written when serializing */
 }
-	NadfIdType;
+	NADataDef;
 
 /**
- * The structure which fully describe a logical group of data
- * Each #NAIFactoryObject item may definition may be built from a list of
+ * The structure which fully describes a logical group of data
+ * Each #NAIFactoryObject item definition is built from a list of
  * these groups
  */
 typedef struct {
-	guint       idgroup;				/* cf. na-ifactory-object-enum.h */
-	NadfIdType *iddef;
+	gchar     *group;					/* defined in na-ifactory-object-data.h */
+	NADataDef *def;
 }
-	NadfIdGroup;
+	NADataGroup;
 
 G_END_DECLS
 
-#endif /* __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_STR_H__ */
+#endif /* __NAUTILUS_ACTIONS_API_NA_FACTORY_DATA_DEF_H__ */
diff --git a/src/api/na-ifactory-object-enum.h b/src/api/na-data-types.h
similarity index 54%
rename from src/api/na-ifactory-object-enum.h
rename to src/api/na-data-types.h
index 2540e9c..4138ed8 100644
--- a/src/api/na-ifactory-object-enum.h
+++ b/src/api/na-data-types.h
@@ -28,71 +28,49 @@
  *   ... and many others (see AUTHORS)
  */
 
-#ifndef __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_ENUM_H__
-#define __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_ENUM_H__
-
-#include <glib.h>
+#ifndef __NAUTILUS_ACTIONS_API_NA_FACTORY_DATA_TYPES_H__
+#define __NAUTILUS_ACTIONS_API_NA_FACTORY_DATA_TYPES_H__
 
 /**
- * SECTION: na_ifactory_object
- * @short_description: Enumeration of all serializable elementary datas.
- * @include: nautilus-actions/na-ifactory-object-enum.h
+ * SECTION: na_data
+ * @short_description: NADataBoxed type definitions.
+ * @include: nautilus-actions/na-data-types.h
  */
 
+#include <glib-object.h>
+
 G_BEGIN_DECLS
 
-/*
+/**
+ * Elementary factory data types
+ * Each elementary factory data must be typed as one of these
+ * IFactoryProvider implementations should provide a primitive for reading
+ * (resp. writing) a value for each of these elementary data types.
+ *
  * IMPORTANT NOTE
  * Please note that this enumeration may  be compiled in by extensions.
  * They must so remain fixed, unless you want see strange effects (e.g.
- * an extension has been compiled with NADF_TYPE_STRING = 2, while you
+ * an extension has been compiled with NAFD_TYPE_STRING = 2, while you
  * have inserted another element, making it to 3 !) - or you know what
  * you are doing...
  */
 
 enum {
-	NA_FACTORY_OBJECT_ID_GROUP = 1,
-	NADF_DATA_ID,
-	NADF_DATA_LABEL,
-	NADF_DATA_PARENT,
+	NAFD_TYPE_STRING = 1,				/* an ASCII string */
 
-	NA_FACTORY_OBJECT_ITEM_GROUP = 20,
-	NADF_DATA_TOOLTIP,
-	NADF_DATA_ICON,
-	NADF_DATA_DESCRIPTION,
-	NADF_DATA_SUBITEMS,
-	NADF_DATA_SUBITEMS_SLIST,
-	NADF_DATA_ENABLED,
-	NADF_DATA_READONLY,
-	NADF_DATA_PROVIDER,
-	NADF_DATA_PROVIDER_DATA,
+	NAFD_TYPE_LOCALE_STRING,			/* a localized UTF-8 string */
 
-	NA_FACTORY_OBJECT_ACTION_GROUP = 40,
-	NADF_DATA_VERSION,
-	NADF_DATA_TARGET_SELECTION,
-	NADF_DATA_TARGET_BACKGROUND,
-	NADF_DATA_TARGET_TOOLBAR,
-	NADF_DATA_TOOLBAR_LABEL,
-	NADF_DATA_TOOLBAR_SAME_LABEL,
-	NADF_DATA_LAST_ALLOCATED,
+	NAFD_TYPE_BOOLEAN,					/* a boolean
+										 * can be initialized with "true" or "false" (case insensitive) */
 
-	NA_FACTORY_OBJECT_MENU_GROUP = 60,
+	NAFD_TYPE_STRING_LIST,				/* a list of ASCII strings */
 
-	NA_FACTORY_OBJECT_PROFILE_GROUP = 80,
-	NADF_DATA_PATH,
-	NADF_DATA_PARAMETERS,
-	NADF_DATA_BASENAMES,
-	NADF_DATA_MATCHCASE,
-	NADF_DATA_MIMETYPES,
-	NADF_DATA_ISFILE,
-	NADF_DATA_ISDIR,
-	NADF_DATA_MULTIPLE,
-	NADF_DATA_SCHEMES,
-	NADF_DATA_FOLDERS,
+	NAFD_TYPE_POINTER,					/* a ( void * ) pointer
+										 * should be initialized to NULL */
 
-	NA_FACTORY_OBJECT_CONDITIONS_GROUP = 100,
+	NAFD_TYPE_UINT,						/* an unsigned integer */
 };
 
 G_END_DECLS
 
-#endif /* __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_ENUM_H__ */
+#endif /* __NAUTILUS_ACTIONS_API_NA_FACTORY_DATA_TYPES_H__ */
diff --git a/src/api/na-gconf-utils.h b/src/api/na-gconf-utils.h
index 08f6973..4d4d816 100644
--- a/src/api/na-gconf-utils.h
+++ b/src/api/na-gconf-utils.h
@@ -63,6 +63,8 @@ gboolean na_gconf_utils_write_string_list( GConfClient *gconf, const gchar *path
 
 gboolean na_gconf_utils_remove_entry     ( GConfClient *gconf, const gchar *path, gchar **message );
 
+GSList  *na_gconf_utils_slist_from_string( const gchar *string );
+
 G_END_DECLS
 
 #endif /* __NAUTILUS_ACTIONS_API_NA_GCONF_UTILS_H__ */
diff --git a/src/api/na-ifactory-object-data.h b/src/api/na-ifactory-object-data.h
new file mode 100644
index 0000000..8949fbf
--- /dev/null
+++ b/src/api/na-ifactory-object-data.h
@@ -0,0 +1,89 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_DATA_H__
+#define __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_DATA_H__
+
+/**
+ * SECTION: na_ifactory_object
+ * @short_description: Declaration of all serializable elementary datas.
+ * @include: nautilus-actions/na-ifactory-object-data.h
+ */
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define NA_FACTORY_OBJECT_ID_GROUP			"na-factory-group-id"
+#define NAFO_DATA_ID						"na-factory-data-id"
+#define NAFO_DATA_LABEL						"na-factory-data-label"
+#define NAFO_DATA_PARENT					"na-factory-data-parent"
+
+#define NA_FACTORY_OBJECT_ITEM_GROUP		"na-factory-group-item"
+#define NAFO_DATA_TOOLTIP					"na-factory-data-tooltip"
+#define NAFO_DATA_ICON						"na-factory-data-icon"
+#define NAFO_DATA_DESCRIPTION				"na-factory-data-description"
+#define NAFO_DATA_SUBITEMS					"na-factory-data-items"
+#define NAFO_DATA_SUBITEMS_SLIST			"na-factory-data-items-slist"
+#define NAFO_DATA_ENABLED					"na-factory-data-enabled"
+#define NAFO_DATA_READONLY					"na-factory-data-readonly"
+#define NAFO_DATA_PROVIDER					"na-factory-data-provider"
+#define NAFO_DATA_PROVIDER_DATA				"na-factory-data-provider-data"
+
+#define NA_FACTORY_OBJECT_ACTION_GROUP		"na-factory-group-action"
+#define NAFO_DATA_VERSION					"na-factory-data-version"
+#define NAFO_DATA_TARGET_SELECTION			"na-factory-data-target-selection"
+#define NAFO_DATA_TARGET_BACKGROUND			"na-factory-data-target-background"
+#define NAFO_DATA_TARGET_TOOLBAR			"na-factory-data-target-toolbar"
+#define NAFO_DATA_TOOLBAR_LABEL				"na-factory-data-toolbar-label"
+#define NAFO_DATA_TOOLBAR_SAME_LABEL		"na-factory-data-toolbar-same-label"
+#define NAFO_DATA_LAST_ALLOCATED			"na-factory-data-last-allocated"
+
+#define NA_FACTORY_OBSOLETED_ACTION_GROUP	"na-factory-group-action-obsoleted"
+
+#define NA_FACTORY_OBJECT_MENU_GROUP		"na-factory-group-menu"
+
+#define NA_FACTORY_OBJECT_PROFILE_GROUP		"na-factory-group-profile"
+#define NAFO_DATA_PATH						"na-factory-data-path"
+#define NAFO_DATA_PARAMETERS				"na-factory-data-parameters"
+#define NAFO_DATA_BASENAMES					"na-factory-data-basenames"
+#define NAFO_DATA_MATCHCASE					"na-factory-data-matchcase"
+#define NAFO_DATA_MIMETYPES					"na-factory-data-mimetypes"
+#define NAFO_DATA_ISFILE					"na-factory-data-isfile"
+#define NAFO_DATA_ISDIR						"na-factory-data-isdir"
+#define NAFO_DATA_MULTIPLE					"na-factory-data-multiple"
+#define NAFO_DATA_SCHEMES					"na-factory-data-schemes"
+#define NAFO_DATA_FOLDERS					"na-factory-data-folders"
+
+#define NA_FACTORY_OBJECT_CONDITIONS_GROUP	"na-factory-group-conditions"
+
+G_END_DECLS
+
+#endif /* __NAUTILUS_ACTIONS_API_NA_IFACTORY_OBJECT_DATA_H__ */
diff --git a/src/api/na-ifactory-object.h b/src/api/na-ifactory-object.h
index ddea8fa..b8f14f2 100644
--- a/src/api/na-ifactory-object.h
+++ b/src/api/na-ifactory-object.h
@@ -39,21 +39,22 @@
  * This interface must be implemented by #NAObject-derived objects which
  * should take advantage of data factory management system.
  *
- * A #NAObject which would implement this #NAIFactoryObject interface
- * must meet following conditions:
+ * A #NAObject-derived which should implement this #NAIFactoryObject
+ * interface must meet following conditions:
  * - must accept an empty constructor
  *
+ * Elementary data are implemented as a GList of NADataBoxed objects.
+ *
  * Nautilus-Actions v 2.30 - API version:  1
  */
 
-#include "na-ifactory-object-enum.h"
-#include "na-ifactory-object-str.h"
+#include "na-data-def.h"
 #include "na-ifactory-provider-provider.h"
 
 G_BEGIN_DECLS
 
-#define NA_IFACTORY_OBJECT_TYPE						( na_ifactory_object_get_type())
-#define NA_IFACTORY_OBJECT( instance )				( G_TYPE_CHECK_INSTANCE_CAST( instance, NA_IFACTORY_OBJECT_TYPE, NAIFactoryObject ))
+#define NA_IFACTORY_OBJECT_TYPE							( na_ifactory_object_get_type())
+#define NA_IFACTORY_OBJECT( instance )					( G_TYPE_CHECK_INSTANCE_CAST( instance, NA_IFACTORY_OBJECT_TYPE, NAIFactoryObject ))
 #define NA_IS_IFACTORY_OBJECT( instance )				( G_TYPE_CHECK_INSTANCE_TYPE( instance, NA_IFACTORY_OBJECT_TYPE ))
 #define NA_IFACTORY_OBJECT_GET_INTERFACE( instance )	( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), NA_IFACTORY_OBJECT_TYPE, NAIFactoryObjectInterface ))
 
@@ -62,7 +63,7 @@ typedef struct NAIFactoryObject                 NAIFactoryObject;
 typedef struct NAIFactoryObjectInterfacePrivate NAIFactoryObjectInterfacePrivate;
 
 typedef struct {
-	GTypeInterface                  parent;
+	GTypeInterface                    parent;
 	NAIFactoryObjectInterfacePrivate *private;
 
 	/**
@@ -73,22 +74,30 @@ typedef struct {
 	 *
 	 * Defaults to 1.
 	 */
-	guint    ( *get_version )( const NAIFactoryObject *instance );
+	guint         ( *get_version )( const NAIFactoryObject *instance );
+
+	/**
+	 * get_groups:
+	 * @instance: this #NAIFactoryObject instance.
+	 *
+	 * Returns: a pointer to the NADataGroup which defines this object.
+	 */
+	NADataGroup * ( *get_groups ) ( const NAIFactoryObject *instance );
 
 	/**
 	 * get_default:
 	 * @instance: this #NAIFactoryObject instance.
-	 * @iddef: the #NadfIdType structure which defines the data whose
+	 * @iddef: the #NADataDef structure which defines the data whose
 	 * default value is searched for.
 	 *
 	 * The @instance may take advantage of this method to setup a default
 	 * value for a specific instance, or even for instances of a class when
-	 * several classes share some elementary data via common #NadfIdGroup.
+	 * several classes share some elementary data via common #NADataGroup.
 	 *
 	 * Returns: a newly allocated string which defines the suitable
 	 * default value, or %NULL.
 	 */
-	gchar *  ( *get_default )( const NAIFactoryObject *instance, const NadfIdType *iddef );
+	gchar *       ( *get_default )( const NAIFactoryObject *instance, const NADataDef *iddef );
 
 	/**
 	 * copy:
@@ -100,7 +109,7 @@ typedef struct {
 	 * The target @instance may take advantage of this call to do some
 	 * particular copy tasks.
 	 */
-	void     ( *copy )       ( NAIFactoryObject *instance, const NAIFactoryObject *source );
+	void          ( *copy )       ( NAIFactoryObject *instance, const NAIFactoryObject *source );
 
 	/**
 	 * are_equal:
@@ -112,7 +121,7 @@ typedef struct {
 	 * This function is triggered after all elementary data comparisons
 	 * have been sucessfully made.
 	 */
-	gboolean ( *are_equal )  ( const NAIFactoryObject *a, const NAIFactoryObject *b );
+	gboolean      ( *are_equal )  ( const NAIFactoryObject *a, const NAIFactoryObject *b );
 
 	/**
 	 * is_valid:
@@ -123,7 +132,7 @@ typedef struct {
 	 * This function is triggered after all elementary data comparisons
 	 * have been sucessfully made.
 	 */
-	gboolean ( *is_valid )   ( const NAIFactoryObject *object );
+	gboolean      ( *is_valid )   ( const NAIFactoryObject *object );
 
 	/**
 	 * read_start:
@@ -135,7 +144,7 @@ typedef struct {
 	 *
 	 * Called just before the object is unserialized.
 	 */
-	void     ( *read_start ) ( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+	void          ( *read_start ) ( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
 
 	/**
 	 * read_done:
@@ -147,7 +156,7 @@ typedef struct {
 	 *
 	 * Called when the object has been unserialized.
 	 */
-	void     ( *read_done )  ( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+	void          ( *read_done )  ( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
 
 	/**
 	 * write_start:
@@ -159,7 +168,7 @@ typedef struct {
 	 *
 	 * Called just before the object is serialized.
 	 */
-	void     ( *write_start )( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
+	void          ( *write_start )( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
 
 	/**
 	 * write_done:
@@ -171,16 +180,24 @@ typedef struct {
 	 *
 	 * Called when the object has been serialized.
 	 */
-	void     ( *write_done ) ( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
+	void          ( *write_done ) ( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
 }
 	NAIFactoryObjectInterface;
 
-GType       na_ifactory_object_get_type( void );
+GType      na_ifactory_object_get_type( void );
 
-void       *na_ifactory_object_get( const NAIFactoryObject *object, guint data_id );
+void      *na_ifactory_object_get_as_void  ( const NAIFactoryObject *object, const gchar *name );
 
+void       na_ifactory_object_set_from_void( NAIFactoryObject *object, const gchar *name, const void *data );
+
+#if 0
 void        na_ifactory_object_set_from_string( NAIFactoryObject *object, guint data_id, const gchar *data );
-void        na_ifactory_object_set_from_void  ( NAIFactoryObject *object, guint data_id, const void *data );
+#endif
+
+#if 0
+NADataDef *na_ifactory_object_get_data_def_from_name     ( const NAIFactoryObject *object, const gchar *name );
+NADataDef *na_ifactory_object_get_data_def_from_gconf_key( const NAIFactoryObject *object, const gchar *entry );
+#endif
 
 G_END_DECLS
 
diff --git a/src/api/na-ifactory-provider.h b/src/api/na-ifactory-provider.h
index 87e4374..f6c9186 100644
--- a/src/api/na-ifactory-provider.h
+++ b/src/api/na-ifactory-provider.h
@@ -44,6 +44,7 @@
  * Nautilus-Actions v 2.30 - API version:  1
  */
 
+#include "na-data-boxed.h"
 #include "na-ifactory-object.h"
 #include "na-ifactory-provider-provider.h"
 
@@ -68,7 +69,7 @@ typedef struct {
 	 *
 	 * Defaults to 1.
 	 */
-	guint    ( *get_version )( const NAIFactoryProvider *instance );
+	guint         ( *get_version )( const NAIFactoryProvider *instance );
 
 	/**
 	 * read_start:
@@ -80,27 +81,23 @@ typedef struct {
 	 *
 	 * API called by #NAIFactoryObject just before starting with reading data.
 	 */
-	void     ( *read_start ) ( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *object, GSList **messages  );
+	void          ( *read_start ) ( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *object, GSList **messages  );
 
 	/**
-	 * read_value:
+	 * read_data:
 	 * @reader: this #NAIFactoryProvider instance.
 	 * @reader_data: the data associated to this instance.
-	 * @iddef: the description of the data to be readen.
+	 * @object: the #NAIFactoryobject being unserialized.
+	 * @def: a #NADataDef structure which identifies the data to be unserialized.
 	 * @messages: a pointer to a #GSList list of strings; the provider
 	 *  may append messages to this list, but shouldn't reinitialize it.
 	 *
-	 * Returns: a newly allocated #GValue, or %NULL if an error has occurred.
-	 *
-	 * Note that a string list should be returned as a #GValue of type
-	 * G_TYPE_POINTER, which itself must be a GSList pointer.
-	 *
-	 * The returned #GValue, and its content if apply, will be freed
-	 * by the caller.
+	 * Returns: a newly allocated NADataBoxed which contains the readen value.
+	 * Should return %NULL if data is not found.
 	 *
 	 * This method must be implemented in order any data be read.
 	 */
-	GValue * ( *read_value ) ( const NAIFactoryProvider *reader, void *reader_data, const NadfIdType *iddef, GSList **messages );
+	NADataBoxed * ( *read_data )  ( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *object, const NADataDef *def, GSList **messages );
 
 	/**
 	 * read_done:
@@ -113,7 +110,7 @@ typedef struct {
 	 * API called by #NAIFactoryObject when all data have been readen.
 	 * Implementor may take advantage of this to do some cleanup.
 	 */
-	void     ( *read_done )  ( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *object, GSList **messages  );
+	void          ( *read_done )  ( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *object, GSList **messages  );
 
 	/**
 	 * write_start:
@@ -125,14 +122,15 @@ typedef struct {
 	 *
 	 * API called by #NAIFactoryObject just before starting with writing data.
 	 */
-	void     ( *write_start )( const NAIFactoryProvider *writer, void *writer_data, NAIFactoryObject *object, GSList **messages  );
+	void          ( *write_start )( const NAIFactoryProvider *writer, void *writer_data, const NAIFactoryObject *object, GSList **messages  );
 
 	/**
-	 * write_value:
+	 * write_data:
 	 * @writer: this #NAIFactoryProvider instance.
 	 * @writer_data: the data associated to this instance.
-	 * @iddef: the description of the data to be written.
-	 * @value: the #NADataElement to be written down.
+	 * @object: the #NAIFactoryObject object being written.
+	 * @def: the description of the data to be written.
+	 * @value: the #NADataBoxed to be written down.
 	 * @messages: a pointer to a #GSList list of strings; the provider
 	 *  may append messages to this list, but shouldn't reinitialize it.
 	 *
@@ -140,7 +138,7 @@ typedef struct {
 	 *
 	 * This method must be implemented in order any data be written.
 	 */
-	void     ( *write_value )( const NAIFactoryProvider *writer, void *writer_data, const NadfIdType *iddef, GValue *value, GSList **messages );
+	void          ( *write_data ) ( const NAIFactoryProvider *writer, void *writer_data, const NAIFactoryObject *object, const NADataDef *iddef, NADataBoxed *value, GSList **messages );
 
 	/**
 	 * write_done:
@@ -153,16 +151,14 @@ typedef struct {
 	 * API called by #NAIFactoryObject when all data have been written.
 	 * Implementor may take advantage of this to do some cleanup.
 	 */
-	void     ( *write_done ) ( const NAIFactoryProvider *writer, void *writer_data, NAIFactoryObject *object, GSList **messages  );
+	void          ( *write_done ) ( const NAIFactoryProvider *writer, void *writer_data, const NAIFactoryObject *object, GSList **messages  );
 }
 	NAIFactoryProviderInterface;
 
-GType           na_ifactory_provider_get_type( void );
-
-NAIFactoryObject *na_ifactory_provider_read_item ( const NAIFactoryProvider *reader, void *reader_data, GType type, GSList **messages );
-void            na_ifactory_provider_write_item( const NAIFactoryProvider *writer, void *writer_data, NAIFactoryObject *serializable, GSList **messages );
+GType na_ifactory_provider_get_type( void );
 
-NadfIdType     *na_ifactory_provider_get_idtype_from_gconf_key( const gchar *xml_entry );
+void  na_ifactory_provider_read_item ( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *object, GSList **messages );
+void  na_ifactory_provider_write_item( const NAIFactoryProvider *writer, void *writer_data, NAIFactoryObject *object, GSList **messages );
 
 G_END_DECLS
 
diff --git a/src/api/na-iimporter.h b/src/api/na-iimporter.h
index f9193b9..6eeea1d 100644
--- a/src/api/na-iimporter.h
+++ b/src/api/na-iimporter.h
@@ -51,11 +51,10 @@ G_BEGIN_DECLS
 #define NA_IIMPORTER_GET_INTERFACE( instance )	( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), NA_IIMPORTER_TYPE, NAIImporterInterface ))
 
 typedef struct NAIImporter                 NAIImporter;
+typedef struct NAIImporterParms            NAIImporterParms;
 
 typedef struct NAIImporterInterfacePrivate NAIImporterInterfacePrivate;
 
-typedef gboolean ( *ImporterCheckFn )( const gchar *, void *fn_data );
-
 typedef struct {
 	GTypeInterface               parent;
 	NAIImporterInterfacePrivate *private;
@@ -68,10 +67,10 @@ typedef struct {
 	 *
 	 * Defaults to 1.
 	 */
-	guint          ( *get_version )( const NAIImporter *instance );
+	guint ( *get_version )    ( const NAIImporter *instance );
 
 	/**
-	 * import_uri:
+	 * import_from_uri:
 	 * @instance: the #NAIImporter provider.
 	 * @uri: the URI of the file to be imported.
 	 * @mode: import mode.
@@ -86,7 +85,7 @@ typedef struct {
 	 * Returns: a #NAObjectItem-derived object, or %NULL if an error has
 	 * been detected.
 	 */
-	NAObjectItem * ( *import_uri ) ( const NAIImporter *instance, const gchar *uri, guint mode, ImporterCheckFn fn, void *fn_data, GSList **messages );
+	guint ( *import_from_uri )( const NAIImporter *instance, NAIImporterParms *parms );
 }
 	NAIImporterInterface;
 
@@ -99,6 +98,34 @@ enum {
 	IMPORTER_MODE_ASK
 };
 
+/* return code
+ */
+enum {
+	IMPORTER_CODE_OK = 0,
+	IMPORTER_CODE_PROGRAM_ERROR,
+	IMPORTER_CODE_NOT_WILLING_TO,
+	IMPORTER_CODE_NO_ITEM_ID,
+	IMPORTER_CODE_NO_ITEM_TYPE,
+	IMPORTER_CODE_UNKNOWN_ITEM_TYPE,
+	IMPORTER_CODE_CANCELLED
+};
+
+/* parameters via a structure
+ */
+typedef gboolean ( *NAIImporterCheckFn )( const NAObjectItem *, void *fn_data );
+
+struct NAIImporterParms {
+	guint              version;			/* i 1: version of this structure */
+	gchar             *uri;				/* i 1: uri of the file to be imported */
+	guint              mode;			/* i 1: import mode */
+	NAObjectItem      *item;			/*  o1: imported NAObjectItem-derived object */
+	NAIImporterCheckFn fn;				/* i 1: a function to check the existance of the imported item */
+	void              *fn_data;			/* i 1: data function */
+	GSList            *messages;		/* io1: a #GSList list of localized strings;
+										 *       the provider may append messages to this list,
+										 *       but shouldn't reinitialize it. */
+};
+
 GType na_iimporter_get_type( void );
 
 G_END_DECLS
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index b0c5a98..caa544d 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -42,7 +42,7 @@
  */
 
 #include "na-ifactory-object.h"
-#include "na-ifactory-object-enum.h"
+#include "na-ifactory-object-data.h"
 #include "na-iduplicable.h"
 #include "na-object-action.h"
 #include "na-object-profile.h"
@@ -77,13 +77,13 @@ G_BEGIN_DECLS
 
 /* NAObjectId
  */
-#define na_object_get_id( obj )							(( gchar * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ID ))
-#define na_object_get_label( obj )						(( gchar * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_LABEL ))
-#define na_object_get_parent( obj )						(( NAObjectItem * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PARENT ))
+#define na_object_get_id( obj )							(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ID ))
+#define na_object_get_label( obj )						(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_LABEL ))
+#define na_object_get_parent( obj )						(( NAObjectItem * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PARENT ))
 
-#define na_object_set_id( obj, id )						na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ID, ( const void * )( id ))
-#define na_object_set_label( obj, label )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_LABEL, ( const void * )( label ))
-#define na_object_set_parent( obj, parent )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PARENT, ( const void * )( parent ))
+#define na_object_set_id( obj, id )						na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ID, ( const void * )( id ))
+#define na_object_set_label( obj, label )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_LABEL, ( const void * )( label ))
+#define na_object_set_parent( obj, parent )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PARENT, ( const void * )( parent ))
 
 #define na_object_sort_alpha_asc( a, b )				na_object_id_sort_alpha_asc( NA_OBJECT_ID( a ), NA_OBJECT_ID( b ))
 #define na_object_sort_alpha_desc( a, b )				na_object_id_sort_alpha_desc( NA_OBJECT_ID( a ), NA_OBJECT_ID( b ))
@@ -95,23 +95,23 @@ G_BEGIN_DECLS
 
 /* NAObjectItem
  */
-#define na_object_get_tooltip( obj )					(( gchar * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TOOLTIP ))
-#define na_object_get_icon( obj )						(( gchar * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ICON ))
-#define na_object_get_items( obj )						(( GList * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_SUBITEMS ))
-#define na_object_get_items_slist( obj )				(( GSList * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_SUBITEMS_SLIST ))
-#define na_object_is_enabled( obj )						(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ENABLED )))
-#define na_object_is_readonly( obj )					(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_READONLY )))
-#define na_object_get_provider( obj )					na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PROVIDER )
-#define na_object_get_provider_data( obj )				na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PROVIDER_DATA )
-
-#define na_object_set_tooltip( obj, tooltip )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TOOLTIP, ( const void * )( tooltip ))
-#define na_object_set_icon( obj, icon )					na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ICON, ( const void * )( icon ))
-#define na_object_set_items( obj, list )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_SUBITEMS, ( const void * )( list ))
-#define na_object_set_items_slist( obj, slist )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_SUBITEMS_SLIST, ( const void * )( slist ))
-#define na_object_set_enabled( obj, enabled )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ENABLED, ( const void * ) GUINT_TO_POINTER( enabled ))
-#define na_object_set_readonly( obj, readonly )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_READONLY, ( const void * ) GUINT_TO_POINTER( readonly ))
-#define na_object_set_provider( obj, provider )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PROVIDER, ( const void * )( provider ))
-#define na_object_set_provider_data( obj, data )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PROVIDER_DATA, ( const void * )( data ))
+#define na_object_get_tooltip( obj )					(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLTIP ))
+#define na_object_get_icon( obj )						(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ICON ))
+#define na_object_get_items( obj )						(( GList * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SUBITEMS ))
+#define na_object_get_items_slist( obj )				(( GSList * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SUBITEMS_SLIST ))
+#define na_object_is_enabled( obj )						(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ENABLED )))
+#define na_object_is_readonly( obj )					(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_READONLY )))
+#define na_object_get_provider( obj )					na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PROVIDER )
+#define na_object_get_provider_data( obj )				na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PROVIDER_DATA )
+
+#define na_object_set_tooltip( obj, tooltip )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLTIP, ( const void * )( tooltip ))
+#define na_object_set_icon( obj, icon )					na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ICON, ( const void * )( icon ))
+#define na_object_set_items( obj, list )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SUBITEMS, ( const void * )( list ))
+#define na_object_set_items_slist( obj, slist )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SUBITEMS_SLIST, ( const void * )( slist ))
+#define na_object_set_enabled( obj, enabled )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ENABLED, ( const void * ) GUINT_TO_POINTER( enabled ))
+#define na_object_set_readonly( obj, readonly )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_READONLY, ( const void * ) GUINT_TO_POINTER( readonly ))
+#define na_object_set_provider( obj, provider )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PROVIDER, ( const void * )( provider ))
+#define na_object_set_provider_data( obj, data )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PROVIDER_DATA, ( const void * )( data ))
 
 #define na_object_get_item( obj, id )					na_object_item_get_item( NA_OBJECT_ITEM( obj ),( const gchar * )( id ))
 #define na_object_get_position( obj, child )			na_object_item_get_position( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ))
@@ -127,48 +127,48 @@ G_BEGIN_DECLS
 
 /* NAObjectAction
  */
-#define na_object_get_version( obj )					(( gchar * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_VERSION ))
-#define na_object_is_target_selection( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TARGET_SELECTION )))
-#define na_object_is_target_background( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TARGET_BACKGROUND )))
-#define na_object_is_target_toolbar( obj )				(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TARGET_TOOLBAR )))
-#define na_object_get_toolbar_label( obj )				(( gchar * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TOOLBAR_LABEL ))
-#define na_object_is_toolbar_same_label( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TOOLBAR_SAME_LABEL )))
-#define na_object_get_last_allocated( obj )				(( guint ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_LAST_ALLOCATED )))
-
-#define na_object_set_version( obj, version )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_VERSION, ( const void * )( version ))
-#define na_object_set_target_selection( obj, target )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TARGET_SELECTION, ( const void * ) GUINT_TO_POINTER( target ))
-#define na_object_set_target_background( obj, target )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TARGET_BACKGROUND, ( const void * ) GUINT_TO_POINTER( target ))
-#define na_object_set_target_toolbar( obj, target )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TARGET_TOOLBAR, ( const void * ) GUINT_TO_POINTER( target ))
-#define na_object_set_toolbar_label( obj, label )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TOOLBAR_LABEL, ( const void * )( label ))
-#define na_object_set_toolbar_same_label( obj, same )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_TOOLBAR_SAME_LABEL, ( const void * ) GUINT_TO_POINTER( same ))
-#define na_object_set_last_allocated( obj, last )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_LAST_ALLOCATED, ( const void * ) GUINT_TO_POINTER( last ))
-
-#define na_object_reset_last_allocated( obj )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_LAST_ALLOCATED, ( const void * ) GUINT_TO_POINTER( 0 ))
+#define na_object_get_version( obj )					(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_VERSION ))
+#define na_object_is_target_selection( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_SELECTION )))
+#define na_object_is_target_background( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_BACKGROUND )))
+#define na_object_is_target_toolbar( obj )				(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_TOOLBAR )))
+#define na_object_get_toolbar_label( obj )				(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLBAR_LABEL ))
+#define na_object_is_toolbar_same_label( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLBAR_SAME_LABEL )))
+#define na_object_get_last_allocated( obj )				(( guint ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_LAST_ALLOCATED )))
+
+#define na_object_set_version( obj, version )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_VERSION, ( const void * )( version ))
+#define na_object_set_target_selection( obj, target )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_SELECTION, ( const void * ) GUINT_TO_POINTER( target ))
+#define na_object_set_target_background( obj, target )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_BACKGROUND, ( const void * ) GUINT_TO_POINTER( target ))
+#define na_object_set_target_toolbar( obj, target )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_TOOLBAR, ( const void * ) GUINT_TO_POINTER( target ))
+#define na_object_set_toolbar_label( obj, label )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLBAR_LABEL, ( const void * )( label ))
+#define na_object_set_toolbar_same_label( obj, same )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLBAR_SAME_LABEL, ( const void * ) GUINT_TO_POINTER( same ))
+#define na_object_set_last_allocated( obj, last )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_LAST_ALLOCATED, ( const void * ) GUINT_TO_POINTER( last ))
+
+#define na_object_reset_last_allocated( obj )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_LAST_ALLOCATED, ( const void * ) GUINT_TO_POINTER( 0 ))
 #define na_object_attach_profile( obj, profile )		na_object_action_attach_profile( NA_OBJECT_ACTION( obj ), NA_OBJECT_PROFILE( profile ))
 
 /* NAObjectProfile
  */
-#define na_object_get_path( obj )						(( gchar * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PATH ))
-#define na_object_get_parameters( obj )					(( gchar * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PARAMETERS ))
-#define na_object_get_basenames( obj )					(( GSList * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_BASENAMES ))
-#define na_object_is_matchcase( obj )					(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_MATCHCASE )))
-#define na_object_get_mimetypes( obj )					(( GSList * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_MIMETYPES ))
-#define na_object_is_file( obj )						(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ISFILE )))
-#define na_object_is_dir( obj )							(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ISDIR )))
-#define na_object_is_multiple( obj )					(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_MULTIPLE )))
-#define na_object_get_schemes( obj )					(( GSList * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_SCHEMES ))
-#define na_object_get_folders( obj )					(( GSList * ) na_ifactory_object_get( NA_IFACTORY_OBJECT( obj ), NADF_DATA_FOLDERS ))
-
-#define na_object_set_path( obj, path )					na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PATH, ( const void * )( path ))
-#define na_object_set_parameters( obj, parms )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_PARAMETERS, ( const void * )( parms ))
-#define na_object_set_basenames( obj, bnames )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_BASENAMES, ( const void * )( bnames ))
-#define na_object_set_matchcase( obj, match )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_MATCHCASE, ( const void * ) GUINT_TO_POINTER( match ))
-#define na_object_set_mimetypes( obj, types )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_MIMETYPES, ( const void * )( types ))
-#define na_object_set_isfile( obj, isfile )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ISFILE, ( const void * ) GUINT_TO_POINTER( isfile ))
-#define na_object_set_isdir( obj, isdir )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_ISDIR, ( const void * ) GUINT_TO_POINTER( isdir ))
-#define na_object_set_multiple( obj, multiple )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_MULTIPLE, ( const void * ) GUINT_TO_POINTER( multiple ))
-#define na_object_set_schemes( obj, schemes )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_SCHEMES, ( const void * )( schemes ))
-#define na_object_set_folders( obj, folders )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NADF_DATA_FOLDERS, ( const void * )( folders ))
+#define na_object_get_path( obj )						(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PATH ))
+#define na_object_get_parameters( obj )					(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PARAMETERS ))
+#define na_object_get_basenames( obj )					(( GSList * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_BASENAMES ))
+#define na_object_is_matchcase( obj )					(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_MATCHCASE )))
+#define na_object_get_mimetypes( obj )					(( GSList * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_MIMETYPES ))
+#define na_object_is_file( obj )						(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ISFILE )))
+#define na_object_is_dir( obj )							(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ISDIR )))
+#define na_object_is_multiple( obj )					(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_MULTIPLE )))
+#define na_object_get_schemes( obj )					(( GSList * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SCHEMES ))
+#define na_object_get_folders( obj )					(( GSList * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_FOLDERS ))
+
+#define na_object_set_path( obj, path )					na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PATH, ( const void * )( path ))
+#define na_object_set_parameters( obj, parms )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PARAMETERS, ( const void * )( parms ))
+#define na_object_set_basenames( obj, bnames )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_BASENAMES, ( const void * )( bnames ))
+#define na_object_set_matchcase( obj, match )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_MATCHCASE, ( const void * ) GUINT_TO_POINTER( match ))
+#define na_object_set_mimetypes( obj, types )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_MIMETYPES, ( const void * )( types ))
+#define na_object_set_isfile( obj, isfile )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ISFILE, ( const void * ) GUINT_TO_POINTER( isfile ))
+#define na_object_set_isdir( obj, isdir )				na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_ISDIR, ( const void * ) GUINT_TO_POINTER( isdir ))
+#define na_object_set_multiple( obj, multiple )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_MULTIPLE, ( const void * ) GUINT_TO_POINTER( multiple ))
+#define na_object_set_schemes( obj, schemes )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SCHEMES, ( const void * )( schemes ))
+#define na_object_set_folders( obj, folders )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_FOLDERS, ( const void * )( folders ))
 
 #define na_object_set_scheme( obj, scheme, add )		na_object_profile_set_scheme( NA_OBJECT_PROFILE( obj ), ( const gchar * )( scheme ), ( add ))
 #define na_object_replace_folder( obj, old, new )		na_object_profile_replace_folder( NA_OBJECT_PROFILE( obj ), ( const gchar * )( old ), ( const gchar * )( new ))
diff --git a/src/api/na-object-profile.h b/src/api/na-object-profile.h
index 67180f2..d425860 100644
--- a/src/api/na-object-profile.h
+++ b/src/api/na-object-profile.h
@@ -67,15 +67,11 @@ typedef struct {
 }
 	NAObjectProfileClass;
 
-/* default prefix for profile name
- */
-#define NA_PROFILE_DEFAULT_PREFIX		"profile-"
-
 GType            na_object_profile_get_type( void );
 
 NAObjectProfile *na_object_profile_new( void );
 
-void             na_object_profile_set_scheme( NAObjectProfile *profile, const gchar *scheme, gboolean selected );
+void             na_object_profile_set_scheme    ( NAObjectProfile *profile, const gchar *scheme, gboolean selected );
 void             na_object_profile_replace_folder( NAObjectProfile *profile, const gchar *old, const gchar *new );
 
 gboolean         na_object_profile_is_candidate                ( const NAObjectProfile *profile, gint target, GList *files );
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 4d3e84f..617d57e 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -39,8 +39,7 @@ AM_CPPFLAGS += \
 
 libna_core_la_SOURCES = \
 	na-core-utils.c										\
-	na-data-element.c									\
-	na-data-element.h									\
+	na-data-boxed.c										\
 	na-dbus-tracker.h									\
 	na-exporter.c										\
 	na-exporter.h										\
@@ -60,7 +59,6 @@ libna_core_la_SOURCES = \
 	na-iexporter.c										\
 	na-ifactory-object.c								\
 	na-ifactory-provider.c								\
-	na-ifactory-provider-priv.h							\
 	na-iimporter.c										\
 	na-iio-provider.c									\
 	na-io-provider.c									\
@@ -75,15 +73,15 @@ libna_core_la_SOURCES = \
 	na-module.h											\
 	na-object.c											\
 	na-object-id.c										\
-	na-object-id-enum.c									\
+	na-object-id-factory.c								\
 	na-object-item.c									\
-	na-object-item-enum.c								\
+	na-object-item-factory.c							\
 	na-object-action.c									\
-	na-object-action-enum.c								\
+	na-object-action-factory.c							\
 	na-object-profile.c									\
-	na-object-profile-enum.c							\
+	na-object-profile-factory.c							\
 	na-object-menu.c									\
-	na-object-menu-enum.c								\
+	na-object-menu-factory.c							\
 	na-pivot.c											\
 	na-pivot.h											\
 	na-updater.c										\
diff --git a/src/core/na-data-boxed.c b/src/core/na-data-boxed.c
new file mode 100644
index 0000000..5c666a5
--- /dev/null
+++ b/src/core/na-data-boxed.c
@@ -0,0 +1,1165 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <api/na-core-utils.h>
+#include <api/na-gconf-utils.h>
+#include <api/na-data-def.h>
+#include <api/na-data-types.h>
+#include <api/na-data-boxed.h>
+
+/* private class data
+ */
+struct NADataBoxedClassPrivate {
+	void *empty;						/* so that gcc -pedantic is happy */
+};
+
+/* private instance data
+ */
+struct NADataBoxedPrivate {
+	gboolean      dispose_has_run;
+	NADataDef    *def ;
+	union {
+		gboolean  boolean;
+		gchar    *string;
+		GSList   *slist;
+		void     *pointer;
+		guint     uint;
+	} u;
+};
+
+typedef struct {
+	guint           type;
+	GParamSpec * ( *spec )            ( const NADataDef * );
+	void         ( *free )            ( const NADataBoxed * );
+	void         ( *dump )            ( const NADataBoxed * );
+	gboolean     ( *are_equal )       ( const NADataBoxed *, const NADataBoxed * );
+	gboolean     ( *is_valid )        ( const NADataBoxed * );
+	void *       ( *get_as_void )     ( const NADataBoxed * );
+	void         ( *get_as_value )    ( const NADataBoxed *, GValue *value );
+	void         ( *set_from_boxed )( NADataBoxed *, const NADataBoxed * );
+	void         ( *set_from_string ) ( NADataBoxed *, const gchar *string );
+	void         ( *set_from_value )  ( NADataBoxed *, const GValue *value );
+	void         ( *set_from_void )   ( NADataBoxed *, const void *value );
+}
+	DataBoxedFn;
+
+static GObjectClass *st_parent_class   = NULL;
+
+static GType register_type( void );
+static void  class_init( NADataBoxedClass *klass );
+static void  instance_init( GTypeInstance *instance, gpointer klass );
+static void  instance_dispose( GObject *object );
+static void  instance_finalize( GObject *object );
+
+static DataBoxedFn *get_data_boxed_fn( guint type );
+
+static GParamSpec *string_spec( const NADataDef *idtype );
+static void        string_free( const NADataBoxed *boxed );
+static void        string_dump( const NADataBoxed *boxed );
+static gboolean    string_are_equal( const NADataBoxed *a, const NADataBoxed *b );
+static gboolean    string_is_valid( const NADataBoxed *boxed );
+static void       *string_get_as_void( const NADataBoxed *boxed );
+static void        string_get_as_value( const NADataBoxed *boxed, GValue *value );
+static void        string_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source );
+static void        string_set_from_string( NADataBoxed *boxed, const gchar *string );
+static void        string_set_from_value( NADataBoxed *boxed, const GValue *value );
+static void        string_set_from_void( NADataBoxed *boxed, const void *value );
+
+static gboolean    locale_are_equal( const NADataBoxed *a, const NADataBoxed *b );
+static gboolean    locale_is_valid( const NADataBoxed *boxed );
+
+static GParamSpec *slist_spec( const NADataDef *idtype );
+static void        slist_free( const NADataBoxed *boxed );
+static void        slist_dump( const NADataBoxed *boxed );
+static gboolean    slist_are_equal( const NADataBoxed *a, const NADataBoxed *b );
+static gboolean    slist_is_valid( const NADataBoxed *boxed );
+static void       *slist_get_as_void( const NADataBoxed *boxed );
+static void        slist_get_as_value( const NADataBoxed *boxed, GValue *value );
+static void        slist_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source );
+static void        slist_set_from_string( NADataBoxed *boxed, const gchar *string );
+static void        slist_set_from_value( NADataBoxed *boxed, const GValue *value );
+static void        slist_set_from_void( NADataBoxed *boxed, const void *value );
+
+static GParamSpec *bool_spec( const NADataDef *idtype );
+static void        bool_free( const NADataBoxed *boxed );
+static void        bool_dump( const NADataBoxed *boxed );
+static gboolean    bool_are_equal( const NADataBoxed *a, const NADataBoxed *b );
+static gboolean    bool_is_valid( const NADataBoxed *boxed );
+static void       *bool_get_as_void( const NADataBoxed *boxed );
+static void        bool_get_as_value( const NADataBoxed *boxed, GValue *value );
+static void        bool_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source );
+static void        bool_set_from_string( NADataBoxed *boxed, const gchar *string );
+static void        bool_set_from_value( NADataBoxed *boxed, const GValue *value );
+static void        bool_set_from_void( NADataBoxed *boxed, const void *value );
+
+static GParamSpec *pointer_spec( const NADataDef *idtype );
+static void        pointer_free( const NADataBoxed *boxed );
+static void        pointer_dump( const NADataBoxed *boxed );
+static gboolean    pointer_are_equal( const NADataBoxed *a, const NADataBoxed *b );
+static gboolean    pointer_is_valid( const NADataBoxed *boxed );
+static void       *pointer_get_as_void( const NADataBoxed *boxed );
+static void        pointer_get_as_value( const NADataBoxed *boxed, GValue *value );
+static void        pointer_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source );
+static void        pointer_set_from_string( NADataBoxed *boxed, const gchar *string );
+static void        pointer_set_from_value( NADataBoxed *boxed, const GValue *value );
+static void        pointer_set_from_void( NADataBoxed *boxed, const void *value );
+
+static GParamSpec *uint_spec( const NADataDef *idtype );
+static void        uint_free( const NADataBoxed *boxed );
+static void        uint_dump( const NADataBoxed *boxed );
+static gboolean    uint_are_equal( const NADataBoxed *a, const NADataBoxed *b );
+static gboolean    uint_is_valid( const NADataBoxed *boxed );
+static void       *uint_get_as_void( const NADataBoxed *boxed );
+static void        uint_get_as_value( const NADataBoxed *boxed, GValue *value );
+static void        uint_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source );
+static void        uint_set_from_string( NADataBoxed *boxed, const gchar *string );
+static void        uint_set_from_value( NADataBoxed *boxed, const GValue *value );
+static void        uint_set_from_void( NADataBoxed *boxed, const void *value );
+
+static DataBoxedFn st_data_boxed_fn[] = {
+		{ NAFD_TYPE_STRING,
+				string_spec,
+				string_free,
+				string_dump,
+				string_are_equal,
+				string_is_valid,
+				string_get_as_void,
+				string_get_as_value,
+				string_set_from_boxed,
+				string_set_from_string,
+				string_set_from_value,
+				string_set_from_void
+				},
+		{ NAFD_TYPE_LOCALE_STRING,
+				string_spec,
+				string_free,
+				string_dump,
+				locale_are_equal,
+				locale_is_valid,
+				string_get_as_void,
+				string_get_as_value,
+				string_set_from_boxed,
+				string_set_from_string,
+				string_set_from_value,
+				string_set_from_void
+				},
+		{ NAFD_TYPE_STRING_LIST,
+				slist_spec,
+				slist_free,
+				slist_dump,
+				slist_are_equal,
+				slist_is_valid,
+				slist_get_as_void,
+				slist_get_as_value,
+				slist_set_from_boxed,
+				slist_set_from_string,
+				slist_set_from_value,
+				slist_set_from_void
+				},
+		{ NAFD_TYPE_BOOLEAN,
+				bool_spec,
+				bool_free,
+				bool_dump,
+				bool_are_equal,
+				bool_is_valid,
+				bool_get_as_void,
+				bool_get_as_value,
+				bool_set_from_boxed,
+				bool_set_from_string,
+				bool_set_from_value,
+				bool_set_from_void
+				},
+		{ NAFD_TYPE_POINTER,
+				pointer_spec,
+				pointer_free,
+				pointer_dump,
+				pointer_are_equal,
+				pointer_is_valid,
+				pointer_get_as_void,
+				pointer_get_as_value,
+				pointer_set_from_boxed,
+				pointer_set_from_string,
+				pointer_set_from_value,
+				pointer_set_from_void
+				},
+		{ NAFD_TYPE_UINT,
+				uint_spec,
+				uint_free,
+				uint_dump,
+				uint_are_equal,
+				uint_is_valid,
+				uint_get_as_void,
+				uint_get_as_value,
+				uint_set_from_boxed,
+				uint_set_from_string,
+				uint_set_from_value,
+				uint_set_from_void
+				},
+		{ 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+};
+
+GType
+na_data_boxed_get_type( void )
+{
+	static GType item_type = 0;
+
+	if( item_type == 0 ){
+		item_type = register_type();
+	}
+
+	return( item_type );
+}
+
+static GType
+register_type( void )
+{
+	static const gchar *thisfn = "na_data_boxed_register_type";
+	GType type;
+
+	static GTypeInfo info = {
+		sizeof( NADataBoxedClass ),
+		NULL,
+		NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( NADataBoxed ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	g_debug( "%s", thisfn );
+
+	type = g_type_register_static( G_TYPE_OBJECT, "NADataBoxed", &info, 0 );
+
+	return( type );
+}
+
+static void
+class_init( NADataBoxedClass *klass )
+{
+	static const gchar *thisfn = "na_data_boxed_class_init";
+	GObjectClass *object_class;
+
+	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
+
+	klass->private = g_new0( NADataBoxedClassPrivate, 1 );
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+	static const gchar *thisfn = "na_data_boxed_instance_init";
+	NADataBoxed *self;
+
+	g_debug( "%s: instance=%p (%s), klass=%p",
+			thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
+
+	g_return_if_fail( NA_IS_DATA_BOXED( instance ));
+
+	self = NA_DATA_BOXED( instance );
+
+	self->private = g_new0( NADataBoxedPrivate, 1 );
+}
+
+static void
+instance_dispose( GObject *object )
+{
+	static const gchar *thisfn = "na_data_boxed_instance_dispose";
+	NADataBoxed *self;
+
+	g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+	g_return_if_fail( NA_IS_DATA_BOXED( object ));
+
+	self = NA_DATA_BOXED( object );
+
+	if( !self->private->dispose_has_run ){
+
+		self->private->dispose_has_run = TRUE;
+
+		/* chain up to the parent class */
+		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
+			G_OBJECT_CLASS( st_parent_class )->dispose( object );
+		}
+	}
+}
+
+static void
+instance_finalize( GObject *object )
+{
+	NADataBoxed *self;
+
+	g_return_if_fail( NA_IS_DATA_BOXED( object ));
+
+	self = NA_DATA_BOXED( object );
+
+	DataBoxedFn *fn = get_data_boxed_fn( self->private->def->type );
+	if( fn->free ){
+		( *fn->free )( self );
+	}
+
+	g_free( self->private );
+
+	/* chain call to parent class */
+	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( object );
+	}
+}
+
+static DataBoxedFn *
+get_data_boxed_fn( guint type )
+{
+	static const gchar *thisfn = "na_data_boxed_get_data_boxed_fn";
+	int i;
+	DataBoxedFn *fn;
+
+	fn = NULL;
+
+	for( i = 0 ; st_data_boxed_fn[i].type && !fn ; ++i ){
+		if( st_data_boxed_fn[i].type == type ){
+			fn = st_data_boxed_fn+i;
+		}
+	}
+
+	if( !fn ){
+		g_warning( "%s: unmanaged type=%d", thisfn, type );
+	}
+
+	return( fn );
+}
+
+/**
+ * na_data_boxed_get_param_spec:
+ * @def: a #NADataDef definition structure.
+ *
+ * Returns: a #GParamSpec structure.
+ */
+GParamSpec *
+na_data_boxed_get_param_spec( const NADataDef *def )
+{
+	GParamSpec *spec;
+	DataBoxedFn *fn;
+
+	spec = NULL;
+	fn = get_data_boxed_fn( def->type );
+
+	if( fn ){
+		if( fn->spec ){
+			spec = ( *fn->spec )( def );
+		}
+	}
+
+	return( spec );
+}
+
+/**
+ * na_data_boxed_new:
+ * @def: the #NADataDef definition structure for this boxed.
+ *
+ * Returns: a newly allocated #NADataBoxed.
+ */
+NADataBoxed *
+na_data_boxed_new( const NADataDef *def )
+{
+	NADataBoxed *boxed;
+
+	g_return_val_if_fail( def != NULL, NULL );
+
+	boxed = g_object_new( NA_DATA_BOXED_TYPE, NULL );
+
+	boxed->private->def = ( NADataDef * ) def;
+
+	return( boxed );
+}
+
+/**
+ * na_data_boxed_get_data_def:
+ * @boxed: this #NADataBoxed object.
+ *
+ * Returns: a pointer to the #NADataDef structure attached to the object.
+ * Should never be %NULL.
+ */
+NADataDef *
+na_data_boxed_get_data_def( const NADataBoxed *boxed )
+{
+	NADataDef *def;
+
+	g_return_val_if_fail( NA_IS_DATA_BOXED( boxed ), NULL );
+
+	def = NULL;
+
+	if( !boxed->private->dispose_has_run ){
+
+		def = boxed->private->def;
+	}
+
+	return( def );
+}
+
+/**
+ * na_data_boxed_are_equal:
+ * @a: the first #NADataBoxed object.
+ * @b: the second #NADataBoxed object.
+ *
+ * Returns: %TRUE if the two boxeds are equal, %FALSE else.
+ */
+gboolean
+na_data_boxed_are_equal( const NADataBoxed *a, const NADataBoxed *b )
+{
+	DataBoxedFn *fn;
+	gboolean are_equal;
+
+	g_return_val_if_fail( NA_IS_DATA_BOXED( a ), FALSE );
+	g_return_val_if_fail( NA_IS_DATA_BOXED( b ), FALSE );
+
+	are_equal = FALSE;
+
+	if( !a->private->dispose_has_run &&
+		!b->private->dispose_has_run ){
+
+		if( a->private->def->type == b->private->def->type ){
+
+			fn = get_data_boxed_fn( a->private->def->type );
+
+			if( fn ){
+				if( fn->are_equal ){
+					are_equal = ( *fn->are_equal )( a, b );
+				}
+			}
+		}
+	}
+
+	return( are_equal );
+}
+
+/**
+ * na_data_boxed_is_valid:
+ * @object: the #NADataBoxed object whose validity is to be checked.
+ *
+ * Returns: %TRUE if the boxed is valid, %FALSE else.
+ */
+gboolean
+na_data_boxed_is_valid( const NADataBoxed *boxed )
+{
+	DataBoxedFn *fn;
+	gboolean is_valid;
+
+	g_return_val_if_fail( NA_IS_DATA_BOXED( boxed ), FALSE );
+
+	is_valid = FALSE;
+
+	if( !boxed->private->dispose_has_run ){
+
+		fn = get_data_boxed_fn( boxed->private->def->type );
+
+		if( fn ){
+			if( fn->is_valid ){
+				is_valid = ( *fn->is_valid )( boxed );
+			}
+		}
+	}
+
+	return( is_valid );
+}
+
+/**
+ * na_data_boxed_dump:
+ * @boxed: this #NADataBoxed object.
+ *
+ * Dump the content of @boxed.
+ */
+void
+na_data_boxed_dump( const NADataBoxed *boxed )
+{
+	DataBoxedFn *fn;
+
+	fn = get_data_boxed_fn( boxed->private->def->type );
+
+	if( fn ){
+		if( fn->dump ){
+			( *fn->dump )( boxed );
+		}
+	}
+}
+
+/**
+ * na_data_boxed_get_as_void:
+ * @boxed: the #NADataBoxed whose value is to be set.
+ *
+ * Returns: the content of the @boxed.
+ *
+ * If of type NAFD_TYPE_STRING, NAFD_TYPE_LOCALE_STRING OR
+ * NAFD_TYPE_STRING_LIST, then the content is returned in a newly
+ * allocated value, which should be released by the caller.
+ */
+void *
+na_data_boxed_get_as_void( const NADataBoxed *boxed )
+{
+	DataBoxedFn *fn;
+	void *value;
+
+	g_return_val_if_fail( NA_IS_DATA_BOXED( boxed ), NULL );
+
+	value = NULL;
+
+	if( !boxed->private->dispose_has_run ){
+
+		fn = get_data_boxed_fn( boxed->private->def->type );
+
+		if( fn ){
+			if( fn->get_as_void ){
+				value = ( *fn->get_as_void )( boxed );
+			}
+		}
+	}
+
+	return( value );
+}
+
+/**
+ * na_data_boxed_get_as_value:
+ * @boxed: the #NADataBoxed whose value is to be set.
+ * @value: the string to be set.
+ *
+ * Setup @value with the content of the @boxed.
+ */
+void
+na_data_boxed_get_as_value( const NADataBoxed *boxed, GValue *value )
+{
+	DataBoxedFn *fn;
+
+	g_return_if_fail( NA_IS_DATA_BOXED( boxed ));
+
+	if( !boxed->private->dispose_has_run ){
+
+		fn = get_data_boxed_fn( boxed->private->def->type );
+
+		if( fn ){
+			if( fn->get_as_value ){
+				( *fn->get_as_value )( boxed, value );
+			}
+		}
+	}
+}
+
+/**
+ * na_data_boxed_set_default:
+ * @boxed: the #NADataBoxed whose value is to be set.
+ *
+ * Set the @boxed with its default value.
+ */
+void
+na_data_boxed_set_default( NADataBoxed *boxed )
+{
+	g_return_if_fail( NA_IS_DATA_BOXED( boxed ));
+
+	if( !boxed->private->dispose_has_run ){
+
+		DataBoxedFn *fn = get_data_boxed_fn( boxed->private->def->type );
+
+		if( fn ){
+			if( fn->free ){
+				( *fn->free )( boxed );
+			}
+			if( fn->set_from_string ){
+				( *fn->set_from_string )( boxed, boxed->private->def->default_value );
+			}
+		}
+	}
+}
+
+/**
+ * na_data_boxed_set_from_boxed:
+ * @boxed: the #NADataBoxed whose value is to be set.
+ * @value: the source #NADataBoxed.
+ *
+ * Copy value from @value to @boxed.
+ */
+void
+na_data_boxed_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *value )
+{
+	DataBoxedFn *fn;
+
+	g_return_if_fail( NA_IS_DATA_BOXED( boxed ));
+	g_return_if_fail( NA_IS_DATA_BOXED( value ));
+	g_return_if_fail( boxed->private->def->type == value->private->def->type );
+
+	if( !boxed->private->dispose_has_run ){
+
+		fn = get_data_boxed_fn( boxed->private->def->type );
+
+		if( fn ){
+			if( fn->free ){
+				( *fn->free )( boxed );
+			}
+			if( fn->set_from_boxed ){
+				( *fn->set_from_boxed )( boxed, value );
+			}
+		}
+	}
+}
+
+/**
+ * na_data_boxed_set_from_string:
+ * @boxed: the #NADataBoxed whose value is to be set.
+ * @value: the string to be set.
+ *
+ * Evaluates the @value and set it to the @boxed.
+ */
+void
+na_data_boxed_set_from_string( NADataBoxed *boxed, const gchar *value )
+{
+	DataBoxedFn *fn;
+
+	g_return_if_fail( NA_IS_DATA_BOXED( boxed ));
+
+	if( !boxed->private->dispose_has_run ){
+
+		fn = get_data_boxed_fn( boxed->private->def->type );
+
+		if( fn ){
+			if( fn->free ){
+				( *fn->free )( boxed );
+			}
+			if( fn->set_from_string ){
+				( *fn->set_from_string )( boxed, value );
+			}
+		}
+	}
+}
+
+/**
+ * na_data_boxed_set_from_value:
+ * @boxed: the #NADataBoxed whose value is to be set.
+ * @value: the value whose content is to be got.
+ *
+ * Evaluates the @value and set it to the @boxed.
+ */
+void
+na_data_boxed_set_from_value( NADataBoxed *boxed, const GValue *value )
+{
+	DataBoxedFn *fn;
+
+	g_return_if_fail( NA_IS_DATA_BOXED( boxed ));
+
+	if( !boxed->private->dispose_has_run ){
+
+		fn = get_data_boxed_fn( boxed->private->def->type );
+
+		if( fn ){
+			if( fn->free ){
+				( *fn->free )( boxed );
+			}
+			if( fn->set_from_value ){
+				( *fn->set_from_value )( boxed, value );
+			}
+		}
+	}
+}
+
+/**
+ * na_data_boxed_set_from_void:
+ * @boxed: the #NADataBoxed whose value is to be set.
+ * @value: the value whose content is to be got.
+ *
+ * Evaluates the @value and set it to the @boxed.
+ */
+void
+na_data_boxed_set_from_void( NADataBoxed *boxed, const void *value )
+{
+	DataBoxedFn *fn;
+
+	g_return_if_fail( NA_IS_DATA_BOXED( boxed ));
+
+	if( !boxed->private->dispose_has_run ){
+
+		fn = get_data_boxed_fn( boxed->private->def->type );
+
+		if( fn ){
+			if( fn->free ){
+				( *fn->free )( boxed );
+			}
+			if( fn->set_from_void ){
+				( *fn->set_from_void )( boxed, value );
+			}
+		}
+	}
+}
+
+static GParamSpec *
+string_spec( const NADataDef *def )
+{
+	return( g_param_spec_string(
+			def->name,
+			def->short_label,
+			def->long_label,
+			def->default_value,
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+}
+
+static void
+string_free( const NADataBoxed *boxed )
+{
+	if( boxed->private->def->free ){
+		( *boxed->private->def->free )( boxed->private->u.string );
+	} else {
+		g_free( boxed->private->u.string );
+	}
+	boxed->private->u.string = NULL;
+}
+
+static void
+string_dump( const NADataBoxed *boxed )
+{
+	g_debug( "na-data-boxed: %s=%s", boxed->private->def->name, boxed->private->u.string );
+}
+
+static gboolean
+string_are_equal( const NADataBoxed *a, const NADataBoxed *b )
+{
+	if( !a->private->u.string && !b->private->u.string ){
+		return( TRUE );
+	}
+	if( !a->private->u.string || !b->private->u.string ){
+		return( FALSE );
+	}
+	return( strcmp( a->private->u.string, b->private->u.string ) == 0 );
+}
+
+static gboolean
+string_is_valid( const NADataBoxed *boxed )
+{
+	return( boxed->private->u.string && strlen( boxed->private->u.string ) > 0 );
+}
+
+static void *
+string_get_as_void( const NADataBoxed *boxed )
+{
+	void *value = NULL;
+
+	if( boxed->private->u.string ){
+		value = g_strdup( boxed->private->u.string );
+	}
+
+	return( value );
+}
+
+static void
+string_get_as_value( const NADataBoxed *boxed, GValue *value )
+{
+	g_value_set_string( value, boxed->private->u.string );
+}
+
+static void
+string_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source )
+{
+	boxed->private->u.string = g_strdup( source->private->u.string );
+}
+
+static void
+string_set_from_string( NADataBoxed *boxed, const gchar *string )
+{
+	if( string ){
+		boxed->private->u.string = g_strdup( string );
+	}
+}
+
+static void
+string_set_from_value( NADataBoxed *boxed, const GValue *value )
+{
+	if( g_value_get_string( value )){
+		boxed->private->u.string = g_value_dup_string( value );
+	}
+}
+
+static void
+string_set_from_void( NADataBoxed *boxed, const void *value )
+{
+	if( value ){
+		boxed->private->u.string = g_strdup(( const gchar * ) value );
+	}
+}
+
+static gboolean
+locale_are_equal( const NADataBoxed *a, const NADataBoxed *b )
+{
+	if( !a->private->u.string && !b->private->u.string ){
+		return( TRUE );
+	}
+	if( !a->private->u.string || !b->private->u.string ){
+		return( FALSE );
+	}
+	return( g_utf8_collate( a->private->u.string, b->private->u.string ) == 0 );
+}
+
+static gboolean
+locale_is_valid( const NADataBoxed *boxed )
+{
+	return( boxed->private->u.string && g_utf8_strlen( boxed->private->u.string, -1 ) > 0 );
+}
+
+static GParamSpec *
+slist_spec( const NADataDef *def )
+{
+	return( g_param_spec_pointer(
+			def->name,
+			def->short_label,
+			def->long_label,
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+}
+
+static void
+slist_free( const NADataBoxed *boxed )
+{
+	if( boxed->private->def->free ){
+		( *boxed->private->def->free )( boxed->private->u.slist );
+	} else {
+		na_core_utils_slist_free( boxed->private->u.slist );
+	}
+	boxed->private->u.slist = NULL;
+}
+
+static void
+slist_dump( const NADataBoxed *boxed )
+{
+	g_debug( "na-data-boxed: %s=", boxed->private->def->name );
+	na_core_utils_slist_dump( boxed->private->u.slist );
+}
+
+static gboolean
+slist_are_equal( const NADataBoxed *a, const NADataBoxed *b )
+{
+	if( !a->private->u.slist && !b->private->u.slist ){
+		return( TRUE );
+	}
+	if( !a->private->u.slist || !b->private->u.slist ){
+		return( FALSE );
+	}
+	return( na_core_utils_slist_are_equal( a->private->u.slist, b->private->u.slist ));
+}
+
+static gboolean
+slist_is_valid( const NADataBoxed *boxed )
+{
+	return( boxed->private->u.slist && g_slist_length( boxed->private->u.slist ) > 0 );
+}
+
+static void *
+slist_get_as_void( const NADataBoxed *boxed )
+{
+	void *value = NULL;
+
+	if( boxed->private->u.slist ){
+		value = na_core_utils_slist_duplicate( boxed->private->u.slist );
+	}
+
+	return( value );
+}
+
+static void
+slist_get_as_value( const NADataBoxed *boxed, GValue *value )
+{
+	g_value_set_pointer( value, na_core_utils_slist_duplicate( boxed->private->u.slist ));
+}
+
+static void
+slist_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source )
+{
+	boxed->private->u.slist = na_core_utils_slist_duplicate( source->private->u.slist );
+}
+
+static void
+slist_set_from_string( NADataBoxed *boxed, const gchar *string )
+{
+	GSList *slist;
+
+	if( string ){
+
+		/* if it is a string list which comes from GConf
+		 */
+		slist = na_gconf_utils_slist_from_string( string );
+
+		if( slist ){
+			boxed->private->u.slist = slist;
+
+		} else {
+			boxed->private->u.slist = g_slist_append( NULL, g_strdup( string ));
+		}
+	}
+}
+
+static void
+slist_set_from_value( NADataBoxed *boxed, const GValue *value )
+{
+	if( g_value_get_pointer( value )){
+		boxed->private->u.slist = na_core_utils_slist_duplicate( g_value_get_pointer( value ));
+	}
+}
+
+static void
+slist_set_from_void( NADataBoxed *boxed, const void *value )
+{
+	if( value ){
+		boxed->private->u.slist = na_core_utils_slist_duplicate(( GSList * ) value );
+	}
+}
+
+static GParamSpec *
+bool_spec( const NADataDef *def )
+{
+	return( g_param_spec_boolean(
+			def->name,
+			def->short_label,
+			def->long_label,
+			na_core_utils_boolean_from_string( def->default_value ),
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+}
+
+static void
+bool_free( const NADataBoxed *boxed )
+{
+	/* n/a */
+}
+
+static void
+bool_dump( const NADataBoxed *boxed )
+{
+	g_debug( "na-data-boxed: %s=%s",
+			boxed->private->def->name, boxed->private->u.boolean ? "True":"False" );
+}
+
+static gboolean
+bool_are_equal( const NADataBoxed *a, const NADataBoxed *b )
+{
+	return( a->private->u.boolean == b->private->u.boolean );
+}
+
+static gboolean
+bool_is_valid( const NADataBoxed *boxed )
+{
+	return( TRUE );
+}
+
+static void *
+bool_get_as_void( const NADataBoxed *boxed )
+{
+	return( GUINT_TO_POINTER( boxed->private->u.boolean ));
+}
+
+static void
+bool_get_as_value( const NADataBoxed *boxed, GValue *value )
+{
+	g_value_set_boolean( value, boxed->private->u.boolean );
+}
+
+static void
+bool_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source )
+{
+	boxed->private->u.boolean = source->private->u.boolean;
+}
+
+static void
+bool_set_from_string( NADataBoxed *boxed, const gchar *string )
+{
+	boxed->private->u.boolean = na_core_utils_boolean_from_string( string );
+}
+
+static void
+bool_set_from_value( NADataBoxed *boxed, const GValue *value )
+{
+	boxed->private->u.boolean = g_value_get_boolean( value );
+}
+
+static void
+bool_set_from_void( NADataBoxed *boxed, const void *value )
+{
+	boxed->private->u.boolean = GPOINTER_TO_UINT( value );
+}
+
+static GParamSpec *
+pointer_spec( const NADataDef *def )
+{
+	return( g_param_spec_pointer(
+			def->name,
+			def->short_label,
+			def->long_label,
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+}
+
+static void
+pointer_free( const NADataBoxed *boxed )
+{
+	if( boxed->private->def->free ){
+		( *boxed->private->def->free )( boxed->private->u.pointer );
+	}
+	boxed->private->u.pointer = NULL;
+}
+
+static void
+pointer_dump( const NADataBoxed *boxed )
+{
+	g_debug( "na-data-boxed: %s=%p",
+			boxed->private->def->name, ( void * ) boxed->private->u.pointer );
+}
+
+static gboolean
+pointer_are_equal( const NADataBoxed *a, const NADataBoxed *b )
+{
+	return( a->private->u.pointer == b->private->u.pointer );
+}
+
+static gboolean
+pointer_is_valid( const NADataBoxed *boxed )
+{
+	return( boxed->private->u.pointer != NULL );
+}
+
+static void *
+pointer_get_as_void( const NADataBoxed *boxed )
+{
+	return( boxed->private->u.pointer );
+}
+
+static void
+pointer_get_as_value( const NADataBoxed *boxed, GValue *value )
+{
+	g_value_set_pointer( value, boxed->private->u.pointer );
+}
+
+static void
+pointer_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source )
+{
+	boxed->private->u.pointer = source->private->u.pointer;
+}
+
+static void
+pointer_set_from_string( NADataBoxed *boxed, const gchar *pointer )
+{
+}
+
+static void
+pointer_set_from_value( NADataBoxed *boxed, const GValue *value )
+{
+	boxed->private->u.pointer = g_value_get_pointer( value );
+}
+
+static void
+pointer_set_from_void( NADataBoxed *boxed, const void *value )
+{
+	boxed->private->u.pointer = ( void * ) value;
+}
+
+static GParamSpec *
+uint_spec( const NADataDef *def )
+{
+	return( g_param_spec_uint(
+			def->name,
+			def->short_label,
+			def->long_label,
+			0,
+			UINT_MAX,
+			atoi( def->default_value ),
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+}
+
+static void
+uint_free( const NADataBoxed *boxed )
+{
+	boxed->private->u.uint = 0;
+}
+
+static void
+uint_dump( const NADataBoxed *boxed )
+{
+	g_debug( "na-data-boxed: %s=%d",
+			boxed->private->def->name, boxed->private->u.uint );
+}
+
+static gboolean
+uint_are_equal( const NADataBoxed *a, const NADataBoxed *b )
+{
+	return( a->private->u.uint == b->private->u.uint );
+}
+
+static gboolean
+uint_is_valid( const NADataBoxed *boxed )
+{
+	return( boxed->private->u.uint > 0 );
+}
+
+static void *
+uint_get_as_void( const NADataBoxed *boxed )
+{
+	return( GUINT_TO_POINTER( boxed->private->u.uint ));
+}
+
+static void
+uint_get_as_value( const NADataBoxed *boxed, GValue *value )
+{
+	g_value_set_uint( value, boxed->private->u.uint );
+}
+
+static void
+uint_set_from_boxed( NADataBoxed *boxed, const NADataBoxed *source )
+{
+	boxed->private->u.uint = source->private->u.uint;
+}
+
+static void
+uint_set_from_string( NADataBoxed *boxed, const gchar *string )
+{
+	boxed->private->u.uint = atoi( string );
+}
+
+static void
+uint_set_from_value( NADataBoxed *boxed, const GValue *value )
+{
+	boxed->private->u.uint = g_value_get_uint( value );
+}
+
+static void
+uint_set_from_void( NADataBoxed *boxed, const void *value )
+{
+	boxed->private->u.uint = GPOINTER_TO_UINT( value );
+}
diff --git a/src/core/na-factory-object.c b/src/core/na-factory-object.c
index 12fb852..60a45af 100644
--- a/src/core/na-factory-object.c
+++ b/src/core/na-factory-object.c
@@ -34,76 +34,125 @@
 
 #include <stdarg.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <api/na-core-utils.h>
+#include <api/na-data-types.h>
 #include <api/na-ifactory-provider.h>
+#include <api/na-data-boxed.h>
 
-#include "na-data-element.h"
 #include "na-factory-object.h"
+#if 0
+#include "na-ifactory-object-priv.h"
+#endif
 #include "na-factory-provider.h"
 
-typedef gboolean ( *IdGroupIterFunc )( NadfIdType *iddef, void *user_data );
+typedef gboolean ( *NADataDefIterFunc )( NADataDef *def, void *user_data );
 
 /* while iterating on read/write item
  */
 typedef struct {
-	NAIFactoryObject *object;
-	NAIFactoryProvider   *reader;
-	void           *reader_data;
-	GSList        **messages;
+	NAIFactoryObject   *object;
+	NAIFactoryProvider *reader;
+	void               *reader_data;
+	GSList            **messages;
 }
-	NadfRWIter;
+	NafoRWIter;
 
+#if 0
 /* while iterating on set defaults
  */
 typedef struct {
 	NAIFactoryObject *object;
-	gboolean        creation;
+	gboolean          creation;
 }
 	NadfNewIter;
+#endif
+
+#define NA_IFACTORY_OBJECT_PROP_DATA				"na-ifactory-object-prop-data"
+
+extern gboolean                   ifactory_object_initialized;
+extern gboolean                   ifactory_object_finalized;
+#if 0
+extern NAIFactoryObjectInterface *ifactory_object_klass;
+#endif
+
+static gboolean     define_class_properties_iter( const NADataDef *def, GObjectClass *class );
+static gboolean     factory_object_read_data_iter( NADataDef *def, NafoRWIter *iter );
+static gboolean     factory_object_write_data_iter( NADataDef *def, NafoRWIter *iter );
+
+static NADataGroup *v_get_groups( const NAIFactoryObject *object );
+static void         v_copy( NAIFactoryObject *target, const NAIFactoryObject *source );
+static gboolean     v_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
+static gboolean     v_is_valid( const NAIFactoryObject *object );
+static void         v_read_start( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+static void         v_read_done( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+static void         v_write_start( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+static void         v_write_done( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+
+static void         attach_boxed_to_object( NAIFactoryObject *object, NADataBoxed *boxed );
+static NADataBoxed *data_boxed_from_name( const NAIFactoryObject *object, const gchar *name );
+static void         free_data_boxed_list( NAIFactoryObject *object );
+static void         iter_on_data_defs( const NADataGroup *idgroups, gboolean serializable_only, NADataDefIterFunc pfn, void *user_data );
+
+#if 0
+static gboolean     factory_object_init_instance_iter( const NADataDef *def, NAIFactoryObject *object );
+static gchar       *v_get_default( const NAIFactoryObject *object, const NADataDef *def );
+#endif
 
-/* object values are set on a list of this structure
+#if 0
+/**
+ * na_factory_object_register_type:
+ * @type: the #GType of the implementation class.
+ * @groups: a table of #NADataGroup structures which defines the
+ *  serializable properties which will be attached to each instance of
+ *  this class.
+ *
+ * Registers the implementation #GType @type.
  */
-typedef struct {
-	NadfIdType    *iddef;
-	NADataElement *element;
-}
-	NadfDataValue;
+void
+na_factory_object_register_type( GType type, const NADataGroup *groups )
+{
+	static const gchar *thisfn = "na_factory_object_register_type";
+	NADataImplement *known;
+	NADataGroup *registered;
 
-#define NA_IFACTORY_OBJECT_PROP_DATA				"na-ifactory-object-prop-data"
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
+
+		g_debug( "%s: type=%lu, groups=%p",
+				thisfn, ( unsigned long ) type, ( void * ) groups );
 
-extern gboolean ifactory_object_initialized;		/* defined in na-ifactory-object.c */
-extern gboolean ifactory_object_finalized;		/* defined in na-ifactory-object.c */
-
-static gboolean       define_class_properties_iter( const NadfIdType *iddef, GObjectClass *class );
-static gboolean       factory_object_init_iter( const NadfIdType *iddef, NAIFactoryObject *object );
-static gchar         *v_get_default( const NAIFactoryObject *object, const NadfIdType *iddef );
-static void           v_copy( NAIFactoryObject *target, const NAIFactoryObject *source );
-static gboolean       v_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
-static gboolean       v_is_valid( const NAIFactoryObject *object );
-static void           factory_object_read_data( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, NadfIdGroup *groups, GSList **messages );
-static gboolean       factory_object_read_data_iter( NadfIdType *iddef, NadfRWIter *iter );
-static void           v_read_start( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
-static void           v_read_done( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
-static void           factory_object_write_data( NAIFactoryObject *serializable, const NAIFactoryProvider *writer, void *writer_data, NadfIdGroup *groups, GSList **messages );
-static gboolean       factory_object_write_data_iter( NadfIdType *iddef, NadfRWIter *iter );
-static void           v_write_start( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
-static void           v_write_done( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
-static NADataElement *data_element_from_id( const NAIFactoryObject *object, guint data_id );
-static void           iter_on_id_groups( const NadfIdGroup *idgroups, gboolean serializable_only, IdGroupIterFunc pfn, void *user_data );
-static void           free_gvalue( GValue *value, guint type );
+		g_return_if_fail( groups != NULL );
+
+		registered = na_factory_object_get_data_groups_from_type( type );
+		if( registered ){
+			g_warning( "%s: type=%lu: already registered", thisfn, ( unsigned long ) type );
+
+		} else {
+			/* register the implementation
+			 */
+			known = g_new0( NADataImplement, 1 );
+			known->type = type;
+			known->groups = ( NADataGroup * ) groups;
+
+			ifactory_object_klass->private->registered =
+					g_list_prepend( ifactory_object_klass->private->registered, known );
+		}
+	}
+}
+#endif
 
 /**
- * na_factory_object_properties:
+ * na_factory_object_define_properties:
  * @class: the #GObjectClass.
+ * @groups: the list of #NADataGroup structure which define the data of the class.
  *
- * Initializes the serializable properties.
+ * Initializes all the properties for the class.
  */
 void
-na_factory_object_properties( GObjectClass *class )
+na_factory_object_define_properties( GObjectClass *class, const NADataGroup *groups )
 {
-	static const gchar *thisfn = "na_factory_object_properties";
-	NadfIdGroup *groups;
+	static const gchar *thisfn = "na_factory_object_define_properties";
 
 	if( ifactory_object_initialized && !ifactory_object_finalized ){
 
@@ -114,193 +163,213 @@ na_factory_object_properties( GObjectClass *class )
 
 		/* define class properties
 		 */
-		groups = na_factory_provider_get_groups( G_OBJECT_CLASS_TYPE( class ));
-		if( groups ){
-			iter_on_id_groups(
-					groups,
-					FALSE,
-					( IdGroupIterFunc ) &define_class_properties_iter,
-					class );
-		}
+		iter_on_data_defs( groups, FALSE, ( NADataDefIterFunc ) &define_class_properties_iter, class );
 	}
 }
 
 static gboolean
-define_class_properties_iter( const NadfIdType *iddef, GObjectClass *class )
+define_class_properties_iter( const NADataDef *def, GObjectClass *class )
 {
 	static const gchar *thisfn = "na_factory_object_define_class_properties_iter";
 	gboolean stop;
 	GParamSpec *spec;
 
-	g_debug( "%s: iddef=%s", thisfn, iddef->name );
+	g_debug( "%s: def=%p (%s)", thisfn, ( void * ) def, def->name );
 
 	stop = FALSE;
 
-	switch( iddef->type ){
-
-		case NADF_TYPE_LOCALE_STRING:
-		case NADF_TYPE_STRING:
-		case NADF_TYPE_BOOLEAN:
-		case NADF_TYPE_STRING_LIST:
-		case NADF_TYPE_POINTER:
-			spec = g_param_spec_pointer(
-					iddef->name,
-					iddef->short_label,
-					iddef->long_label,
-					G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-			g_object_class_install_property( class, iddef->id, spec );
-			break;
-
-		case NADF_TYPE_UINT:
-			spec = g_param_spec_uint(
-					iddef->name,
-					iddef->short_label,
-					iddef->long_label,
-					0, UINT_MAX, atoi( iddef->default_value ),
-					G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-			g_object_class_install_property( class, iddef->id, spec );
-			break;
-
-		default:
-			g_debug( "%s: type=%d", thisfn, iddef->type );
-			g_return_val_if_reached( FALSE );
+	if( !def->obsoleted ){
+		spec = na_data_boxed_get_param_spec( def );
+
+		if( spec ){
+			g_object_class_install_property( class, g_quark_from_string( def->name ), spec );
+
+		} else {
+			g_warning( "%s: type=%d: unable to get a spec", thisfn, def->type );
+		}
 	}
 
 	return( stop );
 }
 
 /**
- * na_factory_object_new:
- * @type: the GType type of the object we want allocate.
+ * na_factory_object_get_data_def:
+ * @object: this #NAIFactoryObject object.
+ * @name: the searched name.
  *
- * Returns: a newly allocated #NAObject-derived object, or %NULL.
+ * Returns: the #NADataDef structure which describes this @name, or %NULL.
+ */
+NADataDef *
+na_factory_object_get_data_def( const NAIFactoryObject *object, const gchar *name )
+{
+	NADataDef *def;
+
+	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
+
+	def = NULL;
+
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
+
+		NADataGroup *groups = v_get_groups( object );
+		while( groups->group ){
+
+			NADataDef *def = groups->def;
+			if( def ){
+				while( def->name ){
+
+					if( !strcmp( def->name, name )){
+						return( def );
+					}
+					def++;
+				}
+			}
+			groups++;
+		}
+	}
+
+	return( def );
+}
+
+/**
+ * na_factory_object_get_data_groups:
+ * @object: the #NAIFactoryObject instance.
  *
- * The function checks that @type has been previously registered in the
- * data factory management system (cf. #na_factory_object_init_class()),
- * and if so invoke an empty constructor with this @type.
+ * Returns: a pointer to the list of #NADataGroup which define the data.
  */
-NAIFactoryObject *
-na_factory_object_new( GType type )
+NADataGroup *
+na_factory_object_get_data_groups( const NAIFactoryObject *object )
 {
-	NAIFactoryObject *object;
-	NadfIdGroup *groups;
+	NADataGroup *groups;
 
-	object = NULL;
+	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
 
-	/* check that @type has been registered
-	 */
-	groups = na_factory_provider_get_groups( type );
-	if( groups ){
+	groups = NULL;
 
-		object = NA_IFACTORY_OBJECT( g_object_new( type, NULL ));
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
+
+		groups = v_get_groups( object );
 	}
 
-	return( object );
+	return( groups );
 }
 
 /**
- * na_factory_object_init:
- * @object: the #NAIFactoryObject being initialized.
+ * na_factory_object_iter_on_boxed:
+ * @object: this #NAIFactoryObject object.
+ * @fn: the function to be called.
+ * @user_data: data to be provided to the user function.
  *
- * Initializes properties attached to the @object.
+ * Iterate on each #NADataBoxed attached to the @object.
  *
- * This essentially consists of creating a #NADataElement for each
- * defined elementary data, initializing it to its default value.
+ * The @fn called function may return %TRUE to stop the iteration.
  */
 void
-na_factory_object_init( NAIFactoryObject *object )
+na_factory_object_iter_on_boxed( const NAIFactoryObject *object, NAFactoryObjectIterBoxedFn pfn, void *user_data )
 {
-	static const gchar *thisfn = "na_factory_object_init";
-	NadfIdGroup *groups;
+	GList *list, *ibox;
+	gboolean stop;
 
-	g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
 	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	groups = na_factory_provider_get_groups( G_OBJECT_TYPE( object ));
-	if( groups ){
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
 
-		iter_on_id_groups( groups, FALSE, ( IdGroupIterFunc ) &factory_object_init_iter, object );
+		list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
+		/*g_debug( "list=%p (count=%u)", ( void * ) list, g_list_length( list ));*/
+		stop = FALSE;
+
+		for( ibox = list ; ibox && !stop ; ibox = ibox->next ){
+			stop = ( *pfn )( object, NA_DATA_BOXED( ibox->data ), user_data );
+		}
 	}
 }
 
-static gboolean
-factory_object_init_iter( const NadfIdType *iddef, NAIFactoryObject *object )
+/**
+ * na_factory_object_attach_with_default:
+ * @object: this #NAIFactoryObject object.
+ * @name: a #NADataDef name.
+ *
+ * Attach a new #NADataBoxed element to this @object, initializing it
+ * with its default value.
+ */
+void
+na_factory_object_attach_with_default( NAIFactoryObject *object, const gchar *name )
 {
-	gboolean stop;
-	GList *list;
-	NADataElement *element;
-	NadfDataValue *data;
-	gchar *default_value;
+	static const gchar *thisfn = "na_factory_object_attach_with_default";
 
-	stop = FALSE;
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	default_value = v_get_default( object, iddef );
-	element = na_data_element_new( iddef );
-	na_data_element_set_from_string( element, ( const void * )( default_value ? default_value : iddef->default_value ));
-	g_free( default_value );
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
 
-	data = g_new0( NadfDataValue, 1 );
-	data->iddef = ( NadfIdType * ) iddef;
-	data->element = element;
+		NADataDef *def = na_factory_object_get_data_def( object, name );
 
-	list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
-	list = g_list_prepend( list, data );
-	g_object_set_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA, list );
+		if( !def ){
+			g_warning( "%s: no NADataDef found for %s", thisfn, name );
 
-	return( stop );
+		} else {
+			NADataBoxed *boxed = na_data_boxed_new( def );
+			na_data_boxed_set_default( boxed );
+			attach_boxed_to_object( object, boxed );
+		}
+	}
 }
 
 /**
- * na_factory_object_copy:
+ * na_factory_object_move_boxed:
  * @target: the target #NAIFactoryObject instance.
  * @source: the source #NAIFactoryObject instance.
+ * @boxed: a #NADataBoxed.
  *
- * Copies one instance to another.
+ * Move the @boxed from @source to @target, detaching from @source list
+ * to be attached to @target one.
  */
 void
-na_factory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source )
+na_factory_object_move_boxed( NAIFactoryObject *target, const NAIFactoryObject *source, NADataBoxed *boxed )
 {
-	GList *src_list, *isrc;
-	NadfDataValue *src_data;
-	NADataElement *tgt_element;
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( target ));
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( source ));
 
-	src_list = g_object_get_data( G_OBJECT( source ), NA_IFACTORY_OBJECT_PROP_DATA );
-	for( isrc = src_list ; isrc ; isrc = isrc->next ){
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
 
-		src_data = ( NadfDataValue * ) isrc->data;
-		if( src_data->iddef->copyable ){
+		GList *src_list = g_object_get_data( G_OBJECT( source ), NA_IFACTORY_OBJECT_PROP_DATA );
 
-			tgt_element = data_element_from_id( target, src_data->iddef->id );
-			if( tgt_element ){
+		if( g_list_find( src_list, boxed )){
+			src_list = g_list_remove( src_list, boxed );
+			g_object_set_data( G_OBJECT( source ), NA_IFACTORY_OBJECT_PROP_DATA, src_list );
 
-				na_data_element_set( tgt_element, src_data->element );
-			}
+			attach_boxed_to_object( target, boxed );
 		}
 	}
-
-	v_copy( target, source );
 }
 
-static gchar *
-v_get_default( const NAIFactoryObject *object, const NadfIdType *iddef )
+/**
+ * na_factory_object_copy:
+ * @target: the target #NAIFactoryObject instance.
+ * @source: the source #NAIFactoryObject instance.
+ *
+ * Copies one instance to another.
+ */
+void
+na_factory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source )
 {
-	gchar *default_value;
+	GList *src_list, *isrc;
 
-	default_value = NULL;
+	free_data_boxed_list( target );
 
-	if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_default ){
-		default_value = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_default( object, iddef );
-	}
+	src_list = g_object_get_data( G_OBJECT( source ), NA_IFACTORY_OBJECT_PROP_DATA );
 
-	return( default_value );
-}
+	for( isrc = src_list ; isrc ; isrc = isrc->next ){
 
-static void
-v_copy( NAIFactoryObject *target, const NAIFactoryObject *source )
-{
-	if( NA_IFACTORY_OBJECT_GET_INTERFACE( target )->copy ){
-		NA_IFACTORY_OBJECT_GET_INTERFACE( target )->copy( target, source );
+		NADataBoxed *src_boxed = NA_DATA_BOXED( isrc->data );
+		NADataDef *def = na_data_boxed_get_data_def( src_boxed );
+		if( def->copyable ){
+
+			NADataBoxed *tgt_boxed = na_data_boxed_new( def );
+			na_data_boxed_set_from_boxed( tgt_boxed, src_boxed );
+			attach_boxed_to_object( target, tgt_boxed );
+		}
 	}
+
+	v_copy( target, source );
 }
 
 /**
@@ -315,8 +384,6 @@ na_factory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *
 {
 	gboolean are_equal;
 	GList *a_list, *b_list, *ia;
-	NadfDataValue *a_data;
-	NADataElement *b_element;
 
 	are_equal = FALSE;
 
@@ -328,12 +395,13 @@ na_factory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *
 		are_equal = TRUE;
 		for( ia = a_list ; ia && are_equal ; ia = ia->next ){
 
-			a_data = ( NadfDataValue * ) ia->data;
-			if( a_data->iddef->comparable ){
+			NADataBoxed *a_boxed = NA_DATA_BOXED( ia->data );
+			NADataDef *a_def = na_data_boxed_get_data_def( a_boxed );
+			if( a_def->comparable ){
 
-				b_element = data_element_from_id( b, a_data->iddef->id );
-				if( b_element ){
-					are_equal = na_data_element_are_equal( a_data->element, b_element);
+				NADataBoxed *b_boxed = data_boxed_from_name( b, a_def->name );
+				if( b_boxed ){
+					are_equal = na_data_boxed_are_equal( a_boxed, b_boxed );
 
 				} else {
 					are_equal = FALSE;
@@ -349,20 +417,6 @@ na_factory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *
 	return( are_equal );
 }
 
-static gboolean
-v_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b )
-{
-	gboolean are_equal;
-
-	are_equal = TRUE;
-
-	if( NA_IFACTORY_OBJECT_GET_INTERFACE( a )->are_equal ){
-		are_equal = NA_IFACTORY_OBJECT_GET_INTERFACE( a )->are_equal( a, b );
-	}
-
-	return( are_equal );
-}
-
 /**
  * na_factory_object_is_valid:
  * @object: the #NAIFactoryObject instance whose validity is to be checked.
@@ -374,25 +428,22 @@ na_factory_object_is_valid( const NAIFactoryObject *object )
 {
 	static const gchar *thisfn = "na_factory_object_is_valid";
 	gboolean is_valid;
-	GList *list_values, *iv;
-	NadfDataValue *a_data;
-
-	g_debug( "%s: object=%p (%s)",
-			thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+	GList *list, *iv;
 
 	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), FALSE );
 
-	list_values = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
+	list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
 	is_valid = TRUE;
 
-	for( iv = list_values ; iv && is_valid ; iv = iv->next ){
+	for( iv = list ; iv && is_valid ; iv = iv->next ){
 
-		a_data = ( NadfDataValue * ) iv->data;
-		if( a_data->iddef->mandatory ){
+		NADataBoxed *boxed = NA_DATA_BOXED( iv->data );
+		NADataDef *def = na_data_boxed_get_data_def( boxed );
+		if( def->mandatory ){
 
-			is_valid = na_data_element_is_valid( a_data->element );
+			is_valid = na_data_boxed_is_valid( boxed );
 			if( !is_valid ){
-				g_debug( "%s: invalid element: %s", thisfn, a_data->iddef->name );
+				g_debug( "%s: %s: invalid", thisfn, def->name );
 			}
 		}
 	}
@@ -404,20 +455,6 @@ na_factory_object_is_valid( const NAIFactoryObject *object )
 	return( is_valid );
 }
 
-static gboolean
-v_is_valid( const NAIFactoryObject *object )
-{
-	gboolean is_valid;
-
-	is_valid = TRUE;
-
-	if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid ){
-		is_valid = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid( object );
-	}
-
-	return( is_valid );
-}
-
 /**
  * na_factory_object_dump:
  * @object: this #NAIFactoryObject instance.
@@ -428,43 +465,92 @@ void
 na_factory_object_dump( const NAIFactoryObject *object )
 {
 	GList *list, *it;
-	NadfDataValue *str;
 
 	list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
 
 	for( it = list ; it ; it = it->next ){
 
-		str = ( NadfDataValue * ) it->data;
-		na_data_element_dump( str->element );
+		na_data_boxed_dump( NA_DATA_BOXED( it->data ));
 	}
 }
 
+#if 0
 /**
- * na_factory_object_finalize:
- * @object: the #NAIFactoryObject being finalized.
+ * na_factory_object_init_instance:
+ * @object: the #NAIFactoryObject being initialized.
  *
- * Clears all data associated with this @object.
+ * Initializes properties attached to the @object.
+ *
+ * This essentially consists of creating a #NADataBoxed for each
+ * defined elementary data, initializing it to its default value.
  */
 void
-na_factory_object_finalize( NAIFactoryObject *object )
+na_factory_object_init_instance( NAIFactoryObject *object )
 {
-	GList *list, *it;
-	NadfDataValue *str;
+	static const gchar *thisfn = "na_factory_object_init_instance";
+	NADataGroup *groups;
 
-	list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
+	g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	for( it = list ; it ; it = it->next ){
+	/* do not allocate any NADataBoxed now
+	 * just ensure that the GList which will host them is initialized
+	 */
+	g_object_set_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA, NULL );
 
-		str = ( NadfDataValue * ) it->data;
-		g_object_unref( str->element );
-		g_free( str );
+	if( FALSE ){
+		groups = na_factory_object_get_data_groups_from_type( G_OBJECT_TYPE( object ));
+		if( groups ){
+			iter_on_data_defs( groups, FALSE, ( NADataDefIterFunc ) &factory_object_init_instance_iter, object );
+
+		} else {
+			g_warning( "%s: class=%s: groups not found", thisfn, G_OBJECT_TYPE_NAME( object ));
+		}
 	}
+}
 
-	g_list_free( list );
+static gboolean
+factory_object_init_instance_iter( const NADataDef *def, NAIFactoryObject *object )
+{
+	gboolean stop;
+	GList *list;
+	NADataBoxed *element;
+	NadfDataValue *data;
+	gchar *default_value;
+
+	stop = FALSE;
+
+	default_value = v_get_default( object, def );
+	element = na_data_boxed_new( def );
+	na_data_boxed_set_from_string( element, ( const void * )( default_value ? default_value : def->default_value ));
+	g_free( default_value );
+
+	data = g_new0( NadfDataValue, 1 );
+	data->def = ( NADataDef * ) def;
+	data->element = element;
+
+	list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
+	list = g_list_prepend( list, data );
+	g_object_set_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA, list );
+
+	return( stop );
 }
+#endif
 
 /**
- * na_factory_object_read:
+ * na_factory_object_finalize_instance:
+ * @object: the #NAIFactoryObject being finalized.
+ *
+ * Clears all data associated with this @object.
+ */
+void
+na_factory_object_finalize_instance( NAIFactoryObject *object )
+{
+	free_data_boxed_list( object );
+}
+
+/**
+ * na_factory_object_read_item:
  * @serializable: this #NAIFactoryObject instance.
  * @reader: the #NAIFactoryProvider which is at the origin of this read.
  * @reader_data: reader data.
@@ -474,102 +560,66 @@ na_factory_object_finalize( NAIFactoryObject *object )
  * Unserializes the object.
  */
 void
-na_factory_object_read( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
+na_factory_object_read_item( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
 {
-	static const gchar *thisfn = "na_factory_object_read";
-	NadfIdGroup *groups;
-	gchar *msg;
+	static const gchar *thisfn = "na_factory_object_read_item";
 
 	if( ifactory_object_initialized && !ifactory_object_finalized ){
 
 		g_return_if_fail( NA_IS_IFACTORY_OBJECT( serializable ));
 		g_return_if_fail( NA_IS_IFACTORY_PROVIDER( reader ));
 
-		groups = na_factory_provider_get_groups( G_OBJECT_TYPE( serializable ));
+		NADataGroup *groups = v_get_groups( serializable );
 
 		if( groups ){
+			free_data_boxed_list( serializable );
 			v_read_start( serializable, reader, reader_data, messages );
-			factory_object_read_data( serializable, reader, reader_data, groups, messages );
+
+			NafoRWIter *iter = g_new0( NafoRWIter, 1 );
+			iter->object = serializable;
+			iter->reader = ( NAIFactoryProvider * ) reader;
+			iter->reader_data = reader_data;
+			iter->messages = messages;
+
+			iter_on_data_defs( groups, TRUE, ( NADataDefIterFunc ) &factory_object_read_data_iter, iter );
+
+			g_free( iter );
+
 			v_read_done( serializable, reader, reader_data, messages );
 
 		} else {
-			msg = g_strdup_printf( "%s: instance %s doesn't return any NadfIdGroup structure",
+			g_warning( "%s: class %s doesn't return any NADataGroup structure",
 					thisfn, G_OBJECT_TYPE_NAME( serializable ));
-			g_warning( "%s", msg );
-			*messages = g_slist_append( *messages, msg );
 		}
 	}
 }
 
-/*
- * factory_object_read_data:
- * @serializable: this #NAIFactoryObject instance.
- * @reader: the #NAIFactoryProvider which is at the origin of this read.
- * @reader_data: reader data.
- * @groups: the list of NadfIdGroup structure which define @serializable.
- * @messages: a pointer to a #GSList list of strings; the implementation
- *  may append messages to this list, but shouldn't reinitialize it.
- *
- * Unserializes the object.
- */
-static void
-factory_object_read_data( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, NadfIdGroup *groups, GSList **messages )
-{
-	NadfRWIter *iter;
-
-	iter = g_new0( NadfRWIter, 1 );
-	iter->object = serializable;
-	iter->reader = ( NAIFactoryProvider * ) reader;
-	iter->reader_data = reader_data;
-	iter->messages = messages;
-
-	iter_on_id_groups( groups, TRUE, ( IdGroupIterFunc ) &factory_object_read_data_iter, iter );
-
-	g_free( iter );
-}
-
 static gboolean
-factory_object_read_data_iter( NadfIdType *iddef, NadfRWIter *iter )
+factory_object_read_data_iter( NADataDef *def, NafoRWIter *iter )
 {
 	gboolean stop;
-	GValue *value;
-	NADataElement *element;
 
 	stop = FALSE;
 
-	value = na_factory_provider_read_value( iter->reader, iter->reader_data, iddef, iter->messages );
-	if( value ){
+	NADataBoxed *boxed = na_factory_provider_read_data( iter->reader, iter->reader_data, iter->object, def, iter->messages );
 
-		element = data_element_from_id( iter->object, iddef->id );
-		if( element ){
+	if( boxed ){
+		NADataBoxed *exist = data_boxed_from_name( iter->object, def->name );
 
-			na_data_element_set_from_value( element, value );
-		}
+		if( exist ){
+			na_data_boxed_set_from_boxed( exist, boxed );
+			g_object_unref( boxed );
 
-		free_gvalue( value, iddef->type );
+		} else {
+			attach_boxed_to_object( iter->object, boxed );
+		}
 	}
 
 	return( stop );
 }
 
-static void
-v_read_start( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
-{
-	if( NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->read_start ){
-		NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->read_start( serializable, reader, reader_data, messages );
-	}
-}
-
-static void
-v_read_done( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
-{
-	if( NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->read_done ){
-		NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->read_done( serializable, reader, reader_data, messages );
-	}
-}
-
 /**
- * na_factory_object_write:
+ * na_factory_object_write_item:
  * @serializable: this #NAIFactoryObject instance.
  * @writer: the #NAIFactoryProvider which is at the origin of this write.
  * @writer_data: writer data.
@@ -579,292 +629,427 @@ v_read_done( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, v
  * Serializes the object down to the @writer.
  */
 void
-na_factory_object_write( NAIFactoryObject *serializable, const NAIFactoryProvider *writer, void *writer_data, GSList **messages )
+na_factory_object_write_item( NAIFactoryObject *serializable, const NAIFactoryProvider *writer, void *writer_data, GSList **messages )
 {
-	static const gchar *thisfn = "na_factory_object_write";
-	NadfIdGroup *groups;
+	static const gchar *thisfn = "na_factory_object_write_item";
+	NADataGroup *groups;
 	gchar *msg;
 
 	g_return_if_fail( NA_IS_IFACTORY_OBJECT( serializable ));
 	g_return_if_fail( NA_IS_IFACTORY_PROVIDER( writer ));
 
-	groups = na_factory_provider_get_groups( G_OBJECT_TYPE( serializable ));
-
+	groups = v_get_groups( serializable );
 	if( groups ){
+
 		v_write_start( serializable, writer, writer_data, messages );
-		factory_object_write_data( serializable, writer, writer_data, groups, messages );
+
+		NafoRWIter *iter = g_new0( NafoRWIter, 1 );
+		iter->object = serializable;
+		iter->reader = ( NAIFactoryProvider * ) writer;
+		iter->reader_data = writer_data;
+		iter->messages = messages;
+
+		iter_on_data_defs( groups, TRUE, ( NADataDefIterFunc ) &factory_object_write_data_iter, iter );
+
+		g_free( iter );
+
 		v_write_done( serializable, writer, writer_data, messages );
 
 	} else {
-		msg = g_strdup_printf( "%s: instance %s doesn't return any NadfIdGroup structure",
+		msg = g_strdup_printf( "%s: class %s doesn't return any NADataGroup structure",
 				thisfn, G_OBJECT_TYPE_NAME( serializable ));
 		g_warning( "%s", msg );
 		*messages = g_slist_append( *messages, msg );
 	}
 }
 
-/*
- * factory_object_write_data:
- * @serializable: this #NAIFactoryObject instance.
- * @writer: the #NAIFactoryProvider which is at the origin of this writ.
- * @writer_data: writer data.
- * @groups: the list of NadfIdGroup structure which define @serializable.
- * @messages: a pointer to a #GSList list of strings; the implementation
- *  may append messages to this list, but shouldn't reinitialize it.
- *
- * Serializes the object.
- */
-static void
-factory_object_write_data( NAIFactoryObject *serializable, const NAIFactoryProvider *writer, void *writer_data, NadfIdGroup *groups, GSList **messages )
-{
-	NadfRWIter *iter;
-
-	iter = g_new0( NadfRWIter, 1 );
-	iter->object = serializable;
-	iter->reader = ( NAIFactoryProvider * ) writer;
-	iter->reader_data = writer_data;
-	iter->messages = messages;
-
-	iter_on_id_groups( groups, TRUE, ( IdGroupIterFunc ) &factory_object_write_data_iter, iter );
-
-	g_free( iter );
-}
-
 static gboolean
-factory_object_write_data_iter( NadfIdType *iddef, NadfRWIter *iter )
+factory_object_write_data_iter( NADataDef *def, NafoRWIter *iter )
 {
 	gboolean stop;
 
 	stop = FALSE;
 
-	/*na_factory_provider_set_value( iter->reader, iter->reader_data, iddef, iter->messages );*/
+	/*na_factory_provider_set_value( iter->reader, iter->reader_data, def, iter->messages );*/
 
 	return( stop );
 }
 
-static void
-v_write_start( NAIFactoryObject *serializable, const NAIFactoryProvider *writer, void *writer_data, GSList **messages )
+#if 0
+/**
+ * na_factory_provider_get_data_groups:
+ * @type: a previously registered #GType.
+ *
+ * Returns the #NADataGroups table which has been registered for this @type,
+ * or %NULL.
+ */
+NADataGroup *
+na_factory_object_get_data_groups_from_type( GType type )
 {
-	if( NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->write_start ){
-		NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->write_start( serializable, writer, writer_data, messages );
-	}
-}
+	GList *it;
 
-static void
-v_write_done( NAIFactoryObject *serializable, const NAIFactoryProvider *writer, void *writer_data, GSList **messages )
-{
-	if( NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->write_done ){
-		NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->write_done( serializable, writer, writer_data, messages );
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
+
+		for( it = ifactory_object_klass->private->registered ; it ; it = it->next ){
+			if((( NADataImplement * ) it->data )->type == type ){
+				return((( NADataImplement * ) it->data )->groups );
+			}
+		}
 	}
+
+	return( NULL );
 }
+#endif
 
 /**
- * na_factory_object_set_from_string:
+ * na_factory_object_get_as_value:
  * @object: this #NAIFactoryObject instance.
  * @property_id: the elementary data id.
- * @string: the string to be set in the element.
+ * @value: the #GValue to be set.
+ * @spec: the #GParamSpec which describes this data.
  *
- * Set the @object with the @string.
+ * Set the @value with the current content of the #NADataBoxed attached
+ * to @property_id.
+ *
+ * This is to be readen as "set value from data element".
  */
 void
-na_factory_object_set_from_string( NAIFactoryObject *object, guint data_id, const gchar *string )
+na_factory_object_get_as_value( const NAIFactoryObject *object, const gchar *name, GValue *value )
 {
-	static const gchar *thisfn = "na_factory_object_set_from_string";
-	NADataElement *element;
+	NADataBoxed *boxed;
 
 	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	element = data_element_from_id( object, data_id );
-	if( element ){
-		na_data_element_set_from_string( element, string );
+	g_value_unset( value );
 
-	} else {
-		g_warning( "%s: unknown property id %d", thisfn, data_id );
+	boxed = data_boxed_from_name( object, name );
+	if( boxed ){
+		na_data_boxed_get_as_value( boxed, value );
 	}
 }
 
 /**
+ * na_factory_object_get_as_void:
+ * @object: this #NAIFactoryObject instance.
+ * @name: the elementary data whose value is to be got.
+ *
+ * Returns: the searched value.
+ *
+ * If the type of the value is NAFD_TYPE_STRING, NAFD_TYPE_LOCALE_STRING,
+ * or NAFD_TYPE_STRING_LIST, then the returned value is a newly allocated
+ * one and should be g_free() (resp. na_core_utils_slist_free()) by the
+ * caller.
+ */
+void *
+na_factory_object_get_as_void( const NAIFactoryObject *object, const gchar *name )
+{
+	void *value;
+	NADataBoxed *boxed;
+
+	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
+
+	value = NULL;
+
+	boxed = data_boxed_from_name( object, name );
+	if( boxed ){
+		value = na_data_boxed_get_as_void( boxed );
+	}
+
+	return( value );
+}
+
+/**
  * na_factory_object_set_from_value:
  * @object: this #NAIFactoryObject instance.
- * @property_id: the elementary data id.
+ * @name: the elementary data id.
  * @value: the #GValue whose content is to be got.
  *
- * Get from the @value the content to be set in the #NADataElement
+ * Get from the @value the content to be set in the #NADataBoxed
  * attached to @property_id.
- *
- * This is to be readen as "set data element from value".
  */
 void
-na_factory_object_set_from_value( NAIFactoryObject *object, guint data_id, const GValue *value )
+na_factory_object_set_from_value( NAIFactoryObject *object, const gchar *name, const GValue *value )
 {
 	static const gchar *thisfn = "na_factory_object_set_from_value";
-	NADataElement *element;
 
 	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	element = data_element_from_id( object, data_id );
-	if( element ){
-		na_data_element_set_from_value( element, value );
+	NADataBoxed *boxed = data_boxed_from_name( object, name );
+	if( boxed ){
+		na_data_boxed_set_from_value( boxed, value );
 
 	} else {
-		g_warning( "%s: unknown property id %d", thisfn, data_id );
+		NADataDef *def = na_factory_object_get_data_def( object, name );
+		if( !def ){
+			g_warning( "%s: unknown NADataDef %s", thisfn, name );
+
+		} else {
+			boxed = na_data_boxed_new( def );
+			na_data_boxed_set_from_value( boxed, value );
+			attach_boxed_to_object( object, boxed );
+		}
 	}
 }
 
 /**
  * na_factory_object_set_from_void:
  * @object: this #NAIFactoryObject instance.
- * @data_id: the elementary data whose value is to be set.
+ * @name: the elementary data whose value is to be set.
  * @data: the value to set.
  *
  * Set the elementary data with the given value.
  */
 void
-na_factory_object_set_from_void( NAIFactoryObject *object, guint data_id, const void *data )
+na_factory_object_set_from_void( NAIFactoryObject *object, const gchar *name, const void *data )
 {
 	static const gchar *thisfn = "na_factory_object_set_from_void";
-	NADataElement *element;
-
-	/*g_debug( "%s: object=%p (%s), data_id=%d, data=%p",
-			thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ), data_id, ( void * ) data );*/
 
 	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	element = data_element_from_id( object, data_id );
-	if( element ){
-		na_data_element_set_from_void( element, data );
+	NADataBoxed *boxed = data_boxed_from_name( object, name );
+	if( boxed ){
+		na_data_boxed_set_from_void( boxed, data );
 
 	} else {
-		g_warning( "%s: unknown property id %d", thisfn, data_id );
+		NADataDef *def = na_factory_object_get_data_def( object, name );
+		if( !def ){
+			g_warning( "%s: unknown NADataDef %s", thisfn, name );
+
+		} else {
+			boxed = na_data_boxed_new( def );
+			na_data_boxed_set_from_void( boxed, data );
+			attach_boxed_to_object( object, boxed );
+		}
+	}
+}
+
+static NADataGroup *
+v_get_groups( const NAIFactoryObject *object )
+{
+	NADataGroup *groups;
+
+	groups = NULL;
+
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_groups ){
+		groups = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_groups( object );
+	}
+
+	return( groups );
+}
+
+static void
+v_copy( NAIFactoryObject *target, const NAIFactoryObject *source )
+{
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( target )->copy ){
+		NA_IFACTORY_OBJECT_GET_INTERFACE( target )->copy( target, source );
+	}
+}
+
+static gboolean
+v_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b )
+{
+	gboolean are_equal;
+
+	are_equal = TRUE;
+
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( a )->are_equal ){
+		are_equal = NA_IFACTORY_OBJECT_GET_INTERFACE( a )->are_equal( a, b );
+	}
+
+	return( are_equal );
+}
+
+static gboolean
+v_is_valid( const NAIFactoryObject *object )
+{
+	gboolean is_valid;
+
+	is_valid = TRUE;
+
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid ){
+		is_valid = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid( object );
 	}
+
+	return( is_valid );
 }
 
+#if 0
 /**
- * na_factory_object_get:
- * @object: this #NAIFactoryObject instance.
- * @data_id: the elementary data whose value is to be got.
+ * na_factory_object_new:
+ * @type: the GType type of the object we want allocate.
  *
- * Returns: the searched value.
+ * Returns: a newly allocated #NAObject-derived object, or %NULL.
  *
- * If the type of the value is NADF_TYPE_STRING, NADF_TYPE_LOCALE_STRING,
- * or NADF_TYPE_STRING_LIST, then the returned value is a newly allocated
- * one and should be g_free() (resp. na_core_utils_slist_free()) by the
- * caller.
+ * The function checks that @type has been previously registered in the
+ * data factory management system (cf. #na_factory_object_init_class()),
+ * and if so invoke an empty constructor with this @type.
  */
-void *
-na_factory_object_get( const NAIFactoryObject *object, guint data_id )
+NAIFactoryObject *
+na_factory_object_new( GType type )
 {
-	static const gchar *thisfn = "na_factory_object_get";
-	void *value;
-	NADataElement *element;
+	NAIFactoryObject *object;
+	NADataGroup *groups;
 
-	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
+	object = NULL;
 
-	value = NULL;
+	/* check that @type has been registered
+	 */
+	groups = na_factory_object_get_data_groups_from_type( type );
+	if( groups ){
 
-	element = data_element_from_id( object, data_id );
-	if( element ){
-		value = na_data_element_get( element );
+		object = NA_IFACTORY_OBJECT( g_object_new( type, NULL ));
+	}
 
-	} else {
-		g_warning( "%s: unknown property id %d", thisfn, data_id );
+	return( object );
+}
+
+static gchar *
+v_get_default( const NAIFactoryObject *object, const NADataDef *def )
+{
+	gchar *default_value;
+
+	default_value = NULL;
+
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_default ){
+		default_value = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_default( object, def );
 	}
 
-	return( value );
+	return( default_value );
 }
+#endif
 
+static void
+v_read_start( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
+{
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->read_start ){
+		NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->read_start( serializable, reader, reader_data, messages );
+	}
+}
+
+static void
+v_read_done( NAIFactoryObject *serializable, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
+{
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->read_done ){
+		NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->read_done( serializable, reader, reader_data, messages );
+	}
+}
+
+static void
+v_write_start( NAIFactoryObject *serializable, const NAIFactoryProvider *writer, void *writer_data, GSList **messages )
+{
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->write_start ){
+		NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->write_start( serializable, writer, writer_data, messages );
+	}
+}
+
+static void
+v_write_done( NAIFactoryObject *serializable, const NAIFactoryProvider *writer, void *writer_data, GSList **messages )
+{
+	if( NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->write_done ){
+		NA_IFACTORY_OBJECT_GET_INTERFACE( serializable )->write_done( serializable, writer, writer_data, messages );
+	}
+}
+
+#if 0
 /**
- * na_factory_object_set_value:
+ * na_factory_object_set_from_string:
  * @object: this #NAIFactoryObject instance.
  * @property_id: the elementary data id.
- * @value: the #GValue to be set.
- * @spec: the #GParamSpec which describes this data.
- *
- * Set the @value with the current content of the #NADataElement attached
- * to @property_id.
+ * @string: the string to be set in the element.
  *
- * This is to be readen as "set value from data element".
+ * Set the @object with the @string.
  */
 void
-na_factory_object_set_value( const NAIFactoryObject *object, guint property_id, GValue *value, GParamSpec *spec )
+na_factory_object_set_from_string( NAIFactoryObject *object, guint data_id, const gchar *string )
 {
-	static const gchar *thisfn = "na_factory_object_set_value";
-	NADataElement *element;
+	static const gchar *thisfn = "na_factory_object_set_from_string";
 
 	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	element = data_element_from_id( object, property_id );
-	if( element ){
-		na_data_element_set_to_value( element, value );
+	NADataBoxed *boxed = data_boxed_from_name( object, data_id );
+	if( boxed ){
+		na_data_boxed_set_from_string( boxed, string );
 
 	} else {
-		g_warning( "%s: unknown property id %d", thisfn, property_id );
+		g_warning( "%s: unknown property id %d", thisfn, data_id );
 	}
 }
+#endif
 
-static NADataElement *
-data_element_from_id( const NAIFactoryObject *object, guint data_id )
+static void
+attach_boxed_to_object( NAIFactoryObject *object, NADataBoxed *boxed )
 {
-	GList *list, *ip;
-	NADataElement *element;
+	GList *list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
+	list = g_list_prepend( list, boxed );
+	g_object_set_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA, list );
+}
 
-	element = NULL;
+static NADataBoxed *
+data_boxed_from_name( const NAIFactoryObject *object, const gchar *name )
+{
+	GList *list, *ip;
 
 	list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
+	/*g_debug( "list=%p (count=%u)", ( void * ) list, g_list_length( list ));*/
+
+	for( ip = list ; ip ; ip = ip->next ){
+		NADataBoxed *boxed = NA_DATA_BOXED( ip->data );
+		NADataDef *def = na_data_boxed_get_data_def( boxed );
 
-	for( ip = list ; ip && !element ; ip = ip->next ){
-		NadfDataValue *ndv = ( NadfDataValue * ) ip->data;
-		if( ndv->iddef->id == data_id ){
-			element = ndv->element;
+		if( !strcmp( def->name, name )){
+			return( boxed );
 		}
 	}
 
-	return( element );
+	return( NULL );
+}
+
+static void
+free_data_boxed_list( NAIFactoryObject *object )
+{
+	GList *list, *it;
+
+	list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
+
+	for( it = list ; it ; it = it->next ){
+
+		g_object_unref( it->data );
+	}
+
+	g_list_free( list );
+
+	g_object_set_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA, NULL );
 }
 
 /*
  * the iter function must return TRUE to stops the enumeration
  */
 static void
-iter_on_id_groups( const NadfIdGroup *groups, gboolean serializable_only, IdGroupIterFunc pfn, void *user_data )
+iter_on_data_defs( const NADataGroup *groups, gboolean serializable_only, NADataDefIterFunc pfn, void *user_data )
 {
-	NadfIdType *iddef;
+	NADataDef *def;
 	gboolean stop;
 
 	stop = FALSE;
 
-	while( groups->idgroup && !stop ){
+	while( groups->group && !stop ){
 
-		if( groups->iddef ){
+		if( groups->def ){
 
-			iddef = groups->iddef;
-			while( iddef->id && !stop ){
+			def = groups->def;
+			while( def->name && !stop ){
 
-				/*g_debug( "serializable_only=%s, iddef->serializable=%s",
-						serializable_only ? "True":"False", iddef->serializable ? "True":"False" );*/
+				/*g_debug( "serializable_only=%s, def->serializable=%s",
+						serializable_only ? "True":"False", def->serializable ? "True":"False" );*/
 
-				if( !serializable_only || iddef->serializable ){
-					stop = ( *pfn )( iddef, user_data );
+				if( !serializable_only || def->serializable ){
+					stop = ( *pfn )( def, user_data );
 				}
 
-				iddef++;
+				def++;
 			}
 		}
 
 		groups++;
 	}
 }
-
-static void
-free_gvalue( GValue *value, guint type )
-{
-	GSList *slist;
-
-	if( type == NADF_TYPE_STRING_LIST ){
-		slist = g_value_get_pointer( value );
-		na_core_utils_slist_free( slist );
-	}
-
-	g_value_unset( value );
-	g_free( value );
-}
diff --git a/src/core/na-factory-object.h b/src/core/na-factory-object.h
index 761bb7c..a645106 100644
--- a/src/core/na-factory-object.h
+++ b/src/core/na-factory-object.h
@@ -35,31 +35,48 @@
  * SECTION: na_ifactory_object
  * @short_description: #NAIFactoryObject internal functions.
  * @include: core/na-factory-object.h
+ *
+ * Declare the function only accessed from core library, i.e. not
+ * published as API.
  */
 
 #include <api/na-ifactory-provider.h>
 
 G_BEGIN_DECLS
 
-void            na_factory_object_properties( GObjectClass *class );
-NAIFactoryObject *na_factory_object_new       ( GType type );
+typedef gboolean ( *NAFactoryObjectIterBoxedFn )( const NAIFactoryObject *object, NADataBoxed *boxed, void *data );
+
+#if 0
+void         na_factory_object_register_type    ( GType type, const NADataGroup *groups );
+#endif
+void         na_factory_object_define_properties  ( GObjectClass *class, const NADataGroup *groups );
+NADataDef   *na_factory_object_get_data_def       ( const NAIFactoryObject *object, const gchar *name );
+NADataGroup *na_factory_object_get_data_groups    ( const NAIFactoryObject *object );
+void         na_factory_object_iter_on_boxed      ( const NAIFactoryObject *object, NAFactoryObjectIterBoxedFn pfn, void *data );
+
+void         na_factory_object_attach_with_default( NAIFactoryObject *object, const gchar *name );
+
+void         na_factory_object_move_boxed         ( NAIFactoryObject *target, const NAIFactoryObject *source, NADataBoxed *boxed );
+
+void         na_factory_object_copy               ( NAIFactoryObject *target, const NAIFactoryObject *source );
+gboolean     na_factory_object_are_equal          ( const NAIFactoryObject *a, const NAIFactoryObject *b );
+gboolean     na_factory_object_is_valid           ( const NAIFactoryObject *object );
+void         na_factory_object_dump               ( const NAIFactoryObject *object );
+void         na_factory_object_finalize_instance  ( NAIFactoryObject *object );
 
-void            na_factory_object_init      ( NAIFactoryObject *object );
-void            na_factory_object_copy      ( NAIFactoryObject *target, const NAIFactoryObject *source );
-gboolean        na_factory_object_are_equal ( const NAIFactoryObject *a, const NAIFactoryObject *b );
-gboolean        na_factory_object_is_valid  ( const NAIFactoryObject *object );
-void            na_factory_object_dump      ( const NAIFactoryObject *object );
-void            na_factory_object_finalize  ( NAIFactoryObject *object );
+void         na_factory_object_read_item          ( NAIFactoryObject *object, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+void         na_factory_object_write_item         ( NAIFactoryObject *object, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
 
-void            na_factory_object_read      ( NAIFactoryObject *object, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
-void            na_factory_object_write     ( NAIFactoryObject *object, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
+void        *na_factory_object_get_as_void        ( const NAIFactoryObject *object, const gchar *name );
+void         na_factory_object_get_as_value       ( const NAIFactoryObject *object, const gchar *name, GValue *value );
 
-void            na_factory_object_set_from_string( NAIFactoryObject *object, guint data_id, const gchar *data );
-void            na_factory_object_set_from_value ( NAIFactoryObject *object, guint data_id, const GValue *value );
-void            na_factory_object_set_from_void  ( NAIFactoryObject *object, guint data_id, const void *data );
+void         na_factory_object_set_from_value     ( NAIFactoryObject *object, const gchar *name, const GValue *value );
+void         na_factory_object_set_from_void      ( NAIFactoryObject *object, const gchar *name, const void *data );
 
+#if 0
+void         na_factory_object_set_from_string  ( NAIFactoryObject *object, const gchar *name, const gchar *data );
 void           *na_factory_object_get       ( const NAIFactoryObject *object, guint data_id );
-void            na_factory_object_set_value ( const NAIFactoryObject *object, guint property_id, GValue *value, GParamSpec *spec );
+#endif
 
 G_END_DECLS
 
diff --git a/src/core/na-factory-provider.c b/src/core/na-factory-provider.c
index e1d3890..c4d069e 100644
--- a/src/core/na-factory-provider.c
+++ b/src/core/na-factory-provider.c
@@ -32,160 +32,39 @@
 #include <config.h>
 #endif
 
-#include <string.h>
-
-#include "na-ifactory-provider-priv.h"
 #include "na-factory-provider.h"
 
-extern gboolean               ifactory_provider_initialized;		/* defined in na-ifactory.c */
-extern gboolean               ifactory_provider_finalized;		/* defined in na-ifactory.c */
-extern NAIFactoryProviderInterface *ifactory_provider_klass;			/* defined in na-ifactory.c */
-
-/**
- * na_factory_provider_register:
- * @type: the #GType of the implementation class.
- * @groups: a table of #NadfIdGroup structures which defines the
- *  serializable properties which will be attached to each instance of
- *  this class at serialization time.
- *
- * Registers the implementation #GType @type.
- */
-void
-na_factory_provider_register( GType type, const NadfIdGroup *groups )
-{
-	static const gchar *thisfn = "na_factory_provider_register";
-	NadfImplement *known;
-	NadfIdGroup *registered;
-
-	if( ifactory_provider_initialized && !ifactory_provider_finalized ){
-
-		g_debug( "%s: type=%lu, groups=%p",
-				thisfn, ( unsigned long ) type, ( void * ) groups );
-
-		g_return_if_fail( groups != NULL );
-
-		registered = na_factory_provider_get_groups( type );
-		if( registered ){
-			g_warning( "%s: type=%lu: already registered", thisfn, ( unsigned long ) type );
-
-		} else {
-			/* register the implementation
-			 */
-			known = g_new0( NadfImplement, 1 );
-			known->type = type;
-			known->groups = ( NadfIdGroup * ) groups;
-
-			ifactory_provider_klass->private->registered = g_list_prepend( ifactory_provider_klass->private->registered, known );
-		}
-	}
-}
-
-/**
- * na_factory_provider_get_groups:
- * @type: a previously registered #GType.
- *
- * Returns the #NadfIdGroups table which has been registered for this @type,
- * or %NULL.
- */
-NadfIdGroup *
-na_factory_provider_get_groups( GType type )
-{
-	GList *it;
-
-	if( ifactory_provider_initialized && !ifactory_provider_finalized ){
-
-		for( it = ifactory_provider_klass->private->registered ; it ; it = it->next ){
-			if((( NadfImplement * ) it->data )->type == type ){
-				return((( NadfImplement * ) it->data )->groups );
-			}
-		}
-	}
-
-	return( NULL );
-}
-
-/**
- * na_factory_provider_get_idtype_from_gconf_key:
- * @entry: the name of the GConf entry we are searching for.
- *
- * Returns: the definition of the data which is exported as @entry in GConf,
- * or %NULL if not found.
- */
-NadfIdType *
-na_factory_provider_get_idtype_from_gconf_key( const gchar *entry )
-{
-	static const gboolean debug = FALSE;
-	GList *imp;
-
-	if( ifactory_provider_initialized && !ifactory_provider_finalized ){
-
-		if( debug ){
-			g_debug( "na_factory_provider_get_idtype_from_gconf_key: entry=%s", entry );
-		}
-
-		for( imp = ifactory_provider_klass->private->registered ; imp ; imp = imp->next ){
-
-			NadfImplement *implement = ( NadfImplement * ) imp->data;
-			if( debug ){
-				g_debug( "implement=%p, type=%lu, groups=%p",
-						( void * ) implement, ( gulong ) implement->type, ( void * ) implement->groups );
-			}
-
-			NadfIdGroup *group = implement->groups;
-			while( group->idgroup ){
-				if( debug ){
-					g_debug( "group=%p, idgroup=%d, iddefs=%p", ( void * ) group, group->idgroup, ( void * ) group->iddef );
-				}
-
-				NadfIdType *iddef = group->iddef;
-				if( iddef ){
-					while( iddef->id ){
-						if( debug ){
-							g_debug( "iddef=%p, id=%d, gconf_entry=%s", ( void * ) iddef, iddef->id, iddef->gconf_entry );
-						}
-
-						if( iddef->gconf_entry && !strcmp( iddef->gconf_entry, entry )){
-							return( iddef );
-						}
-
-						iddef++;
-					}
-				}
-
-				group++;
-			}
-		}
-	}
-
-	return( NULL );
-}
+extern gboolean ifactory_provider_initialized;		/* defined in na-ifactory-provider.c */
+extern gboolean ifactory_provider_finalized;
 
 /**
  * na_factory_provider_read_value:
  * @reader: the instance which implements this #NAIFactoryProvider interface.
  * @reader_data: instance data.
- * @iddef: a NadfIdType structure which identifies the data to be unserialized.
+ * @object: the #NAIFactoryobject being unserialized.
+ * @def: a #NADataDef structure which identifies the data to be unserialized.
  * @messages: a pointer to a #GSList list of strings; the implementation
  *  may append messages to this list, but shouldn't reinitialize it.
  *
- * Returns: the desired value, as a newly allocated #GValue, or NULL.
+ * Reads the specified data and set it up into the @boxed.
  */
-GValue *
-na_factory_provider_read_value( const NAIFactoryProvider *reader, void *reader_data, const NadfIdType *iddef, GSList **messages )
+NADataBoxed *
+na_factory_provider_read_data( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *object, const NADataDef *def, GSList **messages )
 {
-	GValue *value;
+	NADataBoxed *boxed;
 
 	g_return_val_if_fail( NA_IS_IFACTORY_PROVIDER( reader ), NULL );
+	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
 
-	value = NULL;
+	boxed = NULL;
 
 	if( ifactory_provider_initialized && !ifactory_provider_finalized ){
 
-		if( NA_IFACTORY_PROVIDER_GET_INTERFACE( reader )->read_value ){
+		if( NA_IFACTORY_PROVIDER_GET_INTERFACE( reader )->read_data ){
 
-			value = NA_IFACTORY_PROVIDER_GET_INTERFACE( reader )->read_value( reader, reader_data, iddef, messages );
+			boxed = NA_IFACTORY_PROVIDER_GET_INTERFACE( reader )->read_data( reader, reader_data, object, def, messages );
 		}
 	}
 
-	return( value );
+	return( boxed );
 }
diff --git a/src/core/na-factory-provider.h b/src/core/na-factory-provider.h
index ec4ce6d..5cabfb1 100644
--- a/src/core/na-factory-provider.h
+++ b/src/core/na-factory-provider.h
@@ -35,17 +35,18 @@
  * SECTION: na_ifactory_provider
  * @short_description: #NAIFactoryProvider interface definition.
  * @include: core/na-factory-provider.h
+ *
+ * Declare the function only accessed from core library (not published as API).
  */
 
+#include <api/na-data-boxed.h>
 #include <api/na-ifactory-provider.h>
 
 G_BEGIN_DECLS
 
-void         na_factory_provider_register  ( GType type, const NadfIdGroup *groups );
-NadfIdGroup *na_factory_provider_get_groups( GType type );
-NadfIdType  *na_factory_provider_get_idtype_from_gconf_key( const gchar *entry );
-
-GValue      *na_factory_provider_read_value( const NAIFactoryProvider *reader, void *reader_data, const NadfIdType *iddef, GSList **messages );
+NADataBoxed *na_factory_provider_read_data( const NAIFactoryProvider *reader, void *reader_data,
+									NAIFactoryObject *object, const NADataDef *def,
+									GSList **messages );
 
 G_END_DECLS
 
diff --git a/src/core/na-gconf-utils.c b/src/core/na-gconf-utils.c
index bbdfea7..bb654ae 100644
--- a/src/core/na-gconf-utils.c
+++ b/src/core/na-gconf-utils.c
@@ -640,6 +640,43 @@ na_gconf_utils_remove_entry( GConfClient *gconf, const gchar *path, gchar **mess
 	return( ret );
 }
 
+/**
+ * na_gconf_utils_slist_from_string:
+ * @value: a string of the form [xxx,yyy,...] as read from GConf.
+ *
+ * Converts a string representing a list of strings in a GConf format
+ * to a list of strings.
+ *
+ * Returns: a newly allocated list of strings, which should be
+ * na_core_utils_slist_free() by the caller, or %NULL if the provided
+ * string was not of the GConf form.
+ */
+GSList *
+na_gconf_utils_slist_from_string( const gchar *value )
+{
+	GSList *slist;
+	gchar *tmp_string;
+
+	tmp_string = g_strdup( value );
+	g_strstrip( tmp_string );
+
+	if( !tmp_string || strlen( tmp_string ) < 3 ){
+		g_free( tmp_string );
+		return( NULL );
+	}
+
+	if( tmp_string[0] != '[' || tmp_string[strlen(tmp_string)-1] != ']' ){
+		g_free( tmp_string );
+		return( NULL );
+	}
+
+	tmp_string += 1;
+	tmp_string[strlen(tmp_string)-1] = '\0';
+	slist = na_core_utils_slist_from_split( tmp_string, "," );
+
+	return( slist );
+}
+
 static gboolean
 sync_gconf( GConfClient *gconf, gchar **message )
 {
diff --git a/src/core/na-ifactory-object.c b/src/core/na-ifactory-object.c
index 30e876c..89bee3f 100644
--- a/src/core/na-ifactory-object.c
+++ b/src/core/na-ifactory-object.c
@@ -32,6 +32,8 @@
 #include <config.h>
 #endif
 
+#include <string.h>
+
 #include <api/na-ifactory-object.h>
 
 #include "na-factory-object.h"
@@ -39,11 +41,14 @@
 /* private interface data
  */
 struct NAIFactoryObjectInterfacePrivate {
-	void *empty;						/* so that gcc -pedantic is happy */
+	void *empty;					/* so that gcc -pedantic is happy */
 };
 
-gboolean ifactory_object_initialized = FALSE;
-gboolean ifactory_object_finalized   = FALSE;
+gboolean                   ifactory_object_initialized = FALSE;
+gboolean                   ifactory_object_finalized   = FALSE;
+#if 0
+NAIFactoryObjectInterface *ifactory_object_klass       = NULL;
+#endif
 
 static GType register_type( void );
 static void  interface_base_init( NAIFactoryObjectInterface *klass );
@@ -105,6 +110,7 @@ interface_base_init( NAIFactoryObjectInterface *klass )
 		klass->private = g_new0( NAIFactoryObjectInterfacePrivate, 1 );
 
 		klass->get_version = ifactory_object_get_version;
+		klass->get_groups = NULL;
 		klass->get_default = NULL;
 		klass->copy = NULL;
 		klass->are_equal = NULL;
@@ -114,6 +120,10 @@ interface_base_init( NAIFactoryObjectInterface *klass )
 		klass->write_start = NULL;
 		klass->write_done = NULL;
 
+#if 0
+		ifactory_object_klass = klass;
+#endif
+
 		ifactory_object_initialized = TRUE;
 	}
 }
@@ -122,6 +132,9 @@ static void
 interface_base_finalize( NAIFactoryObjectInterface *klass )
 {
 	static const gchar *thisfn = "na_ifactory_object_interface_base_finalize";
+#if 0
+	GList *ip;
+#endif
 
 	if( ifactory_object_initialized && !ifactory_object_finalized ){
 
@@ -129,6 +142,14 @@ interface_base_finalize( NAIFactoryObjectInterface *klass )
 
 		ifactory_object_finalized = TRUE;
 
+#if 0
+		for( ip = klass->private->registered ; ip ; ip = ip->next ){
+			NADataImplement *known = ( NADataImplement * ) ip->data;
+			g_free( known );
+		}
+		g_list_free( klass->private->registered );
+#endif
+
 		g_free( klass->private );
 	}
 }
@@ -139,26 +160,103 @@ ifactory_object_get_version( const NAIFactoryObject *instance )
 	return( 1 );
 }
 
+#if 0
+/**
+ * na_ifactory_object_get_data_def_from_name:
+ * @object: a #NAIFactoryObject object.
+ * @name: the name of the elementary we are searching for.
+ *
+ * Returns: The #NADataDef structure which defines this @name for this @object,
+ * or %NULL.
+ */
+NADataDef *
+na_ifactory_object_get_data_def_from_name( const NAIFactoryObject *object, const gchar *name )
+{
+	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
+
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
+
+		NADataGroup *groups = na_factory_object_get_data_groups( object );
+		while( groups->group ){
+
+			NADataDef *def = groups->def;
+			if( def ){
+				while( def->name ){
+
+					if( !strcmp( def->name, name )){
+						return( def );
+					}
+
+					def++;
+				}
+			}
+
+			groups++;
+		}
+	}
+
+	return( NULL );
+}
+
 /**
- * na_ifactory_object_get:
+ * na_ifactory_object_get_data_def_from_gconf_key:
+ * @object: a #NAIFactoryObject object.
+ * @entry: the name of the GConf entry we are searching for.
+ *
+ * Returns: the #NADataDef structure which defines this GConf @entry,
+ * or %NULL if not found.
+ */
+NADataDef *
+na_ifactory_object_get_data_def_from_gconf_key( const NAIFactoryObject *object, const gchar *entry )
+{
+	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
+
+	if( ifactory_object_initialized && !ifactory_object_finalized ){
+
+		NADataGroup *groups = na_factory_object_get_data_groups( object );
+		while( groups->group ){
+
+			NADataDef *def = groups->def;
+			if( def ){
+				while( def->name ){
+
+					if( def->gconf_entry && !strcmp( def->gconf_entry, entry )){
+						return( def );
+					}
+
+					def++;
+				}
+			}
+
+			groups++;
+		}
+	}
+
+	return( NULL );
+}
+#endif
+
+/**
+ * na_ifactory_object_get_as_void:
  * @object: this #NAIFactoryObject instance.
- * @data_id: the elementary data whose value is to be got.
+ * @name: the elementary data whose value is to be got.
  *
  * Returns: the searched value.
  *
- * If the type of the value is NADF_TYPE_STRING, NADF_TYPE_LOCALE_STRING,
- * or NADF_TYPE_STRING_LIST, then the returned value is a newly allocated
+ * If the type of the value is NAFD_TYPE_STRING, NAFD_TYPE_LOCALE_STRING,
+ * or NAFD_TYPE_STRING_LIST, then the returned value is a newly allocated
  * one and should be g_free() (resp. na_core_utils_slist_free()) by the
  * caller.
  */
 void *
-na_ifactory_object_get( const NAIFactoryObject *object, guint data_id )
+na_ifactory_object_get_as_void( const NAIFactoryObject *object, const gchar *name )
 {
 	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
 
-	return( na_factory_object_get( object, data_id ));
+	return( na_factory_object_get_as_void( object, name ));
 }
 
+#if 0
 /**
  * na_ifactory_object_set_from_string:
  * @object: this #NAIFactoryObject instance.
@@ -174,19 +272,20 @@ na_ifactory_object_set_from_string( NAIFactoryObject *object, guint data_id, con
 
 	na_factory_object_set_from_string( object, data_id, data );
 }
+#endif
 
 /**
  * na_ifactory_object_set_from_void:
  * @object: this #NAIFactoryObject instance.
- * @data_id: the elementary data whose value is to be set.
+ * @name: the name of the elementary data whose value is to be set.
  * @data: the value to set.
  *
  * Set the elementary data with the given value.
  */
 void
-na_ifactory_object_set_from_void( NAIFactoryObject *object, guint data_id, const void *data )
+na_ifactory_object_set_from_void( NAIFactoryObject *object, const gchar *name, const void *data )
 {
 	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	na_factory_object_set_from_void( object, data_id, data );
+	na_factory_object_set_from_void( object, name, data );
 }
diff --git a/src/core/na-ifactory-provider.c b/src/core/na-ifactory-provider.c
index e219be8..c9b896f 100644
--- a/src/core/na-ifactory-provider.c
+++ b/src/core/na-ifactory-provider.c
@@ -35,12 +35,16 @@
 #include <api/na-ifactory-provider.h>
 
 #include "na-factory-object.h"
-#include "na-ifactory-provider-priv.h"
 #include "na-factory-provider.h"
 
-gboolean               ifactory_provider_initialized = FALSE;
-gboolean               ifactory_provider_finalized   = FALSE;
-NAIFactoryProviderInterface *ifactory_provider_klass       = NULL;
+/* private interface data
+ */
+struct NAIFactoryProviderInterfacePrivate {
+	void *empty;						/* so that gcc -pedantic is happy */
+};
+
+gboolean ifactory_provider_initialized = FALSE;
+gboolean ifactory_provider_finalized   = FALSE;
 
 static GType register_type( void );
 static void  interface_base_init( NAIFactoryProviderInterface *klass );
@@ -107,12 +111,13 @@ interface_base_init( NAIFactoryProviderInterface *klass )
 		klass->private = g_new0( NAIFactoryProviderInterfacePrivate, 1 );
 
 		klass->get_version = ifactory_provider_get_version;
-		klass->read_value = NULL;
+		klass->read_start = NULL;
+		klass->read_data = NULL;
 		klass->read_done = NULL;
-		klass->write_value = NULL;
+		klass->write_start = NULL;
+		klass->write_data = NULL;
 		klass->write_done = NULL;
 
-		ifactory_provider_klass = klass;
 		ifactory_provider_initialized = TRUE;
 	}
 }
@@ -121,8 +126,6 @@ static void
 interface_base_finalize( NAIFactoryProviderInterface *klass )
 {
 	static const gchar *thisfn = "na_ifactory_provider_interface_base_finalize";
-	GList *ip;
-	NadfImplement *known;
 
 	if( ifactory_provider_initialized && !ifactory_provider_finalized ){
 
@@ -130,12 +133,6 @@ interface_base_finalize( NAIFactoryProviderInterface *klass )
 
 		ifactory_provider_finalized = TRUE;
 
-		for( ip = klass->private->registered ; ip ; ip = ip->next ){
-			known = ( NadfImplement * ) ip->data;
-			g_free( known );
-		}
-		g_list_free( klass->private->registered );
-
 		g_free( klass->private );
 	}
 }
@@ -150,40 +147,27 @@ ifactory_provider_get_version( const NAIFactoryProvider *instance )
  * na_ifactory_provider_read_item:
  * @reader: the instance which implements this #NAIFactoryProvider interface.
  * @reader_data: instance data.
- * @type: the #GType which identifies the #NAIFactoryObject type.
+ * @object: the #NAIFactoryObject object to be unserialilzed.
  * @messages: a pointer to a #GSList list of strings; the implementation
  *  may append messages to this list, but shouldn't reinitialize it.
  *
  * Returns: a newly instantiated #NAIFactoryObject object just readen from @reader.
  */
-NAIFactoryObject *
-na_ifactory_provider_read_item( const NAIFactoryProvider *reader, void *reader_data, GType type, GSList **messages )
+void
+na_ifactory_provider_read_item( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *object, GSList **messages )
 {
-	static const gchar *thisfn = "na_ifactory_provider_read_item";
-	NAIFactoryObject *serializable;
-	gchar *msg;
-
-	serializable = NULL;
+	g_return_if_fail( NA_IS_IFACTORY_PROVIDER( reader ));
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
 	if( ifactory_provider_initialized && !ifactory_provider_finalized ){
 
-		g_return_val_if_fail( NA_IS_IFACTORY_PROVIDER( reader ), NULL );
-
-		serializable = na_factory_object_new( type );
-
-		if( serializable ){
-			v_factory_provider_read_start( reader, reader_data, serializable, messages );
-			na_factory_object_read( serializable, reader, reader_data, messages );
-			v_factory_provider_read_done( reader, reader_data, serializable, messages );
+		g_return_if_fail( NA_IS_IFACTORY_PROVIDER( reader ));
+		g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-		} else {
-			msg = g_strdup_printf( "%s: %ld: unknown type", thisfn, ( long ) type );
-			g_warning( "%s", msg );
-			*messages = g_slist_append( *messages, msg );
-		}
+		v_factory_provider_read_start( reader, reader_data, object, messages );
+		na_factory_object_read_item( object, reader, reader_data, messages );
+		v_factory_provider_read_done( reader, reader_data, object, messages );
 	}
-
-	return( serializable );
 }
 
 /**
@@ -197,32 +181,19 @@ na_ifactory_provider_read_item( const NAIFactoryProvider *reader, void *reader_d
  * Writes the data down to the FactoryProvider.
  */
 void
-na_ifactory_provider_write_item( const NAIFactoryProvider *writer, void *writer_data, NAIFactoryObject *serializable, GSList **messages )
+na_ifactory_provider_write_item( const NAIFactoryProvider *writer, void *writer_data, NAIFactoryObject *object, GSList **messages )
 {
 	g_return_if_fail( NA_IS_IFACTORY_PROVIDER( writer ));
-	g_return_if_fail( NA_IS_IFACTORY_OBJECT( serializable ));
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
 	if( ifactory_provider_initialized && !ifactory_provider_finalized ){
 
-		v_factory_provider_write_start( writer, writer_data, serializable, messages );
-		na_factory_object_write( serializable, writer, writer_data, messages );
-		v_factory_provider_write_done( writer, writer_data, serializable, messages );
+		v_factory_provider_write_start( writer, writer_data, object, messages );
+		na_factory_object_write_item( object, writer, writer_data, messages );
+		v_factory_provider_write_done( writer, writer_data, object, messages );
 	}
 }
 
-/**
- * na_ifactory_provider_get_idtype_from_gconf_key:
- * @entry: the name of the node we are searching for.
- *
- * Returns: the definition of the data which is exported as @entry in GConf,
- * or %NULL if not found.
- */
-NadfIdType *
-na_ifactory_provider_get_idtype_from_gconf_key( const gchar *entry )
-{
-	return( na_factory_provider_get_idtype_from_gconf_key( entry ));
-}
-
 static void
 v_factory_provider_read_start( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *serializable, GSList **messages )
 {
diff --git a/src/core/na-importer.c b/src/core/na-importer.c
index 3c50dc5..37606c9 100644
--- a/src/core/na-importer.c
+++ b/src/core/na-importer.c
@@ -40,39 +40,34 @@ extern gboolean iimporter_finalized;		/* defined in na-iimporter.c */
 /**
  * na_importer_import:
  * @pivot: the #NAPivot pivot for this application.
- * @uri: the source filename URI.
- * @mode: the import mode.
- * @fn: a function to check the existance of the imported item.
- * @fn_data: function data
- * @messages: a pointer to a #GSList list of strings; the provider
- *  may append messages to this list, but shouldn't reinitialize it.
+ * @parms: a #NAIImporterParms structure.
  *
- * Returns: a newly allocated #NAObjectItem-derived object, or %NULL
- * if an error has been detected.
+ * Returns: the import operation code.
  */
-NAObjectItem *
-na_importer_import( const NAPivot *pivot, const gchar *uri, guint mode, ImporterCheckFn fn, void *fn_data, GSList **messages )
+guint
+na_importer_import_from_uri( const NAPivot *pivot, NAIImporterParms *parms )
 {
-	static const gchar *thisfn = "na_importer_import";
-	NAObjectItem *item;
-	GList *modules;
+	static const gchar *thisfn = "na_importer_import_from_uri";
+	GList *modules, *im;
+	guint code;
 
-	g_debug( "%s: pivot=%p, uri=%s, mode=%d, fn=%p, fn_data=%p, messages=%p",
-			thisfn, ( void * ) pivot, uri, mode, ( void * ) fn, ( void * ) fn_data, ( void * ) messages );
+	g_debug( "%s: pivot=%p, parms=%p", thisfn, ( void * ) pivot, ( void * ) parms );
 
-	item = NULL;
+	code = IMPORTER_CODE_NOT_WILLING_TO;
 
 	if( iimporter_initialized && !iimporter_finalized ){
 
 		modules = na_pivot_get_providers( pivot, NA_IIMPORTER_TYPE );
-		g_debug( "na_importer_import: modules_count=%d", g_list_length( modules ));
-		if( g_list_length( modules )){
-			if( NA_IIMPORTER_GET_INTERFACE( NA_IIMPORTER( modules->data ))->import_uri ){
-				item = NA_IIMPORTER_GET_INTERFACE( NA_IIMPORTER( modules->data ))->import_uri( NA_IIMPORTER( modules->data ), uri, mode, fn, fn_data, messages );
+
+		for( im = modules ; im && code == IMPORTER_CODE_NOT_WILLING_TO ; im = im->next ){
+
+			if( NA_IIMPORTER_GET_INTERFACE( NA_IIMPORTER( im->data ))->import_from_uri ){
+				code = NA_IIMPORTER_GET_INTERFACE( NA_IIMPORTER( im->data ))->import_from_uri( NA_IIMPORTER( im->data ), parms );
 			}
 		}
+
 		na_pivot_free_providers( modules );
 	}
 
-	return( item );
+	return( code );
 }
diff --git a/src/core/na-importer.h b/src/core/na-importer.h
index 1ae1284..f12ab2e 100644
--- a/src/core/na-importer.h
+++ b/src/core/na-importer.h
@@ -44,7 +44,7 @@
 
 G_BEGIN_DECLS
 
-NAObjectItem *na_importer_import( const NAPivot *pivot, const gchar *uri, guint mode, ImporterCheckFn fn, void *fn_data, GSList **messages );
+guint na_importer_import_from_uri( const NAPivot *pivot, NAIImporterParms *parms );
 
 G_END_DECLS
 
diff --git a/src/core/na-io-provider.c b/src/core/na-io-provider.c
index 8e175bb..8f17e1a 100644
--- a/src/core/na-io-provider.c
+++ b/src/core/na-io-provider.c
@@ -750,7 +750,7 @@ build_hierarchy( GList **tree, GSList *level_zero, gboolean list_if_empty )
 				*tree = g_list_remove_link( *tree, it );
 
 				if( NA_IS_OBJECT_MENU( it->data )){
-					subitems_ids = na_object_get_items_slist( NA_OBJECT_ITEM( it->data ));
+					subitems_ids = na_object_get_items_slist( it->data );
 					subitems = build_hierarchy( tree, subitems_ids, FALSE );
 					na_object_set_items( it->data, subitems );
 					na_core_utils_slist_free( subitems_ids );
diff --git a/src/core/na-object-action-factory.c b/src/core/na-object-action-factory.c
new file mode 100644
index 0000000..751e35a
--- /dev/null
+++ b/src/core/na-object-action-factory.c
@@ -0,0 +1,294 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <api/na-ifactory-object-data.h>
+#include <api/na-data-def.h>
+#include <api/na-data-types.h>
+
+extern NADataDef data_def_id[];			/* defined in na-object-id-factory.c */
+extern NADataDef data_def_item [];		/* defined in na-object-item-factory.c */
+
+static NADataDef data_def_action [] = {
+
+	{ NAFO_DATA_VERSION,
+				TRUE,
+				"Action version",
+				"Version of the action",
+				NAFD_TYPE_STRING,
+				"2.0",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"version",
+				NULL,
+				FALSE },
+
+	{ NAFO_DATA_TARGET_SELECTION,
+				TRUE,
+				"Target a selection context menu",
+				"Does the action target the context menu when there is some selection ?",
+				NAFD_TYPE_BOOLEAN,
+				"TRUE",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"target-selection",
+				NULL,
+				FALSE },
+
+	{ NAFO_DATA_TARGET_BACKGROUND,
+				TRUE,
+				"Target the folder context menu",
+				"Does the action target the context menu when there is no selection ?",
+				NAFD_TYPE_BOOLEAN,
+				"FALSE",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"target-background",
+				NULL,
+				FALSE },
+
+	{ NAFO_DATA_TARGET_TOOLBAR,
+				TRUE,
+				"Target the toolbar",
+				"Does the action target the toolbar ? " \
+				"Only an action may target the toolbar as Nautilus, as of 2.28, " \
+				"doesn't support menus in toolbar.",
+				NAFD_TYPE_BOOLEAN,
+				"FALSE",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"target-toolbar",
+				NULL,
+				FALSE },
+
+	{ NAFO_DATA_TOOLBAR_LABEL,
+				TRUE,
+				"Toolbar label",
+				"Label of the action in the toolbar. " \
+				"Defaults to main label if empty or not set.",
+				NAFD_TYPE_LOCALE_STRING,
+				"",
+				TRUE,
+				TRUE,
+				FALSE,
+				TRUE,
+				"toolbar-label",
+				NULL,
+				FALSE },
+
+	{ NAFO_DATA_TOOLBAR_SAME_LABEL,
+				FALSE,
+				"Does the toolbar label is the same than the main one ?",
+				"Does the toolbar label is the same than the main one ?",
+				NAFD_TYPE_BOOLEAN,
+				"true",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"toolbar-same-label",
+				NULL,
+				FALSE },
+
+	{ NAFO_DATA_LAST_ALLOCATED,
+				FALSE,
+				"Last allocated profile",
+				"Last allocated profile number in na_object_action_get_new_profile_name(), " \
+				"reset to zero when saving the action.",
+				NAFD_TYPE_UINT,
+				"0",
+				TRUE,
+				FALSE,
+				FALSE,
+				FALSE,
+				NULL,
+				NULL,
+				FALSE },
+
+	{ NULL },
+};
+
+static NADataDef data_def_obsoleted_action [] = {
+
+	{ NAFO_DATA_PATH,
+				TRUE,
+				"Command path",
+				"The path to the command.",
+				NAFD_TYPE_STRING,
+				"",
+				TRUE,
+				TRUE,
+				TRUE,
+				FALSE,
+				"path",
+				NULL,
+				TRUE },
+
+	{ NAFO_DATA_PARAMETERS,
+				TRUE,
+				"Command parameters",
+				"The parameters of the command.",
+				NAFD_TYPE_STRING,
+				"",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"parameters",
+				NULL,
+				TRUE },
+
+	{ NAFO_DATA_BASENAMES,
+				TRUE,
+				"Basenames",
+				"The basenames the selection must match. " \
+				"Defaults to '*'.",
+				NAFD_TYPE_STRING_LIST,
+				"*",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"basenames",
+				NULL,
+				TRUE },
+
+	{ NAFO_DATA_MATCHCASE,
+				TRUE,
+				"Case sensitive",
+				"Whether the specified basenames are case sensitive." \
+				"Defaults to 'true'.",
+				NAFD_TYPE_BOOLEAN,
+				"TRUE",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"matchcase",
+				NULL,
+				TRUE },
+
+	{ NAFO_DATA_MIMETYPES,
+				TRUE,
+				"Mimetypes",
+				"The mimetypes the selection must match." \
+				"Defaults to '*'.",
+				NAFD_TYPE_STRING_LIST,
+				"*",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"mimetypes",
+				NULL,
+				TRUE },
+
+	{ NAFO_DATA_ISFILE,
+				TRUE,
+				"Applies to files only",
+				"Whether the profile only applies to files." \
+				"Defaults to 'true'",
+				NAFD_TYPE_BOOLEAN,
+				"TRUE",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"isfile",
+				NULL,
+				TRUE },
+
+	{ NAFO_DATA_ISDIR,
+				TRUE,
+				"Applies to directories only",
+				"Whether the profile applies to directories only." \
+				"Defaults to 'false'",
+				NAFD_TYPE_BOOLEAN,
+				"FALSE",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"isdir",
+				NULL,
+				TRUE },
+
+	{ NAFO_DATA_MULTIPLE,
+				TRUE,
+				"Multiple selection",
+				"Whether the selection may be multiple." \
+				"Defaults to 'false'.",
+				NAFD_TYPE_BOOLEAN,
+				"FALSE",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"accept-multiple-files",
+				NULL,
+				TRUE },
+
+	{ NAFO_DATA_SCHEMES,
+				TRUE,
+				"Schemes",
+				"The list of schemes the selection must match." \
+				"Defaults to 'file'.",
+				NAFD_TYPE_STRING_LIST,
+				"file",
+				TRUE,
+				TRUE,
+				FALSE,
+				FALSE,
+				"schemes",
+				NULL,
+				TRUE },
+
+	{ NULL },
+};
+
+NADataGroup action_data_groups [] = {
+	{ NA_FACTORY_OBJECT_ID_GROUP,         data_def_id },
+	{ NA_FACTORY_OBJECT_ITEM_GROUP,       data_def_item },
+	{ NA_FACTORY_OBJECT_ACTION_GROUP,     data_def_action },
+	{ NA_FACTORY_OBSOLETED_ACTION_GROUP,  data_def_obsoleted_action },
+	{ NA_FACTORY_OBJECT_CONDITIONS_GROUP, NULL },
+	{ NULL }
+};
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 5f85419..4496267 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -33,6 +33,7 @@
 #endif
 
 #include <glib/gi18n.h>
+#include <string.h>
 
 #include <api/na-object-api.h>
 
@@ -51,35 +52,46 @@ struct NAObjectActionPrivate {
 	gboolean dispose_has_run;
 };
 
-										/* i18n: default label for a new action */
+/* while iterating when searching for obsoleted boxed
+ */
+typedef struct {
+	NAObjectProfile *profile;
+	GList           *moved;
+}
+	IterForObsoletedParms;
+
+/* i18n: default label for a new action */
 #define NEW_NAUTILUS_ACTION				N_( "New Nautilus action" )
 
-extern NadfIdGroup action_id_groups [];	/* defined in na-item-action-enum.c */
+extern NADataGroup action_data_groups [];		/* defined in na-item-action-factory.c */
 
 static NAObjectItemClass *st_parent_class = NULL;
 
-static GType    register_type( void );
-static void     class_init( NAObjectActionClass *klass );
-static void     instance_init( GTypeInstance *instance, gpointer klass );
-static void     instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
-static void     instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
-static void     instance_dispose( GObject *object );
-static void     instance_finalize( GObject *object );
-
-static gboolean object_is_valid( const NAObject *object );
-
-static void     ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
-static guint    ifactory_object_get_version( const NAIFactoryObject *instance );
-static gchar   *ifactory_object_get_default( const NAIFactoryObject *instance, const NadfIdType *iddef );
-static void     ifactory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source );
-static gboolean ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
-static gboolean ifactory_object_is_valid( const NAIFactoryObject *object );
-static void     ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
-static void     ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
-
-static gboolean object_object_is_valid( const NAObjectAction *action );
-static gboolean is_valid_label( const NAObjectAction *action );
-static gboolean is_valid_toolbar_label( const NAObjectAction *action );
+static GType        register_type( void );
+static void         class_init( NAObjectActionClass *klass );
+static void         instance_init( GTypeInstance *instance, gpointer klass );
+static void         instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
+static void         instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
+static void         instance_dispose( GObject *object );
+static void         instance_finalize( GObject *object );
+
+static gboolean     object_is_valid( const NAObject *object );
+
+static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
+static guint        ifactory_object_get_version( const NAIFactoryObject *instance );
+static NADataGroup *ifactory_object_get_groups( const NAIFactoryObject *instance );
+static gchar       *ifactory_object_get_default( const NAIFactoryObject *instance, const NADataDef *iddef );
+static void         ifactory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source );
+static gboolean     ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
+static gboolean     ifactory_object_is_valid( const NAIFactoryObject *object );
+static void         ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+static void         ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
+
+static gboolean     check_for_obsoleted_iter( const NAIFactoryObject *object, NADataBoxed *boxed, IterForObsoletedParms *parms );
+
+static gboolean     object_object_is_valid( const NAObjectAction *action );
+static gboolean     is_valid_label( const NAObjectAction *action );
+static gboolean     is_valid_toolbar_label( const NAObjectAction *action );
 
 GType
 na_object_action_get_type( void )
@@ -124,7 +136,9 @@ register_type( void )
 
 	g_type_add_interface_static( type, NA_IFACTORY_OBJECT_TYPE, &ifactory_object_iface_info );
 
-	na_factory_provider_register( type, action_id_groups );
+#if 0
+	na_factory_object_register_type( type, action_id_groups );
+#endif
 
 	return( type );
 }
@@ -154,7 +168,7 @@ class_init( NAObjectActionClass *klass )
 
 	klass->private = g_new0( NAObjectActionClassPrivate, 1 );
 
-	na_factory_object_properties( object_class );
+	na_factory_object_define_properties( object_class, action_data_groups );
 }
 
 static void
@@ -171,8 +185,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self = NA_OBJECT_ACTION( instance );
 
 	self->private = g_new0( NAObjectActionPrivate, 1 );
-
-	na_factory_object_init( NA_IFACTORY_OBJECT( instance ));
 }
 
 static void
@@ -183,7 +195,7 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 
 	if( !NA_OBJECT_ACTION( object )->private->dispose_has_run ){
 
-		na_factory_object_set_value( NA_IFACTORY_OBJECT( object ), property_id, value, spec );
+		na_factory_object_get_as_value( NA_IFACTORY_OBJECT( object ), g_quark_to_string( property_id ), value );
 	}
 }
 
@@ -195,7 +207,7 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 
 	if( !NA_OBJECT_ACTION( object )->private->dispose_has_run ){
 
-		na_factory_object_set_from_value( NA_IFACTORY_OBJECT( object ), property_id, value );
+		na_factory_object_set_from_value( NA_IFACTORY_OBJECT( object ), g_quark_to_string( property_id ), value );
 	}
 }
 
@@ -236,7 +248,7 @@ instance_finalize( GObject *object )
 
 	g_free( self->private );
 
-	na_factory_object_finalize( NA_IFACTORY_OBJECT( object ));
+	na_factory_object_finalize_instance( NA_IFACTORY_OBJECT( object ));
 
 	/* chain call to parent class */
 	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
@@ -260,6 +272,7 @@ ifactory_object_iface_init( NAIFactoryObjectInterface *iface )
 	g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
 
 	iface->get_version = ifactory_object_get_version;
+	iface->get_groups = ifactory_object_get_groups;
 	iface->get_default = ifactory_object_get_default;
 	iface->copy = ifactory_object_copy;
 	iface->are_equal = ifactory_object_are_equal;
@@ -276,19 +289,23 @@ ifactory_object_get_version( const NAIFactoryObject *instance )
 	return( 1 );
 }
 
+static NADataGroup *
+ifactory_object_get_groups( const NAIFactoryObject *instance )
+{
+	return( action_data_groups );
+}
+
 static gchar *
-ifactory_object_get_default( const NAIFactoryObject *instance, const NadfIdType *iddef )
+ifactory_object_get_default( const NAIFactoryObject *instance, const NADataDef *def )
 {
 	gchar *value;
 
 	value = NULL;
 
-	switch( iddef->id ){
+	if( !strcmp( def->name, NAFO_DATA_LABEL ) ||
+		!strcmp( def->name, NAFO_DATA_TOOLBAR_LABEL )){
 
-		case NADF_DATA_LABEL:
-		case NADF_DATA_TOOLBAR_LABEL:
 			value = g_strdup( NEW_NAUTILUS_ACTION );
-			break;
 	}
 
 	return( value );
@@ -317,9 +334,32 @@ ifactory_object_is_valid( const NAIFactoryObject *object )
 static void
 ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
 {
+	IterForObsoletedParms parms;
+	GList *ibox;
+
 	g_debug( "na_object_action_ifactory_object_read_done: instance=%p", ( void * ) instance );
 
-	na_object_dump( instance );
+	/* do we have a pre-v2 action ?
+	 *  i.e. an action without profile, with some data in its body
+	 *  -> do we have read some obsoleted data which are now in the profile
+	 */
+	parms.profile = na_object_profile_new();
+	parms.moved = NULL;
+
+	na_factory_object_iter_on_boxed( instance, ( NAFactoryObjectIterBoxedFn ) check_for_obsoleted_iter, &parms );
+
+	if( parms.moved ){
+		na_object_set_id( parms.profile, "profile-pre-v2" );
+		na_object_set_label( parms.profile, _( "Profile automatically created from pre-v2 action" ));
+		na_object_attach_profile( instance, parms.profile );
+
+		for( ibox = parms.moved ; ibox ; ibox = ibox->next ){
+			na_factory_object_move_boxed( NA_IFACTORY_OBJECT( parms.profile ), instance, NA_DATA_BOXED( ibox->data ));
+		}
+
+	} else {
+		g_object_unref( parms.profile );
+	}
 }
 
 static void
@@ -329,6 +369,22 @@ ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider
 }
 
 static gboolean
+check_for_obsoleted_iter( const NAIFactoryObject *object, NADataBoxed *boxed, IterForObsoletedParms *parms )
+{
+	NADataDef *def = na_data_boxed_get_data_def( boxed );
+
+	if( def->obsoleted ){
+		NADataDef *profile_def = na_factory_object_get_data_def( NA_IFACTORY_OBJECT( parms->profile ), def->name );
+
+		if( profile_def ){
+			parms->moved =g_list_prepend( parms->moved, boxed );
+		}
+	}
+
+	return( FALSE );
+}
+
+static gboolean
 object_object_is_valid( const NAObjectAction *action )
 {
 	gboolean is_valid;
@@ -477,10 +533,10 @@ na_object_action_get_new_profile_name( const NAObjectAction *action )
 	if( !action->private->dispose_has_run ){
 
 		last_allocated = na_object_get_last_allocated( action );
-		for( i = last_allocated + 1 ; !ok ; ++i ){
 
+		for( i = last_allocated + 1 ; !ok ; ++i ){
 			g_free( candidate );
-			candidate = g_strdup_printf( "%s%d", NA_PROFILE_DEFAULT_PREFIX, i );
+			candidate = g_strdup_printf( "profile-%d", i );
 
 			if( !na_object_get_item( action, candidate )){
 				ok = TRUE;
@@ -494,6 +550,7 @@ na_object_action_get_new_profile_name( const NAObjectAction *action )
 		}
 	}
 
+	/*g_debug( "returning candidate=%s", candidate );*/
 	return( candidate );
 }
 
diff --git a/src/core/na-object-id-enum.c b/src/core/na-object-id-factory.c
similarity index 84%
rename from src/core/na-object-id-enum.c
rename to src/core/na-object-id-factory.c
index 1554fdb..aaf8663 100644
--- a/src/core/na-object-id-enum.c
+++ b/src/core/na-object-id-factory.c
@@ -32,55 +32,56 @@
 #include <config.h>
 #endif
 
-#include <api/na-ifactory-object-enum.h>
-#include <api/na-ifactory-object-str.h>
+#include <api/na-ifactory-object-data.h>
+#include <api/na-data-def.h>
+#include <api/na-data-types.h>
 
-NadfIdType id_iddef [] = {
+NADataDef data_def_id [] = {
 
-	{ NADF_DATA_ID,
-				"na-object-id",
+	{ NAFO_DATA_ID,
 				FALSE,
 				"NAObjectId identifiant",
 				"Internal identifiant of the NAObjectId object. " \
 				"Historically a UUID used as a GConf directory (thus ASCII, case insensitive), " \
 				"it is also the basename of the .desktop file (thus UTF-8, case sensitive).",
-				NADF_TYPE_STRING,
+				NAFD_TYPE_STRING,
 				NULL,
 				TRUE,
 				TRUE,
 				TRUE,
 				FALSE,
 				NULL,
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_LABEL,
-				"na-object-label",
+	{ NAFO_DATA_LABEL,
 				TRUE,
 				"NAObjectId label",
 				"Main label of the NAObjectId object. " \
 				"Serves as a default for the toolbar label of an action.",
-				NADF_TYPE_LOCALE_STRING,
+				NAFD_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
 				TRUE,
 				FALSE,
 				TRUE,
 				"label",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_PARENT,
-				"na-object-parent",
+	{ NAFO_DATA_PARENT,
 				FALSE,
 				"NAObjectId Parent",
 				"The NAObjectItem which is the parent of this object.",
-				NADF_TYPE_POINTER,
+				NAFD_TYPE_POINTER,
 				NULL,
 				FALSE,
 				FALSE,
 				FALSE,
 				FALSE,
 				NULL,
-				NULL },
+				NULL,
+				FALSE },
 
-	{ 0 },
+	{ NULL },
 };
diff --git a/src/core/na-object-item-enum.c b/src/core/na-object-item-factory.c
similarity index 79%
rename from src/core/na-object-item-enum.c
rename to src/core/na-object-item-factory.c
index 8bf56c4..03ba724 100644
--- a/src/core/na-object-item-enum.c
+++ b/src/core/na-object-item-factory.c
@@ -32,104 +32,104 @@
 #include <config.h>
 #endif
 
-#include <api/na-ifactory-object-enum.h>
-#include <api/na-ifactory-object-str.h>
+#include <api/na-ifactory-object-data.h>
+#include <api/na-data-def.h>
+#include <api/na-data-types.h>
 
 static void free_items_list( void * list );
 
-NadfIdType item_iddef [] = {
+NADataDef data_def_item [] = {
 
-	{ NADF_DATA_TOOLTIP,
-				"na-object-tooltip",
+	{ NAFO_DATA_TOOLTIP,
 				TRUE,
 				"Item tooltip",
 				"Tooltip associated to the item in the context menu or in the toolbar.",
-				NADF_TYPE_LOCALE_STRING,
+				NAFD_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
 				TRUE,
 				FALSE,
 				TRUE,
 				"tooltip",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_ICON,
-				"na-object-icon",
+	{ NAFO_DATA_ICON,
 				TRUE,
 				"Icon name",
 				"Icon displayed in the context menu and in the toolbar. " \
 				"May be the name of a themed icon, or the full path to any appropriate image.",
-				NADF_TYPE_LOCALE_STRING,
+				NAFD_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
 				TRUE,
 				FALSE,
 				TRUE,
 				"icon",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_DESCRIPTION,
-				"na-object-description",
+	{ NAFO_DATA_DESCRIPTION,
 				TRUE,
 				"Description",
 				"Some text which explains the goal of the menu or the action. " \
 				"Will be used, e.g. when displaying available items on a web site.",
-				NADF_TYPE_LOCALE_STRING,
+				NAFD_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
 				TRUE,
 				FALSE,
 				TRUE,
 				"description",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_SUBITEMS,
-				"na-object-subitems",
+	{ NAFO_DATA_SUBITEMS,
 				FALSE,
 				"Subitems",
 				"List of subitems objects",
-				NADF_TYPE_POINTER,
+				NAFD_TYPE_POINTER,
 				NULL,
 				FALSE,
 				FALSE,
 				FALSE,
 				FALSE,
 				NULL,
-				free_items_list },
+				free_items_list,
+				FALSE },
 
-	{ NADF_DATA_SUBITEMS_SLIST,
-				"na-object-subitems-slist",
+	{ NAFO_DATA_SUBITEMS_SLIST,
 				TRUE,
 				"Subitems",
 				"List of subitems ids, " \
 				"as readen from corresponding entry from the storage subsystem.",
-				NADF_TYPE_STRING_LIST,
+				NAFD_TYPE_STRING_LIST,
 				NULL,
 				FALSE,
 				FALSE,
 				FALSE,
 				FALSE,
 				"items",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_ENABLED,
-				"na-object-enabled",
+	{ NAFO_DATA_ENABLED,
 				TRUE,
 				"Enabled",
 				"Is the item enabled ? " \
 				"When FALSE, the item will never be candidate to the context menu," \
 				"nor to the toolbar.",
-				NADF_TYPE_BOOLEAN,
+				NAFD_TYPE_BOOLEAN,
 				"TRUE",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"enabled",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_READONLY,
-				"na-object-readonly",
+	{ NAFO_DATA_READONLY,
 				FALSE,
 				"Read-only",
 				"Is the item only readable ? " \
@@ -138,44 +138,45 @@ NadfIdType item_iddef [] = {
 				"as this also depend of parameters set by user and administrator. " \
 				"Also, a property initially set to FALSE when first unserializing may be set to" \
 				"TRUE if an eccor occurs on a later write operation.",
-				NADF_TYPE_BOOLEAN,
+				NAFD_TYPE_BOOLEAN,
 				"FALSE",
 				TRUE,
 				FALSE,
 				FALSE,
 				FALSE,
 				NULL,
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_PROVIDER,
-				"na-object-provider",
+	{ NAFO_DATA_PROVIDER,
 				FALSE,
 				"I/O provider",
 				"A pointer to the NAIOProvider object.",
-				NADF_TYPE_POINTER,
+				NAFD_TYPE_POINTER,
 				NULL,
 				TRUE,
 				FALSE,
 				FALSE,
 				FALSE,
 				NULL,
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_PROVIDER_DATA,
-				"na-object-provider-data",
+	{ NAFO_DATA_PROVIDER_DATA,
 				FALSE,
 				"I/O provider data",
 				"A pointer to some NAIOProvider specific data.",
-				NADF_TYPE_POINTER,
+				NAFD_TYPE_POINTER,
 				NULL,
 				TRUE,
 				FALSE,
 				FALSE,
 				FALSE,
 				NULL,
-				NULL },
+				NULL,
+				FALSE },
 
-	{ 0 },
+	{ NULL },
 };
 
 static void
diff --git a/src/core/na-object-menu-enum.c b/src/core/na-object-menu-factory.c
similarity index 71%
rename from src/core/na-object-menu-enum.c
rename to src/core/na-object-menu-factory.c
index b71addb..64345ac 100644
--- a/src/core/na-object-menu-enum.c
+++ b/src/core/na-object-menu-factory.c
@@ -32,20 +32,21 @@
 #include <config.h>
 #endif
 
-#include <api/na-ifactory-object-enum.h>
-#include <api/na-ifactory-object-str.h>
+#include <api/na-ifactory-object-data.h>
+#include <api/na-data-def.h>
+#include <api/na-data-types.h>
 
-extern NadfIdType id_iddef [];			/* defined in na-object-id-enum.c */
-extern NadfIdType item_iddef [];		/* defined in na-object-item-enum.c */
+extern NADataDef data_def_id [];			/* defined in na-object-id-factory.c */
+extern NADataDef data_def_item [];			/* defined in na-object-item-factory.c */
 
-static NadfIdType menu_iddef [] = {
-	{ 0 },
+static NADataDef data_def_menu [] = {
+	{ NULL },
 };
 
-NadfIdGroup menu_id_groups [] = {
-	{ NA_FACTORY_OBJECT_ID_GROUP,         id_iddef },
-	{ NA_FACTORY_OBJECT_ITEM_GROUP,       item_iddef },
-	{ NA_FACTORY_OBJECT_MENU_GROUP,       menu_iddef },
+NADataGroup menu_data_groups [] = {
+	{ NA_FACTORY_OBJECT_ID_GROUP,         data_def_id },
+	{ NA_FACTORY_OBJECT_ITEM_GROUP,       data_def_item },
+	{ NA_FACTORY_OBJECT_MENU_GROUP,       data_def_menu },
 	{ NA_FACTORY_OBJECT_CONDITIONS_GROUP, NULL },
-	{ 0 }
+	{ NULL }
 };
diff --git a/src/core/na-object-menu.c b/src/core/na-object-menu.c
index de7f76e..c72b118 100644
--- a/src/core/na-object-menu.c
+++ b/src/core/na-object-menu.c
@@ -33,6 +33,7 @@
 #endif
 
 #include <glib/gi18n.h>
+#include <string.h>
 
 #include <api/na-ifactory-object.h>
 #include <api/na-object-api.h>
@@ -52,34 +53,35 @@ struct NAObjectMenuPrivate {
 	gboolean dispose_has_run;
 };
 
-										/* i18n: default label for a new menu */
+/* i18n: default label for a new menu */
 #define NEW_NAUTILUS_MENU				N_( "New Nautilus menu" )
 
-extern NadfIdGroup menu_id_groups [];	/* defined in na-item-menu-enum.c */
+extern NADataGroup menu_data_groups [];			/* defined in na-item-menu-factory.c */
 
 static NAObjectItemClass *st_parent_class = NULL;
 
-static GType    register_type( void );
-static void     class_init( NAObjectMenuClass *klass );
-static void     instance_init( GTypeInstance *instance, gpointer klass );
-static void     instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
-static void     instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
-static void     instance_dispose( GObject *object );
-static void     instance_finalize( GObject *object );
-
-static gboolean object_is_valid( const NAObject *object );
-
-static void     ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
-static guint    ifactory_object_get_version( const NAIFactoryObject *instance );
-static gchar   *ifactory_object_get_default( const NAIFactoryObject *instance, const NadfIdType *iddef );
-static void     ifactory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source );
-static gboolean ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
-static gboolean ifactory_object_is_valid( const NAIFactoryObject *object );
-static void     ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
-static void     ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
-
-static gboolean menu_is_valid( const NAObjectMenu *menu );
-static gboolean is_valid_label( const NAObjectMenu *menu );
+static GType        register_type( void );
+static void         class_init( NAObjectMenuClass *klass );
+static void         instance_init( GTypeInstance *instance, gpointer klass );
+static void         instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
+static void         instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
+static void         instance_dispose( GObject *object );
+static void         instance_finalize( GObject *object );
+
+static gboolean     object_is_valid( const NAObject *object );
+
+static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
+static guint        ifactory_object_get_version( const NAIFactoryObject *instance );
+static NADataGroup *ifactory_object_get_groups( const NAIFactoryObject *instance );
+static gchar       *ifactory_object_get_default( const NAIFactoryObject *instance, const NADataDef *iddef );
+static void         ifactory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source );
+static gboolean     ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
+static gboolean     ifactory_object_is_valid( const NAIFactoryObject *object );
+static void         ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+static void         ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
+
+static gboolean     menu_is_valid( const NAObjectMenu *menu );
+static gboolean     is_valid_label( const NAObjectMenu *menu );
 
 GType
 na_object_menu_get_type( void )
@@ -124,7 +126,9 @@ register_type( void )
 
 	g_type_add_interface_static( type, NA_IFACTORY_OBJECT_TYPE, &ifactory_object_iface_info );
 
-	na_factory_provider_register( type, menu_id_groups );
+#if 0
+	na_factory_object_register_type( type, menu_id_groups );
+#endif
 
 	return( type );
 }
@@ -154,7 +158,7 @@ class_init( NAObjectMenuClass *klass )
 
 	klass->private = g_new0( NAObjectMenuClassPrivate, 1 );
 
-	na_factory_object_properties( object_class );
+	na_factory_object_define_properties( object_class, menu_data_groups );
 }
 
 static void
@@ -171,8 +175,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self = NA_OBJECT_MENU( instance );
 
 	self->private = g_new0( NAObjectMenuPrivate, 1 );
-
-	na_factory_object_init( NA_IFACTORY_OBJECT( instance ));
 }
 
 static void
@@ -183,7 +185,7 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 
 	if( !NA_OBJECT_MENU( object )->private->dispose_has_run ){
 
-		na_factory_object_set_value( NA_IFACTORY_OBJECT( object ), property_id, value, spec );
+		na_factory_object_get_as_value( NA_IFACTORY_OBJECT( object ), g_quark_to_string( property_id ), value );
 	}
 }
 
@@ -195,7 +197,7 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 
 	if( !NA_OBJECT_MENU( object )->private->dispose_has_run ){
 
-		na_factory_object_set_from_value( NA_IFACTORY_OBJECT( object ), property_id, value );
+		na_factory_object_set_from_value( NA_IFACTORY_OBJECT( object ), g_quark_to_string( property_id ), value );
 	}
 }
 
@@ -236,7 +238,7 @@ instance_finalize( GObject *object )
 
 	g_free( self->private );
 
-	na_factory_object_finalize( NA_IFACTORY_OBJECT( object ));
+	na_factory_object_finalize_instance( NA_IFACTORY_OBJECT( object ));
 
 	/* chain call to parent class */
 	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
@@ -260,6 +262,7 @@ ifactory_object_iface_init( NAIFactoryObjectInterface *iface )
 	g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
 
 	iface->get_version = ifactory_object_get_version;
+	iface->get_groups = ifactory_object_get_groups;
 	iface->get_default = ifactory_object_get_default;
 	iface->copy = ifactory_object_copy;
 	iface->are_equal = ifactory_object_are_equal;
@@ -276,18 +279,22 @@ ifactory_object_get_version( const NAIFactoryObject *instance )
 	return( 1 );
 }
 
+static NADataGroup *
+ifactory_object_get_groups( const NAIFactoryObject *instance )
+{
+	return( menu_data_groups );
+}
+
 static gchar *
-ifactory_object_get_default( const NAIFactoryObject *instance, const NadfIdType *iddef )
+ifactory_object_get_default( const NAIFactoryObject *instance, const NADataDef *def )
 {
 	gchar *value;
 
 	value = NULL;
 
-	switch( iddef->id ){
+	if( !strcmp( def->name, NAFO_DATA_LABEL )){
 
-		case NADF_DATA_LABEL:
-			value = g_strdup( NEW_NAUTILUS_MENU );
-			break;
+		value = g_strdup( NEW_NAUTILUS_MENU );
 	}
 
 	return( value );
diff --git a/src/core/na-object-profile-enum.c b/src/core/na-object-profile-factory.c
similarity index 71%
rename from src/core/na-object-profile-enum.c
rename to src/core/na-object-profile-factory.c
index dbfe967..bffa5a9 100644
--- a/src/core/na-object-profile-enum.c
+++ b/src/core/na-object-profile-factory.c
@@ -32,167 +32,168 @@
 #include <config.h>
 #endif
 
-#include <api/na-ifactory-object-enum.h>
-#include <api/na-ifactory-object-str.h>
+#include <api/na-ifactory-object-data.h>
+#include <api/na-data-def.h>
+#include <api/na-data-types.h>
 
-extern NadfIdType id_iddef [];			/* defined in na-object-id-enum.c */
+extern NADataDef data_def_id [];			/* defined in na-object-id-factory.c */
 
-static NadfIdType profile_iddef [] = {
+static NADataDef data_def_profile [] = {
 
-	{ NADF_DATA_PATH,
-				"na-object-path",
+	{ NAFO_DATA_PATH,
 				TRUE,
 				"Command path",
 				"The path to the command.",
-				NADF_TYPE_STRING,
+				NAFD_TYPE_STRING,
 				"",
 				TRUE,
 				TRUE,
 				TRUE,
 				FALSE,
 				"path",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_PARAMETERS,
-				"na-object-parameters",
+	{ NAFO_DATA_PARAMETERS,
 				TRUE,
 				"Command parameters",
 				"The parameters of the command.",
-				NADF_TYPE_STRING,
+				NAFD_TYPE_STRING,
 				"",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"parameters",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_BASENAMES,
-				"na-object-basenames",
+	{ NAFO_DATA_BASENAMES,
 				TRUE,
 				"Basenames",
 				"The basenames the selection must match. " \
 				"Defaults to '*'.",
-				NADF_TYPE_STRING_LIST,
+				NAFD_TYPE_STRING_LIST,
 				"*",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"basenames",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_MATCHCASE,
-				"na-object-matchcase",
+	{ NAFO_DATA_MATCHCASE,
 				TRUE,
 				"Case sensitive",
 				"Whether the specified basenames are case sensitive." \
 				"Defaults to 'true'.",
-				NADF_TYPE_BOOLEAN,
+				NAFD_TYPE_BOOLEAN,
 				"TRUE",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"matchcase",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_MIMETYPES,
-				"na-object-mimetypes",
+	{ NAFO_DATA_MIMETYPES,
 				TRUE,
 				"Mimetypes",
 				"The mimetypes the selection must match." \
 				"Defaults to '*'.",
-				NADF_TYPE_STRING_LIST,
+				NAFD_TYPE_STRING_LIST,
 				"*",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"mimetypes",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_ISFILE,
-				"na-object-isfile",
+	{ NAFO_DATA_ISFILE,
 				TRUE,
 				"Applies to files only",
 				"Whether the profile only applies to files." \
 				"Defaults to 'true'",
-				NADF_TYPE_BOOLEAN,
+				NAFD_TYPE_BOOLEAN,
 				"TRUE",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"isfile",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_ISDIR,
-				"na-object-isdir",
+	{ NAFO_DATA_ISDIR,
 				TRUE,
 				"Applies to directories only",
 				"Whether the profile applies to directories only." \
 				"Defaults to 'false'",
-				NADF_TYPE_BOOLEAN,
+				NAFD_TYPE_BOOLEAN,
 				"FALSE",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"isdir",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_MULTIPLE,
-				"na-object-multiple",
+	{ NAFO_DATA_MULTIPLE,
 				TRUE,
 				"Multiple selection",
 				"Whether the selection may be multiple." \
 				"Defaults to 'false'.",
-				NADF_TYPE_BOOLEAN,
+				NAFD_TYPE_BOOLEAN,
 				"FALSE",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"accept-multiple-files",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_SCHEMES,
-				"na-object-schemes",
+	{ NAFO_DATA_SCHEMES,
 				TRUE,
 				"Schemes",
 				"The list of schemes the selection must match." \
 				"Defaults to 'file'.",
-				NADF_TYPE_STRING_LIST,
+				NAFD_TYPE_STRING_LIST,
 				"file",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"schemes",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ NADF_DATA_FOLDERS,
-				"na-object-folders",
+	{ NAFO_DATA_FOLDERS,
 				TRUE,
 				"Folders",
 				"The list of folders which apply when there is no selection." \
 				"Defaults to '/'.",
-				NADF_TYPE_STRING_LIST,
+				NAFD_TYPE_STRING_LIST,
 				"/",
 				TRUE,
 				TRUE,
 				FALSE,
 				FALSE,
 				"folders",
-				NULL },
+				NULL,
+				FALSE },
 
-	{ 0 },
+	{ NULL },
 };
 
-NadfIdGroup profile_id_groups [] = {
-	{ NA_FACTORY_OBJECT_ID_GROUP,         id_iddef },
-	{ NA_FACTORY_OBJECT_PROFILE_GROUP,    profile_iddef },
+NADataGroup profile_data_groups [] = {
+	{ NA_FACTORY_OBJECT_ID_GROUP,         data_def_id },
+	{ NA_FACTORY_OBJECT_PROFILE_GROUP,    data_def_profile },
 	{ NA_FACTORY_OBJECT_CONDITIONS_GROUP, NULL },
-	{ 0 }
+	{ NULL }
 };
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 4dbb9b7..e5f947a 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -32,9 +32,8 @@
 #include <config.h>
 #endif
 
-#include <string.h>
-
 #include <glib/gi18n.h>
+#include <string.h>
 
 #include <libnautilus-extension/nautilus-file-info.h>
 
@@ -59,55 +58,56 @@ struct NAObjectProfilePrivate {
 	gboolean dispose_has_run;
 };
 
-											/* i18n: default label for a new profile */
+/* i18n: default label for a new profile */
 #define DEFAULT_PROFILE						N_( "Default profile" )
 
 #define PROFILE_NAME_PREFIX					"profile-"
 
-extern NadfIdGroup profile_id_groups [];	/* defined in na-item-profile-enum.c */
+extern NADataGroup profile_data_groups [];	/* defined in na-item-profile-factory.c */
 
 static NAObjectIdClass *st_parent_class = NULL;
 
-static GType    register_type( void );
-static void     class_init( NAObjectProfileClass *klass );
-static void     instance_init( GTypeInstance *instance, gpointer klass );
-static void     instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
-static void     instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
-static void     instance_dispose( GObject *object );
-static void     instance_finalize( GObject *object );
-
-static gboolean object_is_valid( const NAObject *object );
-
-static void     ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
-static guint    ifactory_object_get_version( const NAIFactoryObject *instance );
-static gchar   *ifactory_object_get_default( const NAIFactoryObject *instance, const NadfIdType *iddef );
-static gboolean ifactory_object_is_valid( const NAIFactoryObject *object );
-static void     ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
-static void     ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
-
-static gboolean profile_is_valid( const NAObjectProfile *profile );
-static gboolean is_valid_path_parameters( const NAObjectProfile *profile );
-static gboolean is_valid_basenames( const NAObjectProfile *profile );
-static gboolean is_valid_mimetypes( const NAObjectProfile *profile );
-static gboolean is_valid_isfiledir( const NAObjectProfile *profile );
-static gboolean is_valid_schemes( const NAObjectProfile *profile );
-static gboolean is_valid_folders( const NAObjectProfile *profile );
-
-static gchar   *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
-
-static gboolean is_target_background_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
-static gboolean is_target_toolbar_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
-static gboolean is_current_folder_inside( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
-static gboolean is_target_selection_candidate( const NAObjectProfile *profile, GList *files, gboolean from_nautilus );
-
-static gchar   *parse_parameters( const NAObjectProfile *profile, gint target, GList* files, gboolean from_nautilus );
-static gboolean tracked_is_directory( void *iter, gboolean from_nautilus );
-static gchar   *tracked_to_basename( void *iter, gboolean from_nautilus );
-static GFile   *tracked_to_location( void *iter, gboolean from_nautilus );
-static gchar   *tracked_to_mimetype( void *iter, gboolean from_nautilus );
-static gchar   *tracked_to_scheme( void *iter, gboolean from_nautilus );
-static gchar   *tracked_to_uri( void *iter, gboolean from_nautilus );
-static int      validate_schemes( GSList *schemes2test, void *iter, gboolean from_nautilus );
+static GType        register_type( void );
+static void         class_init( NAObjectProfileClass *klass );
+static void         instance_init( GTypeInstance *instance, gpointer klass );
+static void         instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
+static void         instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
+static void         instance_dispose( GObject *object );
+static void         instance_finalize( GObject *object );
+
+static gboolean     object_is_valid( const NAObject *object );
+
+static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
+static guint        ifactory_object_get_version( const NAIFactoryObject *instance );
+static NADataGroup *ifactory_object_get_groups( const NAIFactoryObject *instance );
+static gchar       *ifactory_object_get_default( const NAIFactoryObject *instance, const NADataDef *iddef );
+static gboolean     ifactory_object_is_valid( const NAIFactoryObject *object );
+static void         ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
+static void         ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
+
+static gboolean     profile_is_valid( const NAObjectProfile *profile );
+static gboolean     is_valid_path_parameters( const NAObjectProfile *profile );
+static gboolean     is_valid_basenames( const NAObjectProfile *profile );
+static gboolean     is_valid_mimetypes( const NAObjectProfile *profile );
+static gboolean     is_valid_isfiledir( const NAObjectProfile *profile );
+static gboolean     is_valid_schemes( const NAObjectProfile *profile );
+static gboolean     is_valid_folders( const NAObjectProfile *profile );
+
+static gchar       *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
+
+static gboolean     is_target_background_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
+static gboolean     is_target_toolbar_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
+static gboolean     is_current_folder_inside( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
+static gboolean     is_target_selection_candidate( const NAObjectProfile *profile, GList *files, gboolean from_nautilus );
+
+static gchar       *parse_parameters( const NAObjectProfile *profile, gint target, GList* files, gboolean from_nautilus );
+static gboolean     tracked_is_directory( void *iter, gboolean from_nautilus );
+static gchar       *tracked_to_basename( void *iter, gboolean from_nautilus );
+static GFile       *tracked_to_location( void *iter, gboolean from_nautilus );
+static gchar       *tracked_to_mimetype( void *iter, gboolean from_nautilus );
+static gchar       *tracked_to_scheme( void *iter, gboolean from_nautilus );
+static gchar       *tracked_to_uri( void *iter, gboolean from_nautilus );
+static int          validate_schemes( GSList *schemes2test, void *iter, gboolean from_nautilus );
 
 GType
 na_object_profile_get_type( void )
@@ -151,7 +151,9 @@ register_type( void )
 
 	g_type_add_interface_static( type, NA_IFACTORY_OBJECT_TYPE, &ifactory_object_iface_info );
 
-	na_factory_provider_register( type, profile_id_groups );
+#if 0
+	na_factory_object_register_type( type, profile_id_groups );
+#endif
 
 	return( type );
 }
@@ -185,7 +187,7 @@ class_init( NAObjectProfileClass *klass )
 
 	klass->private = g_new0( NAObjectProfileClassPrivate, 1 );
 
-	na_factory_object_properties( object_class );
+	na_factory_object_define_properties( object_class, profile_data_groups );
 }
 
 static void
@@ -204,8 +206,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self->private = g_new0( NAObjectProfilePrivate, 1 );
 
 	self->private->dispose_has_run = FALSE;
-
-	na_factory_object_init( NA_IFACTORY_OBJECT( instance ));
 }
 
 static void
@@ -216,7 +216,7 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 
 	if( !NA_OBJECT_PROFILE( object )->private->dispose_has_run ){
 
-		na_factory_object_set_value( NA_IFACTORY_OBJECT( object ), property_id, value, spec );
+		na_factory_object_get_as_value( NA_IFACTORY_OBJECT( object ), g_quark_to_string( property_id ), value );
 	}
 }
 
@@ -228,7 +228,7 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 
 	if( !NA_OBJECT_PROFILE( object )->private->dispose_has_run ){
 
-		na_factory_object_set_from_value( NA_IFACTORY_OBJECT( object ), property_id, value );
+		na_factory_object_set_from_value( NA_IFACTORY_OBJECT( object ), g_quark_to_string( property_id ), value );
 	}
 }
 
@@ -269,7 +269,7 @@ instance_finalize( GObject *object )
 
 	g_free( self->private );
 
-	na_factory_object_finalize( NA_IFACTORY_OBJECT( object ));
+	na_factory_object_finalize_instance( NA_IFACTORY_OBJECT( object ));
 
 	/* chain call to parent class */
 	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
@@ -293,6 +293,7 @@ ifactory_object_iface_init( NAIFactoryObjectInterface *iface )
 	g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
 
 	iface->get_version = ifactory_object_get_version;
+	iface->get_groups = ifactory_object_get_groups;
 	iface->get_default = ifactory_object_get_default;
 	iface->copy = NULL;
 	iface->are_equal = NULL;
@@ -309,22 +310,24 @@ ifactory_object_get_version( const NAIFactoryObject *instance )
 	return( 1 );
 }
 
+static NADataGroup *
+ifactory_object_get_groups( const NAIFactoryObject *instance )
+{
+	return( profile_data_groups );
+}
+
 static gchar *
-ifactory_object_get_default( const NAIFactoryObject *instance, const NadfIdType *iddef )
+ifactory_object_get_default( const NAIFactoryObject *instance, const NADataDef *def )
 {
 	gchar *value;
 
 	value = NULL;
 
-	switch( iddef->id ){
+	if( !strcmp( def->name, NAFO_DATA_ID )){
+		value = g_strdup( PROFILE_NAME_PREFIX "zero" );
 
-		case NADF_DATA_ID:
-			value = g_strdup( PROFILE_NAME_PREFIX "zero" );
-			break;
-
-		case NADF_DATA_LABEL:
-			value = g_strdup( DEFAULT_PROFILE );
-			break;
+	} else if( !strcmp( def->name, NAFO_DATA_LABEL )){
+		value = g_strdup( DEFAULT_PROFILE );
 	}
 
 	return( value );
diff --git a/src/io-desktop/nadp-desktop-file.c b/src/io-desktop/nadp-desktop-file.c
index 3cac402..3fea206 100644
--- a/src/io-desktop/nadp-desktop-file.c
+++ b/src/io-desktop/nadp-desktop-file.c
@@ -372,9 +372,17 @@ nadp_desktop_file_get_id( const NadpDesktopFile *ndf )
 
 /**
  * nadp_desktop_file_get_boolean:
+ * @ndf: this #NadpDesktopFile instance.
+ * @group: the searched group.
+ * @entry: the searched entry.
+ * @key_found: set to %TRUE if the key has been found, to %FALSE else.
+ * @default_value: value to be set if key has not been found.
+ *
+ * Returns: the readen value, or the default value if the entry has not
+ * been found in the given group.
  */
 gboolean
-nadp_desktop_file_get_boolean( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, gboolean default_value )
+nadp_desktop_file_get_boolean( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, gboolean *key_found, gboolean default_value )
 {
 	static const gchar *thisfn = "nadp_desktop_file_get_boolean";
 	gboolean value;
@@ -383,6 +391,7 @@ nadp_desktop_file_get_boolean( const NadpDesktopFile *ndf, const gchar *group, c
 	GError *error;
 
 	value = default_value;
+	*key_found = FALSE;
 
 	g_return_val_if_fail( NADP_IS_DESKTOP_FILE( ndf ), FALSE );
 
@@ -402,6 +411,7 @@ nadp_desktop_file_get_boolean( const NadpDesktopFile *ndf, const gchar *group, c
 
 			} else {
 				value = read_value;
+				*key_found = TRUE;
 			}
 		}
 	}
@@ -411,13 +421,21 @@ nadp_desktop_file_get_boolean( const NadpDesktopFile *ndf, const gchar *group, c
 
 /**
  * nadp_desktop_file_get_locale_string:
+ * @ndf: this #NadpDesktopFile instance.
+ * @group: the searched group.
+ * @entry: the searched entry.
+ * @key_found: set to %TRUE if the key has been found, to %FALSE else.
+ * @default_value: value to be set if key has not been found.
+ *
+ * Returns: the readen value, or the default value if the entry has not
+ * been found in the given group.
  *
  * Note that g_key_file_has_key doesn't deal correctly with localized
  * strings which have a key[modifier] (it recognizes them as the key
  *  "key[modifier]", not "key")
  */
 gchar *
-nadp_desktop_file_get_locale_string( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, const gchar *default_value )
+nadp_desktop_file_get_locale_string( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, gboolean *key_found, const gchar *default_value )
 {
 	static const gchar *thisfn = "nadp_desktop_file_get_locale_string";
 	gchar *value;
@@ -425,6 +443,7 @@ nadp_desktop_file_get_locale_string( const NadpDesktopFile *ndf, const gchar *gr
 	GError *error;
 
 	value = g_strdup( default_value );
+	*key_found = FALSE;
 
 	g_return_val_if_fail( NADP_IS_DESKTOP_FILE( ndf ), NULL );
 
@@ -442,6 +461,7 @@ nadp_desktop_file_get_locale_string( const NadpDesktopFile *ndf, const gchar *gr
 		} else {
 			g_free( value );
 			value = read_value;
+			*key_found = TRUE;
 		}
 	}
 
@@ -450,9 +470,17 @@ nadp_desktop_file_get_locale_string( const NadpDesktopFile *ndf, const gchar *gr
 
 /**
  * nadp_desktop_file_get_string:
+ * @ndf: this #NadpDesktopFile instance.
+ * @group: the searched group.
+ * @entry: the searched entry.
+ * @key_found: set to %TRUE if the key has been found, to %FALSE else.
+ * @default_value: value to be set if key has not been found.
+ *
+ * Returns: the readen value, or the default value if the entry has not
+ * been found in the given group.
  */
 gchar *
-nadp_desktop_file_get_string( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, const gchar *default_value )
+nadp_desktop_file_get_string( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, gboolean *key_found, const gchar *default_value )
 {
 	static const gchar *thisfn = "nadp_desktop_file_get_string";
 	gchar *value;
@@ -461,6 +489,7 @@ nadp_desktop_file_get_string( const NadpDesktopFile *ndf, const gchar *group, co
 	GError *error;
 
 	value = g_strdup( default_value );
+	*key_found = FALSE;
 
 	g_return_val_if_fail( NADP_IS_DESKTOP_FILE( ndf ), NULL );
 
@@ -482,6 +511,7 @@ nadp_desktop_file_get_string( const NadpDesktopFile *ndf, const gchar *group, co
 			} else {
 				g_free( value );
 				value = read_value;
+				*key_found = TRUE;
 			}
 		}
 	}
@@ -491,9 +521,17 @@ nadp_desktop_file_get_string( const NadpDesktopFile *ndf, const gchar *group, co
 
 /**
  * nadp_desktop_file_get_string_list:
+ * @ndf: this #NadpDesktopFile instance.
+ * @group: the searched group.
+ * @entry: the searched entry.
+ * @key_found: set to %TRUE if the key has been found, to %FALSE else.
+ * @default_value: value to be set if key has not been found.
+ *
+ * Returns: the readen value, or the default value if the entry has not
+ * been found in the given group.
  */
 GSList *
-nadp_desktop_file_get_string_list( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, const gchar *default_value )
+nadp_desktop_file_get_string_list( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, gboolean *key_found, const gchar *default_value )
 {
 	static const gchar *thisfn = "nadp_desktop_file_get_string_list";
 	GSList *value;
@@ -502,6 +540,7 @@ nadp_desktop_file_get_string_list( const NadpDesktopFile *ndf, const gchar *grou
 	GError *error;
 
 	value = g_slist_append( NULL, g_strdup( default_value ));
+	*key_found = FALSE;
 
 	g_return_val_if_fail( NADP_IS_DESKTOP_FILE( ndf ), NULL );
 
@@ -522,6 +561,7 @@ nadp_desktop_file_get_string_list( const NadpDesktopFile *ndf, const gchar *grou
 			} else {
 				na_core_utils_slist_free( value );
 				value = na_core_utils_slist_from_array(( const gchar ** ) read_array );
+				*key_found = TRUE;
 			}
 
 			g_strfreev( read_array );
@@ -531,6 +571,53 @@ nadp_desktop_file_get_string_list( const NadpDesktopFile *ndf, const gchar *grou
 	return( value );
 }
 
+/**
+ * nadp_desktop_file_get_uint:
+ * @ndf: this #NadpDesktopFile instance.
+ * @group: the searched group.
+ * @entry: the searched entry.
+ * @key_found: set to %TRUE if the key has been found, to %FALSE else.
+ * @default_value: value to be set if key has not been found.
+ *
+ * Returns: the readen value, or the default value if the entry has not
+ * been found in the given group.
+ */
+guint
+nadp_desktop_file_get_uint( const NadpDesktopFile *ndf, const gchar *group, const gchar *entry, gboolean *key_found, guint default_value )
+{
+	static const gchar *thisfn = "nadp_desktop_file_get_uint";
+	guint value;
+	gboolean has_entry;
+	GError *error;
+
+	value = default_value;
+	*key_found = FALSE;
+
+	g_return_val_if_fail( NADP_IS_DESKTOP_FILE( ndf ), 0 );
+
+	if( !ndf->private->dispose_has_run ){
+
+		error = NULL;
+		has_entry = g_key_file_has_key( ndf->private->key_file, group, entry, &error );
+		if( error ){
+			g_warning( "%s: %s", thisfn, error->message );
+			g_error_free( error );
+
+		} else if( has_entry ){
+			value = ( guint ) g_key_file_get_integer( ndf->private->key_file, group, entry, &error );
+			if( error ){
+				g_warning( "%s: %s", thisfn, error->message );
+				g_error_free( error );
+
+			} else {
+				*key_found = TRUE;
+			}
+		}
+	}
+
+	return( value );
+}
+
 #if 0
 /**
  * nadp_desktop_file_get_key_file_path:
diff --git a/src/io-desktop/nadp-desktop-file.h b/src/io-desktop/nadp-desktop-file.h
index 99c029f..e024eae 100644
--- a/src/io-desktop/nadp-desktop-file.h
+++ b/src/io-desktop/nadp-desktop-file.h
@@ -83,10 +83,11 @@ gboolean         nadp_desktop_file_write            ( NadpDesktopFile *ndf );
 gchar           *nadp_desktop_file_get_file_type    ( const NadpDesktopFile *ndf );
 
 gchar           *nadp_desktop_file_get_id           ( const NadpDesktopFile *ndf );
-gboolean         nadp_desktop_file_get_boolean      ( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, gboolean default_value );
-gchar           *nadp_desktop_file_get_locale_string( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, const gchar *default_value );
-gchar           *nadp_desktop_file_get_string       ( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, const gchar *default_value );
-GSList          *nadp_desktop_file_get_string_list  ( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, const gchar *default_value );
+gboolean         nadp_desktop_file_get_boolean      ( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, gboolean *key_found, gboolean default_value );
+gchar           *nadp_desktop_file_get_locale_string( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, gboolean *key_found, const gchar *default_value );
+gchar           *nadp_desktop_file_get_string       ( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, gboolean *key_found, const gchar *default_value );
+GSList          *nadp_desktop_file_get_string_list  ( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, gboolean *key_found, const gchar *default_value );
+guint            nadp_desktop_file_get_uint         ( const NadpDesktopFile *ndf, const gchar *group, const gchar *key, gboolean *key_found, guint default_value );
 
 /* ... */
 
diff --git a/src/io-desktop/nadp-desktop-provider.c b/src/io-desktop/nadp-desktop-provider.c
index 8b6f2be..8b2bca7 100644
--- a/src/io-desktop/nadp-desktop-provider.c
+++ b/src/io-desktop/nadp-desktop-provider.c
@@ -33,11 +33,13 @@
 #endif
 
 #include <glib/gi18n.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include <api/na-core-utils.h>
 #include <api/na-iio-provider.h>
 #include <api/na-ifactory-provider.h>
+#include <api/na-data-types.h>
 
 #include "nadp-desktop-provider.h"
 #include "nadp-keys.h"
@@ -53,21 +55,21 @@ struct NadpDesktopProviderClassPrivate {
 static GType         st_module_type = 0;
 static GObjectClass *st_parent_class = NULL;
 
-static void    class_init( NadpDesktopProviderClass *klass );
-static void    instance_init( GTypeInstance *instance, gpointer klass );
-static void    instance_dispose( GObject *object );
-static void    instance_finalize( GObject *object );
+static void         class_init( NadpDesktopProviderClass *klass );
+static void         instance_init( GTypeInstance *instance, gpointer klass );
+static void         instance_dispose( GObject *object );
+static void         instance_finalize( GObject *object );
 
-static void    iio_provider_iface_init( NAIIOProviderInterface *iface );
-static gchar  *iio_provider_get_id( const NAIIOProvider *provider );
-static gchar  *iio_provider_get_name( const NAIIOProvider *provider );
-static guint   iio_provider_get_version( const NAIIOProvider *provider );
+static void         iio_provider_iface_init( NAIIOProviderInterface *iface );
+static gchar       *iio_provider_get_id( const NAIIOProvider *provider );
+static gchar       *iio_provider_get_name( const NAIIOProvider *provider );
+static guint        iio_provider_get_version( const NAIIOProvider *provider );
 
-static void    ifactory_provider_iface_init( NAIFactoryProviderInterface *iface );
-static guint   ifactory_provider_get_version( const NAIFactoryProvider *reader );
-static void    ifactory_provider_read_start( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *serializable, GSList **messages );
-static GValue *ifactory_provider_read_value( const NAIFactoryProvider *reader, void *reader_data, const NadfIdType *iddef, GSList **messages );
-static void    ifactory_provider_read_done( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *serializable, GSList **messages );
+static void         ifactory_provider_iface_init( NAIFactoryProviderInterface *iface );
+static guint        ifactory_provider_get_version( const NAIFactoryProvider *reader );
+static void         ifactory_provider_read_start( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *serializable, GSList **messages );
+static NADataBoxed *ifactory_provider_read_data( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *serializable, const NADataDef *iddef, GSList **messages );
+static void         ifactory_provider_read_done( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *serializable, GSList **messages );
 
 GType
 nadp_desktop_provider_get_type( void )
@@ -227,10 +229,10 @@ ifactory_provider_iface_init( NAIFactoryProviderInterface *iface )
 
 	iface->get_version = ifactory_provider_get_version;
 	iface->read_start = ifactory_provider_read_start;
-	iface->read_value = ifactory_provider_read_value;
+	iface->read_data = ifactory_provider_read_data;
 	iface->read_done = ifactory_provider_read_done;
 	iface->write_start = NULL;
-	iface->write_value = NULL;
+	iface->write_data = NULL;
 	iface->write_done = NULL;
 }
 
@@ -244,7 +246,7 @@ ifactory_provider_get_version( const NAIFactoryProvider *reader )
  * called before starting with reading an object
  */
 static void
-ifactory_provider_read_start( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *serializable, GSList **messages )
+ifactory_provider_read_start( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *serializable, GSList **messages )
 {
 	static const gchar *thisfn = "nadp_desktop_provider_ifactory_provider_read_start";
 
@@ -270,74 +272,92 @@ ifactory_provider_read_start( const NAIFactoryProvider *reader, void *reader_dat
  *   -> has been attached to the NAObjectItem in get_item() above
  * - the data type (+ reading default value)
  * - group and key names
+ *
+ * Returns: NULL if the key has not been found
+ * letting the caller deal with default values
  */
-static GValue *
-ifactory_provider_read_value( const NAIFactoryProvider *reader, void *reader_data, const NadfIdType *iddef, GSList **messages )
+static NADataBoxed *
+ifactory_provider_read_data( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *object, const NADataDef *def, GSList **messages )
 {
 	static const gchar *thisfn = "nadp_desktop_provider_ifactory_provider_read_value";
+	NADataBoxed *boxed;
+	gboolean found;
 	NadpReaderData *nrd;
-	GValue *value;
 	gchar *group, *key;
 	gchar *msg;
 	gchar *str_value;
 	gboolean bool_value;
 	GSList *slist_value;
+	guint uint_value;
 
-	/*g_debug( "%s: reader=%p (%s), reader_data=%p, iddef=%p, messages=%p",
+	/*g_debug( "%s: reader=%p (%s), reader_data=%p, def=%p, messages=%p",
 			thisfn,
 			( void * ) reader, G_OBJECT_TYPE_NAME( reader ),
 			( void * ) reader_data,
-			( void * ) iddef,
+			( void * ) def,
 			( void * ) messages );*/
 
 	g_return_val_if_fail( NA_IS_IFACTORY_PROVIDER( reader ), NULL );
 	g_return_val_if_fail( NADP_IS_DESKTOP_PROVIDER( reader ), NULL );
-	g_return_val_if_fail( iddef->serializable, NULL );
+	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
+	g_return_val_if_fail( def->serializable, NULL );
 
-	value = NULL;
+	boxed = NULL;
 
 	if( !NADP_DESKTOP_PROVIDER( reader )->private->dispose_has_run ){
 
 		nrd = ( NadpReaderData * ) reader_data;
 		g_return_val_if_fail( NADP_IS_DESKTOP_FILE( nrd->ndf ), NULL );
 
-		if( nadp_keys_get_group_and_key( iddef, &group, &key )){
-
-			value = g_new0( GValue, 1 );
+		if( nadp_keys_get_group_and_key( def, &group, &key )){
 
-			switch( iddef->type ){
+			switch( def->type ){
 
-				case NADF_TYPE_LOCALE_STRING:
-					g_value_init( value, G_TYPE_STRING );
-					str_value = nadp_desktop_file_get_locale_string( nrd->ndf, group, key, iddef->default_value );
-					/*g_value_set_string( value, str_value );*/
-					g_debug( "%s: %s=%s", thisfn, iddef->name, str_value );
+				case NAFD_TYPE_LOCALE_STRING:
+					str_value = nadp_desktop_file_get_locale_string( nrd->ndf, group, key, &found, def->default_value );
+					if( str_value && found ){
+						boxed = na_data_boxed_new( def );
+						na_data_boxed_set_from_void( boxed, str_value );
+					}
 					g_free( str_value );
 					break;
 
-				case NADF_TYPE_STRING:
-					g_value_init( value, G_TYPE_STRING );
-					str_value = nadp_desktop_file_get_string( nrd->ndf, group, key, iddef->default_value );
-					g_value_set_string( value, str_value );
-					/*g_debug( "%s: %s=%s", thisfn, iddef->name, str_value );*/
+				case NAFD_TYPE_STRING:
+					str_value = nadp_desktop_file_get_string( nrd->ndf, group, key, &found, def->default_value );
+					if( str_value && found ){
+						boxed = na_data_boxed_new( def );
+						na_data_boxed_set_from_void( boxed, str_value );
+					}
 					g_free( str_value );
 					break;
 
-				case NADF_TYPE_BOOLEAN:
-					g_value_init( value, G_TYPE_BOOLEAN );
-					bool_value = nadp_desktop_file_get_boolean( nrd->ndf, group, key, na_core_utils_boolean_from_string( iddef->default_value ));
-					g_value_set_boolean( value, bool_value );
-					/*g_debug( "%s: %s=%s", thisfn, iddef->name, bool_value ? "True":"False" );*/
+				case NAFD_TYPE_BOOLEAN:
+					bool_value = nadp_desktop_file_get_boolean( nrd->ndf, group, key, &found, na_core_utils_boolean_from_string( def->default_value ));
+					if( found ){
+						boxed = na_data_boxed_new( def );
+						na_data_boxed_set_from_void( boxed, GUINT_TO_POINTER( bool_value ));
+					}
+					break;
+
+				case NAFD_TYPE_STRING_LIST:
+					slist_value = nadp_desktop_file_get_string_list( nrd->ndf, group, key, &found, def->default_value );
+					if( slist_value && found ){
+						boxed = na_data_boxed_new( def );
+						na_data_boxed_set_from_void( boxed, slist_value );
+					}
+					na_core_utils_slist_free( slist_value );
 					break;
 
-				case NADF_TYPE_STRING_LIST:
-					g_value_init( value, G_TYPE_POINTER );
-					slist_value = nadp_desktop_file_get_string_list( nrd->ndf, group, key, iddef->default_value );
-					g_value_set_pointer( value, slist_value );
+				case NAFD_TYPE_UINT:
+					uint_value = nadp_desktop_file_get_uint( nrd->ndf, group, key, &found, atoi( def->default_value ));
+					if( found ){
+						boxed = na_data_boxed_new( def );
+						na_data_boxed_set_from_void( boxed, GUINT_TO_POINTER( uint_value ));
+					}
 					break;
 
 				default:
-					msg = g_strdup_printf( "%s: %d: unknown data type.", thisfn, iddef->type );
+					msg = g_strdup_printf( "%s: %d: invalid data type.", thisfn, def->type );
 					g_warning( "%s", msg );
 					*messages = g_slist_append( *messages, msg );
 			}
@@ -348,7 +368,7 @@ ifactory_provider_read_value( const NAIFactoryProvider *reader, void *reader_dat
 		}
 	}
 
-	return( value );
+	return( boxed );
 }
 
 /*
@@ -356,7 +376,7 @@ ifactory_provider_read_value( const NAIFactoryProvider *reader, void *reader_dat
  * nothing to do here
  */
 static void
-ifactory_provider_read_done( const NAIFactoryProvider *reader, void *reader_data, NAIFactoryObject *serializable, GSList **messages )
+ifactory_provider_read_done( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *serializable, GSList **messages )
 {
 	static const gchar *thisfn = "nadp_desktop_provider_ifactory_provider_read_done";
 	/*NAObjectProfile *profile;*/
diff --git a/src/io-desktop/nadp-keys.c b/src/io-desktop/nadp-keys.c
index fb80810..965dff2 100644
--- a/src/io-desktop/nadp-keys.c
+++ b/src/io-desktop/nadp-keys.c
@@ -32,15 +32,17 @@
 #include <config.h>
 #endif
 
-#include <api/na-ifactory-object-enum.h>
+#include <string.h>
+
+#include <api/na-ifactory-object-data.h>
 
 #include "nadp-keys.h"
 
 static NadpIdKey id_key [] = {
-	{ NADF_DATA_LABEL,   NADP_GROUP_DESKTOP, NADP_KEY_NAME },
-	{ NADF_DATA_TOOLTIP, NADP_GROUP_DESKTOP, NADP_KEY_TOOLTIP },
-	{ NADF_DATA_ICON,    NADP_GROUP_DESKTOP, NADP_KEY_ICON },
-	{ 0, NULL, NULL }
+	{ NAFO_DATA_LABEL,   NADP_GROUP_DESKTOP, NADP_KEY_NAME },
+	{ NAFO_DATA_TOOLTIP, NADP_GROUP_DESKTOP, NADP_KEY_TOOLTIP },
+	{ NAFO_DATA_ICON,    NADP_GROUP_DESKTOP, NADP_KEY_ICON },
+	{ NULL }
 };
 
 /**
@@ -52,7 +54,7 @@ static NadpIdKey id_key [] = {
  * Returns: %TRUE if the data has been found, %FALSE else.
  */
 gboolean
-nadp_keys_get_group_and_key( const NadfIdType *iddef, gchar **group, gchar **key )
+nadp_keys_get_group_and_key( const NADataDef *def, gchar **group, gchar **key )
 {
 	gboolean found;
 	int i;
@@ -63,7 +65,7 @@ nadp_keys_get_group_and_key( const NadfIdType *iddef, gchar **group, gchar **key
 
 	for( i = 0 ; id_key[i].data_id && !found ; ++i ){
 
-		if( id_key[i].data_id == iddef->id ){
+		if( !strcmp( id_key[i].data_id, def->name )){
 
 			*group = g_strdup( id_key[i].group );
 			*key = g_strdup( id_key[i].key );
diff --git a/src/io-desktop/nadp-keys.h b/src/io-desktop/nadp-keys.h
index 5924297..266a03a 100644
--- a/src/io-desktop/nadp-keys.h
+++ b/src/io-desktop/nadp-keys.h
@@ -31,7 +31,7 @@
 #ifndef __NADP_KEYS_H__
 #define __NADP_KEYS_H__
 
-#include <api/na-ifactory-object-str.h>
+#include <api/na-data-def.h>
 
 G_BEGIN_DECLS
 
@@ -93,13 +93,13 @@ G_BEGIN_DECLS
 #define NADP_VALUE_CAPABILITY_LOCAL					"Local"
 
 typedef struct {
-	guint  data_id;
+	gchar *data_id;
 	gchar *group;
 	gchar *key;
 }
 	NadpIdKey;
 
-gboolean nadp_keys_get_group_and_key( const NadfIdType *iddef, gchar **group, gchar **key );
+gboolean nadp_keys_get_group_and_key( const NADataDef *iddef, gchar **group, gchar **key );
 
 G_END_DECLS
 
diff --git a/src/io-desktop/nadp-reader.c b/src/io-desktop/nadp-reader.c
index 35741fb..3090f75 100644
--- a/src/io-desktop/nadp-reader.c
+++ b/src/io-desktop/nadp-reader.c
@@ -35,7 +35,7 @@
 #include <string.h>
 
 #include <api/na-core-utils.h>
-#include <api/na-ifactory-object-enum.h>
+#include <api/na-ifactory-object-data.h>
 #include <api/na-ifactory-provider.h>
 #include <api/na-object-api.h>
 
@@ -241,7 +241,6 @@ item_from_desktop_path( const NadpDesktopProvider *provider, DesktopPath *dps, G
 	NAIFactoryObject *item;
 	NadpDesktopFile *ndf;
 	gchar *type;
-	GType reader_type;
 	NadpReaderData *reader_data;
 	gchar *id;
 
@@ -251,33 +250,30 @@ item_from_desktop_path( const NadpDesktopProvider *provider, DesktopPath *dps, G
 	}
 
 	item = NULL;
-	reader_type = 0;
 	type = nadp_desktop_file_get_file_type( ndf );
 
 	if( !strcmp( type, NADP_VALUE_TYPE_MENU )){
-		reader_type = NA_OBJECT_MENU_TYPE;
+		item = NA_IFACTORY_OBJECT( na_object_menu_new());
 
 	} else if( !type || !strlen( type ) || !strcmp( type, NADP_VALUE_TYPE_ACTION )){
-		reader_type = NA_OBJECT_ACTION_TYPE;
+		item = NA_IFACTORY_OBJECT( na_object_action_new());
 
 	} else {
 		g_warning( "%s: unknown type=%s", thisfn, type );
 	}
 
-	if( reader_type ){
+	if( item ){
+		id = nadp_desktop_file_get_id( ndf );
+		na_object_set_id( item, id );
+		g_free( id );
 
 		reader_data = g_new0( NadpReaderData, 1 );
 		reader_data->ndf = ndf;
 
-		item = na_ifactory_provider_read_item( NA_IFACTORY_PROVIDER( provider ), reader_data, reader_type, messages );
+		na_ifactory_provider_read_item( NA_IFACTORY_PROVIDER( provider ), reader_data, item, messages );
 
-		if( item ){
-			id = nadp_desktop_file_get_id( ndf );
-			na_object_set_id( item, id );
-			g_free( id );
-			na_object_set_provider_data( item, ndf );
-			g_object_weak_ref( G_OBJECT( item ), ( GWeakNotify ) g_object_unref, ndf );
-		}
+		na_object_set_provider_data( item, ndf );
+		g_object_weak_ref( G_OBJECT( item ), ( GWeakNotify ) g_object_unref, ndf );
 
 		g_free( reader_data );
 	}
diff --git a/src/io-gconf/nagp-gconf-provider.c b/src/io-gconf/nagp-gconf-provider.c
index 091b802..4448c5a 100644
--- a/src/io-gconf/nagp-gconf-provider.c
+++ b/src/io-gconf/nagp-gconf-provider.c
@@ -242,10 +242,10 @@ ifactory_provider_iface_init( NAIFactoryProviderInterface *iface )
 
 	iface->get_version = ifactory_provider_get_version;
 	iface->read_start = NULL;
-	iface->read_value = NULL;
+	iface->read_data = NULL;
 	iface->read_done = NULL;
 	iface->write_start = NULL;
-	iface->write_value = NULL;
+	iface->write_data = NULL;
 	iface->write_done = NULL;
 }
 
diff --git a/src/io-xml/naxml-keys.h b/src/io-xml/naxml-keys.h
index f00000d..0cd0294 100644
--- a/src/io-xml/naxml-keys.h
+++ b/src/io-xml/naxml-keys.h
@@ -33,7 +33,7 @@
 
 #include <glib/gi18n.h>
 
-#include <api/na-ifactory-object-str.h>
+#include <api/na-data-def.h>
 
 G_BEGIN_DECLS
 
@@ -74,16 +74,6 @@ typedef struct {
 }
 	NAXMLKeyStr;
 
-/* this structure is allocated once for each element readen
- * and kept in a GList for interpretation in the second run
- */
-typedef struct {
-	gchar      *key_path;
-	gchar      *key_value;
-	NadfIdType *iddef;
-}
-	NAXMLElementStr;
-
 /* XML element names (GConf dump)
  * used in FORMAT_GCONF_ENTRY
  */
diff --git a/src/io-xml/naxml-provider.c b/src/io-xml/naxml-provider.c
index 5ae9c73..1664ddb 100644
--- a/src/io-xml/naxml-provider.c
+++ b/src/io-xml/naxml-provider.c
@@ -239,7 +239,7 @@ iimporter_iface_init( NAIImporterInterface *iface )
 	g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
 
 	iface->get_version = iimporter_get_version;
-	iface->import_uri = naxml_reader_import_uri;
+	iface->import_from_uri = naxml_reader_import_from_uri;
 }
 
 static guint
@@ -282,10 +282,10 @@ ifactory_provider_iface_init( NAIFactoryProviderInterface *iface )
 
 	iface->get_version = ifactory_provider_get_version;
 	iface->read_start = NULL;
-	iface->read_value = NULL;
-	iface->read_done = NULL;
+	iface->read_data = naxml_reader_read_data;
+	iface->read_done = naxml_reader_read_done;
 	iface->write_start = NULL;
-	iface->write_value = NULL;
+	iface->write_data = NULL;
 	iface->write_done = NULL;
 }
 
diff --git a/src/io-xml/naxml-reader.c b/src/io-xml/naxml-reader.c
index 36b0298..c87d256 100644
--- a/src/io-xml/naxml-reader.c
+++ b/src/io-xml/naxml-reader.c
@@ -51,46 +51,46 @@ struct NAXMLReaderClassPrivate {
 	void *empty;						/* so that gcc -pedantic is happy */
 };
 
+/* the association between a document root node key and the functions
+ */
+typedef struct {
+	gchar     *root_key;
+	gchar     *list_key;
+	gchar     *element_key;
+	guint   ( *fn_root_parms )     ( NAXMLReader *, xmlNode * );
+	guint   ( *fn_list_parms )     ( NAXMLReader *, xmlNode * );
+	guint   ( *fn_element_parms )  ( NAXMLReader *, xmlNode * );
+	guint   ( *fn_element_content )( NAXMLReader *, xmlNode * );
+	gchar * ( *fn_get_value )      ( NAXMLReader *, xmlNode *, const NADataDef *def );
+}
+	RootNodeStr;
+
 /* private instance data
- * main naxml_reader_import_uri() function is called once for each file
+ * main naxml_reader_import_from_uri() function is called once for each file
  * to import. We thus have one NAXMLReader object per import operation.
  */
 struct NAXMLReaderPrivate {
-	gboolean      dispose_has_run;
+	gboolean          dispose_has_run;
 
 	/* data provided by the caller
 	 */
-	const gchar  *uri;
-	gint          mode;
+	NAIImporter      *importer;
+	NAIImporterParms *parms;
 
 	/* data dynamically set during the import operation
 	 */
-	gchar        *xml_root;
-	NAObjectItem *item;
-	GSList       *messages;
 	gboolean      type_found;
-	GList        *elements;
+	GList        *nodes;
+	RootNodeStr  *root_node_str;
+	gchar        *item_id;
 
 	/* following values are reset and reused while iterating on each
-	 * element nodes of the imported item (cf. reset_element_data())
+	 * element nodes of the imported item (cf. reset_node_data())
 	 */
-	gboolean      ok;
-	gchar        *applyto_key;
-	gchar        *applyto_value;
-	NadfIdType   *iddef;
-
-	/* --- */
-
-	NAObjectProfile *profile;			/* profile */
-	gboolean         locale_waited;		/* does this require a locale ? */
-	gboolean         profile_waited;	/* does this entry apply to a profile ? */
-	gboolean         list_waited;
-	gchar           *entry;
-	gchar           *value;				/* found value */
-	GSList          *list_value;
+	gboolean      node_ok;
 };
 
-#define PATH_ID_IDX		4				/* index of item id in a GConf key path */
+#define SCHEMA_PATH_ID_IDX		4		/* index of item id in a GConf schema key path */
 
 extern NAXMLKeyStr naxml_schema_key_schema_str[];
 
@@ -102,38 +102,39 @@ static void          instance_init( GTypeInstance *instance, gpointer klass );
 static void          instance_dispose( GObject *object );
 static void          instance_finalize( GObject *object );
 
-/* the association of a document root node key and the functions
- */
-typedef struct {
-	gchar  *root_key;
-	gchar  *list_key;
-	gchar  *element_key;
-	void ( *fn_root_parms )     ( NAXMLReader *, xmlNode * );
-	void ( *fn_list_parms )     ( NAXMLReader *, xmlNode * );
-	void ( *fn_element_parms )  ( NAXMLReader *, xmlNode * );
-	void ( *fn_element_content )( NAXMLReader *, xmlNode * );
-}
-	RootNodeStr;
+static NAXMLReader  *reader_new( void );
 
-static void          reader_parse_schema_schema_content( NAXMLReader *reader, xmlNode *node );
-static void          reader_parse_dump_list_parms( NAXMLReader *reader, xmlNode *node );
-static void          reader_parse_dump_entry_content( NAXMLReader *reader, xmlNode *node );
+static guint         schema_parse_schema_content( NAXMLReader *reader, xmlNode *node );
+static void          schema_check_for_id( NAXMLReader *reader, xmlNode *iter );
+static void          schema_check_for_type( NAXMLReader *reader, xmlNode *iter );
+static gchar        *schema_get_value( xmlNode *node );
+static gchar        *schema_get_locale_value( xmlNode *node );
+static gchar        *schema_read_value( NAXMLReader *reader, xmlNode *node, const NADataDef *def );
+
+static guint         dump_parse_list_parms( NAXMLReader *reader, xmlNode *node );
+static guint         dump_parse_entry_content( NAXMLReader *reader, xmlNode *node );
+static gchar        *dump_read_value( NAXMLReader *reader, xmlNode *node, const NADataDef *def );
 
 static RootNodeStr st_root_node_str[] = {
+
 	{ NAXML_KEY_SCHEMA_ROOT,
 			NAXML_KEY_SCHEMA_LIST,
 			NAXML_KEY_SCHEMA_NODE,
 			NULL,
 			NULL,
 			NULL,
-			reader_parse_schema_schema_content },
+			schema_parse_schema_content,
+			schema_read_value },
+
 	{ NAXML_KEY_DUMP_ROOT,
 			NAXML_KEY_DUMP_LIST,
 			NAXML_KEY_DUMP_NODE,
 			NULL,
-			reader_parse_dump_list_parms,
+			dump_parse_list_parms,
 			NULL,
-			reader_parse_dump_entry_content },
+			dump_parse_entry_content,
+			dump_read_value },
+
 	{ NULL }
 };
 
@@ -183,43 +184,46 @@ static GConfReaderStruct reader_str[] = {
 #define ERR_NODE_UNKNOWN_TYPE		_( "Unknown type %s found at line %d, while waiting for Action or Menu." )
 #define ERR_PATH_LENGTH				_( "Too many elements in key path %s." )
 #define ERR_MENU_UNWAITED			_( "Unwaited key path %s while importing a menu." )
-#define ERR_ID_NOT_FOUND			_( "Item ID not found." )
-#define ERR_ITEM_LABEL_NOT_FOUND	_( "Item label not found." )
+#define ERR_ITEM_ID_NOT_FOUND		_( "Item ID not found." )
+#define ERR_NODE_INVALID_ID			_( "Invalid Item ID: waited for %s, found %s at line %d." )
 
 #if 0
+#define ERR_ITEM_LABEL_NOT_FOUND	_( "Item label not found." )
 #define ERR_IGNORED_SCHEMA			_( "Schema is ignored at line %d." )
 #define ERR_UNEXPECTED_NODE			_( "Unexpected '%s' node found at line %d." )
 #define ERR_UNEXPECTED_ENTRY		_( "Unexpected '%s' entry found at line %d." )
 #define ERR_NODE_NOT_FOUND			_( "Mandatory node '%s' not found." )
 #define ERR_NO_VALUE_FOUND			_( "No value found." )
-#define ERR_INVALID_UUID			_( "Invalid UUID: waited for %s, found %s at line %d." )
 #define ERR_INVALID_KEY_PREFIX		_( "Invalid content: waited for %s prefix, found %s at line %d." )
 #define ERR_NOT_AN_UUID				_( "Invalid UUID %s found at line %d." )
 #define ERR_UUID_ALREADY_EXISTS		_( "Already existing action (UUID: %s)." )
 #define ERR_VALUE_ALREADY_SET		_( "Value '%s' already set: new value ignored at line %d." )
 #endif
 
-static NAXMLReader  *reader_new( void );
+static void          factory_provider_read_done_action( NAXMLReader *reader, GSList **messages );
+
+static guint         reader_parse_xmldoc( NAXMLReader *reader );
+static guint         iter_on_root_children( NAXMLReader *reader, xmlNode *root );
+static guint         iter_on_list_children( NAXMLReader *reader, xmlNode *first );
 
-static void          reader_parse_xmldoc( NAXMLReader *reader );
 static void          add_message( NAXMLReader *reader, const gchar *format, ... );
-static gchar        *build_root_node_list( void );
 static gchar        *build_key_node_list( NAXMLKeyStr *strlist );
-static gchar        *get_default_value( xmlNode *node );
-static gchar        *get_locale_default_value( xmlNode *node );
-static void          iter_on_root_children( NAXMLReader *reader, xmlNode *root, RootNodeStr *str );
-static void          iter_on_list_children( NAXMLReader *reader, xmlNode *first, RootNodeStr *str );
-static void          iter_on_list_children_run( NAXMLReader *reader, xmlNode *list, RootNodeStr *str );
-static void          iter_on_elements_list( NAXMLReader *reader );
-static void          reset_element_data( NAXMLReader *reader );
-static void          reset_item_data( NAXMLReader *reader );
-static void          set_schema_applyto_value( NAXMLReader *reader, xmlNode *node, const gchar *entry );
-static void          free_naxml_element_str( NAXMLElementStr *str, void *data );
+static gchar        *build_root_node_list( void );
+static void          reset_node_data( NAXMLReader *reader );
 static xmlNode      *search_for_child_node( xmlNode *node, const gchar *key );
 static int           strxcmp( const xmlChar *a, const char *b );
 
 
 #if 0
+static void          iter_on_list_children_run( NAXMLReader *reader, xmlNode *list );
+static void          iter_on_elements_list( NAXMLReader *reader );
+#endif
+#if 0
+static void          set_schema_applyto_value( NAXMLReader *reader, xmlNode *node, const gchar *entry );
+#endif
+
+
+#if 0
 static void          reader_parse_schemalist( NAXMLReader *reader, xmlNode *schemalist );
 static gboolean      reader_parse_schema( NAXMLReader *reader, xmlNode *schema );
 static gboolean      reader_parse_applyto( NAXMLReader *reader, xmlNode *node );
@@ -241,7 +245,7 @@ static gboolean      is_uuid_valid( const gchar *uuid );
 static gchar        *get_entry_from_key( const gchar *key );
 
 #endif
-static gboolean      manage_import_mode( NAXMLReader *reader );
+static guint      manage_import_mode( NAXMLReader *reader );
 #if 0
 static void          propagate_default_values( NAXMLReader *reader );
 static NAObjectItem *search_in_auxiliaries( NAXMLReader *reader, const gchar *uuid );
@@ -315,19 +319,11 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self->private = g_new0( NAXMLReaderPrivate, 1 );
 
 	self->private->dispose_has_run = FALSE;
-	self->private->uri = NULL;
-	self->private->mode = 0;
-	self->private->item = NULL;
-	self->private->messages = NULL;
+	self->private->importer = NULL;
+	self->private->parms = NULL;
 	self->private->type_found = FALSE;
-	self->private->elements = NULL;
-
-	reset_item_data( self );
-
-	self->private->profile = NULL;
-	self->private->locale_waited = FALSE;
-	self->private->entry = NULL;
-	self->private->value = NULL;
+	self->private->nodes = NULL;
+	self->private->root_node_str = NULL;
 }
 
 static void
@@ -344,15 +340,7 @@ instance_dispose( GObject *object )
 
 		self->private->dispose_has_run = TRUE;
 
-		g_free( self->private->xml_root );
-
-		if( self->private->item ){
-			g_return_if_fail( NA_IS_OBJECT_ITEM( self->private->item ));
-			na_object_unref( self->private->item );
-		}
-
-		g_list_foreach( self->private->elements, ( GFunc ) free_naxml_element_str, NULL );
-		g_list_free( self->private->elements );
+		g_list_free( self->private->nodes );
 
 		/* chain up to the parent class */
 		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
@@ -371,7 +359,9 @@ instance_finalize( GObject *object )
 	g_return_if_fail( NAXML_IS_READER( object ));
 	self = NAXML_READER( object );
 
-	na_core_utils_slist_free( self->private->messages );
+	g_free( self->private->item_id );
+
+	reset_node_data( self );
 
 	g_free( self->private );
 
@@ -390,77 +380,63 @@ reader_new( void )
 /**
  * naxml_reader_import_uri:
  * @instance: the #NAIImporter provider.
- * @uri: the URI of the file to be imported.
- * @mode: the import mode.
- * @fn: a pointer to the function to be used to check for existancy of
- *  imported id.
- * @fn_data: data to be passed to @fn.
- * @messages: a pointer to a #GSList list of strings; the provider
- *  may append messages to this list, but shouldn't reinitialize it.
+ * @parms: a #NAIImporterParms structure.
  *
  * Imports an item.
  *
- * Returns: a #NAObjectItem-derived object, or %NULL if an error has
- * been detected.
+ * Returns: the import operation code.
  */
-NAObjectItem *
-naxml_reader_import_uri( const NAIImporter *instance, const gchar *uri, guint mode, ImporterCheckFn fn, void *fn_data, GSList **messages )
+guint
+naxml_reader_import_from_uri( const NAIImporter *instance, NAIImporterParms *parms )
 {
-	static const gchar *thisfn = "naxml_reader_import_uri";
-	NAObjectItem *item;
+	static const gchar *thisfn = "naxml_reader_import_from_uri";
 	NAXMLReader *reader;
-	GSList *im;
+	guint code;
 
-	g_debug( "%s: instance=%p, uri=%s, mode=%d, fn=%p, fn_data=%p, messages=%p",
-			thisfn, ( void * ) instance, uri, mode, ( void * ) fn, ( void * ) fn_data, ( void * ) messages );
+	g_debug( "%s: instance=%p, parms=%p", thisfn, ( void * ) instance, ( void * ) parms );
 
-	g_return_val_if_fail( NA_IS_IIMPORTER( instance ), NULL );
+	g_return_val_if_fail( NA_IS_IIMPORTER( instance ), IMPORTER_CODE_PROGRAM_ERROR );
 
 	reader = reader_new();
-	reader->private->uri = uri;
-	reader->private->mode = mode;
+	reader->private->importer = ( NAIImporter * ) instance;
+	reader->private->parms = parms;
 
-	reader_parse_xmldoc( reader );
+	parms->item = NULL;
 
-	item = NULL;
-	if( reader->private->item ){
-		g_assert( NA_IS_OBJECT_ITEM( reader->private->item ));
+	code = reader_parse_xmldoc( reader );
+
+	if( code == IMPORTER_CODE_OK ){
+		g_assert( NA_IS_OBJECT_ITEM( reader->private->parms->item ));
 #if 0
 		propagate_default_values( reader );
 #endif
-		if( manage_import_mode( reader )){
-			item = NA_OBJECT_ITEM( na_object_ref( reader->private->item ));
-		}
-	}
-
-	if( messages ){
-		for( im = reader->private->messages ; im ; im = im->next ){
-			*messages = g_slist_append( *messages, g_strdup(( const gchar * ) im->data ));
-		}
+		code = manage_import_mode( reader );
 	}
 
 	g_object_unref( reader );
 
-	return( item );
+	return( code );
 }
 
 /*
  * check that the file is a valid XML document
  * and that the root node can be identified as a schema or a dump
  */
-static void
+static guint
 reader_parse_xmldoc( NAXMLReader *reader )
 {
 	RootNodeStr *istr;
 	gboolean found;
+	guint code;
 
-	xmlDoc *doc = xmlParseFile( reader->private->uri );
+	xmlDoc *doc = xmlParseFile( reader->private->parms->uri );
 
 	if( !doc ){
 		xmlErrorPtr error = xmlGetLastError();
 		add_message( reader,
 				ERR_XMLDOC_UNABLE_TOPARSE, error->message );
 		xmlResetError( error );
+		code = IMPORTER_CODE_NOT_WILLING_TO;
 
 	} else {
 		xmlNode *root_node = xmlDocGetRootElement( doc );
@@ -468,10 +444,11 @@ reader_parse_xmldoc( NAXMLReader *reader )
 		istr = st_root_node_str;
 		found = FALSE;
 
-		while( istr->root_key ){
+		while( istr->root_key && !found ){
 			if( !strxcmp( root_node->name, istr->root_key )){
 				found = TRUE;
-				iter_on_root_children( reader, root_node, istr );
+				reader->private->root_node_str = istr;
+				code = iter_on_root_children( reader, root_node );
 			}
 			istr++;
 		}
@@ -482,119 +459,53 @@ reader_parse_xmldoc( NAXMLReader *reader )
 						ERR_ROOT_UNKNOWN,
 						( const char * ) root_node->name, root_node->line, node_list );
 			g_free( node_list );
+			code = IMPORTER_CODE_NOT_WILLING_TO;
 		}
 
 		xmlFreeDoc (doc);
 	}
 
 	xmlCleanupParser();
+	return( code );
 }
 
-static gchar *
-build_root_node_list( void )
-{
-	RootNodeStr *next;
-
-	RootNodeStr *istr = st_root_node_str;
-	GString *string = g_string_new( "" );
-
-	while( istr->root_key ){
-		next = istr+1;
-		if( string->len ){
-			if( next->root_key ){
-				string = g_string_append( string, ", " );
-			} else {
-				string = g_string_append( string, " or " );
-			}
-		}
-		string = g_string_append( string, istr->root_key );
-		istr++;
-	}
-
-	return( g_string_free( string, FALSE ));
-}
-
-#if 0
-/*
- * parse a XML schema
- * root = "gconfschemafile" (already tested)
- *  +- have one descendant node "schemalist"
- *  |   +- have one descendant node per key "schema"
- */
-static void
-reader_parse_schema_root( NAXMLReader *reader, xmlNode *root )
-{
-	static const gchar *thisfn = "naxml_reader_parse_schema_root";
-	xmlNodePtr iter;
-	gboolean found = FALSE;
-
-	g_debug( "%s: reader=%p, root=%p", thisfn, ( void * ) reader, ( void * ) root );
-
-	iter_on_tree_nodes(
-			reader, root,
-			NAXML_KEY_SCHEMA_LIST, NAXML_KEY_SCHEMA_ENTRY, reader_parse_schema_schema );
-
-	for( iter = root->children ; iter ; iter = iter->next ){
-
-		if( iter->type != XML_ELEMENT_NODE ){
-			continue;
-		}
-
-		if( strxcmp( iter->name, NAXML_KEY_SCHEMA_LIST )){
-			add_message( reader,
-					ERR_WAITED_IGNORED_NODE,
-					NAXML_KEY_SCHEMA_LIST, ( const char * ) iter->name, iter->line );
-			continue;
-		}
-
-		if( found ){
-			add_message( reader, ERR_IGNORED_NODE, ( const char * ) iter->name, iter->line );
-			continue;
-		}
-
-		found = TRUE;
-		reader_parse_schemalist( reader, iter );
-	}
-}
-#endif
-
 /*
  * parse a XML tree
  * - must have one child on the named 'first_child' key (others are warned)
  * - then iter on child nodes of this previous first named which must ne 'next_child'
  */
-static void
-iter_on_root_children( NAXMLReader *reader, xmlNode *root, RootNodeStr *str )
+static guint
+iter_on_root_children( NAXMLReader *reader, xmlNode *root )
 {
 	static const gchar *thisfn = "naxml_reader_iter_on_root_children";
 	xmlNodePtr iter;
 	gboolean found;
+	guint code;
 
-	g_debug( "%s: reader=%p, root=%p, str=%p",
-			thisfn, ( void * ) reader, ( void * ) root, ( void * ) str );
+	g_debug( "%s: reader=%p, root=%p", thisfn, ( void * ) reader, ( void * ) root );
 
-	reader->private->xml_root = g_strdup(( const gchar * ) root->name );
+	code = IMPORTER_CODE_OK;
 
 	/* deal with properties attached to the root node
 	 */
-	if( str->fn_root_parms ){
-		( *str->fn_root_parms )( reader, root );
+	if( reader->private->root_node_str->fn_root_parms ){
+		code = ( *reader->private->root_node_str->fn_root_parms )( reader, root );
 	}
 
 	/* iter through the first level of children (list)
 	 * we must have only one occurrence of this first 'list' child
 	 */
 	found = FALSE;
-	for( iter = root->children ; iter ; iter = iter->next ){
+	for( iter = root->children ; iter && code == IMPORTER_CODE_OK ; iter = iter->next ){
 
 		if( iter->type != XML_ELEMENT_NODE ){
 			continue;
 		}
 
-		if( strxcmp( iter->name, str->list_key )){
+		if( strxcmp( iter->name, reader->private->root_node_str->list_key )){
 			add_message( reader,
 					ERR_NODE_UNKNOWN,
-					( const char * ) iter->name, iter->line, str->list_key );
+					( const char * ) iter->name, iter->line, reader->private->root_node_str->list_key );
 			continue;
 		}
 
@@ -604,27 +515,29 @@ iter_on_root_children( NAXMLReader *reader, xmlNode *root, RootNodeStr *str )
 		}
 
 		found = TRUE;
-		iter_on_list_children( reader, iter, str );
+		code = iter_on_list_children( reader, iter );
 	}
+
+	return( code );
 }
 
 /*
- * iter on 'schema' element nodes
+ * iter on 'schema/entry' element nodes
  * each node should correspond to an elementary data of the imported item
  * other nodes are warned (and ignored)
  *
- * we have to iterate a first time through all schemas to be sure to find
+ * we have to iterate a first time through all nodes to be sure to find
  * a potential 'type' indication - this is needed in order to allocate an
  * action or a menu - if not found at the end of this first pass, we default
  * to allocate an action
  *
- * this first pass is also used to check schemas
+ * this first pass is also used to check nodes
  *
- * - for each schema, check that
- *   > 'schema' childs are in the list of known schema child nodes
- *   > 'schema' childs appear only once per schema
- *     -> this requires a per-node 'found' flag which is reset for each schema
- *   > has an 'applyto' child node
+ * - for each node, check that
+ *   > 'schema/entry' childs are in the list of known schema/entry child nodes
+ *   > 'schema/entry' childs appear only once per node
+ *     -> this requires a per-node 'found' flag which is reset for each node
+ *   > schema has an 'applyto' child node
  *     -> only checkable at the end of the schema
  *
  * - check that each data, identified by the 'applyto' value, appears only once
@@ -634,79 +547,104 @@ iter_on_root_children( NAXMLReader *reader, xmlNode *root, RootNodeStr *str )
  *      as the item may not be allocated yet, we cannot check that data
  *      is actually relevant with the to-be-imported item
  *
- * - search for type, and allocate the object
- *   default value (allocating an Action) is set between the two runs
- *
  * each schema 'applyto' node let us identify a data and its value
  */
-static void
-iter_on_list_children( NAXMLReader *reader, xmlNode *list, RootNodeStr *str )
+static guint
+iter_on_list_children( NAXMLReader *reader, xmlNode *list )
 {
 	static const gchar *thisfn = "naxml_reader_iter_on_list_children";
-	gboolean ok;
+	guint code;
+	xmlNode *iter;
 
-	g_debug( "%s: reader=%p, list=%p, str=%p",
-			thisfn, ( void * ) reader, ( void * ) list, ( void * ) str );
+	g_debug( "%s: reader=%p, list=%p", thisfn, ( void * ) reader, ( void * ) list );
+
+	code = IMPORTER_CODE_OK;
 
 	/* deal with properties attached to the list node
 	 */
-	if( str->fn_list_parms ){
-		( *str->fn_list_parms )( reader, list );
+	if( reader->private->root_node_str->fn_list_parms ){
+		code = ( *reader->private->root_node_str->fn_list_parms )( reader, list );
 	}
 
 	/* each occurrence should correspond to an elementary data
-	 * we run twice:
-	 * - first to determine the type, and allocate the object
-	 * - second (if ok), to actually read data
+	 * we run first to determine the type, and allocate the object
+	 * we then rely on NAIFactoryProvider to actually read the data
 	 */
-	ok = FALSE;
-	iter_on_list_children_run( reader, list, str );
+	for( iter = list->children ; iter && code == IMPORTER_CODE_OK ; iter = iter->next ){
 
-	/* if type not found, then suppose that we have an action
-	 */
-	if( !reader->private->type_found ){
-		reader->private->item = NA_OBJECT_ITEM( na_object_action_new());
-	}
+		if( iter->type != XML_ELEMENT_NODE ){
+			continue;
+		}
 
-	/* now load the data
-	 */
-	if( reader->private->item ){
+		if( strxcmp( iter->name, reader->private->root_node_str->element_key )){
+			add_message( reader,
+					ERR_NODE_UNKNOWN,
+					( const char * ) iter->name, iter->line, reader->private->root_node_str->element_key );
+			continue;
+		}
 
-		ok = TRUE;
-		iter_on_elements_list( reader );
+		reset_node_data( reader );
 
-		if( ok ){
-			gchar *id = na_object_get_id( reader->private->item );
-			if( !id || !strlen( id )){
-				ok = FALSE;
-				add_message( reader, ERR_ID_NOT_FOUND );
+		if( reader->private->root_node_str->fn_element_parms ){
+			code = ( *reader->private->root_node_str->fn_element_parms )( reader, iter );
+			if( code != IMPORTER_CODE_OK ){
+				continue;
 			}
-			g_free( id );
 		}
 
-		if( ok ){
-			gchar *label = na_object_get_label( reader->private->item );
-			if( !label || !g_utf8_strlen( label, -1 )){
-				ok = FALSE;
-				add_message( reader, ERR_ITEM_LABEL_NOT_FOUND );
+		if( reader->private->root_node_str->fn_element_content ){
+			code = ( *reader->private->root_node_str->fn_element_content )( reader, iter );
+			if( code != IMPORTER_CODE_OK ){
+				continue;
 			}
-			g_free( label );
 		}
 
-		if( !ok ){
-			g_object_unref( reader->private->item );
-			reader->private->item = NULL;
+		if( reader->private->node_ok ){
+			reader->private->nodes = g_list_prepend( reader->private->nodes, iter );
+		}
+	}
+
+	/* check that we have a not empty id
+	 */
+	if( code == IMPORTER_CODE_OK ){
+		if( !reader->private->item_id || !strlen( reader->private->item_id )){
+			add_message( reader, ERR_ITEM_ID_NOT_FOUND );
+			code = 	IMPORTER_CODE_NO_ITEM_ID;
 		}
 	}
+
+	/* if type not found, then suppose that we have an action
+	 */
+	if( code == IMPORTER_CODE_OK ){
+
+		if( !reader->private->type_found ){
+			reader->private->parms->item = NA_OBJECT_ITEM( na_object_action_new());
+		}
+
+		/* now load the data
+		 */
+		na_object_set_id( reader->private->parms->item, reader->private->item_id );
+
+		na_ifactory_provider_read_item(
+				NA_IFACTORY_PROVIDER( reader->private->importer ),
+				reader,
+				NA_IFACTORY_OBJECT( reader->private->parms->item ),
+				&reader->private->parms->messages );
+	}
+
+	return( code );
 }
 
+#if 0
 /*
  * iter on list child nodes
- * each 'schema' node should correspond to an elementary data of the imported item
- * other nodes are warned (and ignored)
+ * each 'schema/entry' node should correspond to an elementary data of
+ * the imported item - other nodes are warned (and ignored)
+ * invalid nodes are just ignored
+ * the id of the item must have been set during this run
  */
 static void
-iter_on_list_children_run( NAXMLReader *reader, xmlNode *list, RootNodeStr *str )
+iter_on_list_children_run( NAXMLReader *reader, xmlNode *list )
 {
 	xmlNode *iter;
 
@@ -716,38 +654,77 @@ iter_on_list_children_run( NAXMLReader *reader, xmlNode *list, RootNodeStr *str
 			continue;
 		}
 
-		if( strxcmp( iter->name, str->element_key )){
+		if( strxcmp( iter->name, reader->private->root_node_str->element_key )){
 			add_message( reader,
 					ERR_NODE_UNKNOWN,
-					( const char * ) iter->name, iter->line, str->element_key );
+					( const char * ) iter->name, iter->line, reader->private->root_node_str->element_key );
 			continue;
 		}
 
-		reset_element_data( reader );
-
-		if( str->fn_element_parms ){
-			( *str->fn_element_parms )( reader, iter );
-		}
+		reset_node_data( reader );
 
-		if( str->fn_element_content ){
-			( *str->fn_element_content )( reader, iter );
+		if( reader->private->root_node_str->fn_element_parms ){
+			( *reader->private->root_node_str->fn_element_parms )( reader, iter );
 		}
 
-		if( !reader->private->applyto_key || !reader->private->iddef ){
-			reader->private->ok = FALSE;
+		if( reader->private->root_node_str->fn_element_content ){
+			( *reader->private->root_node_str->fn_element_content )( reader, iter );
 		}
 
-		if( reader->private->ok ){
+		if( reader->private->node_ok ){
 
 			NAXMLElementStr *str = g_new0( NAXMLElementStr, 1 );
-			str->key_path = g_strdup( reader->private->applyto_key );
-			str->key_value = g_strdup( reader->private->applyto_value );
-			str->iddef = reader->private->iddef;
+			str->node = reader->private->node_ptr;
+			str->key = g_strdup( reader->private->node_key );
 			reader->private->elements = g_list_prepend( reader->private->elements, str );
 		}
 	}
 }
 
+/*
+ * parse a XML schema
+ * root = "gconfschemafile" (already tested)
+ *  +- have one descendant node "schemalist"
+ *  |   +- have one descendant node per key "schema"
+ */
+static void
+reader_parse_schema_root( NAXMLReader *reader, xmlNode *root )
+{
+	static const gchar *thisfn = "naxml_reader_parse_schema_root";
+	xmlNodePtr iter;
+	gboolean found = FALSE;
+
+	g_debug( "%s: reader=%p, root=%p", thisfn, ( void * ) reader, ( void * ) root );
+
+	iter_on_tree_nodes(
+			reader, root,
+			NAXML_KEY_SCHEMA_LIST, NAXML_KEY_SCHEMA_ENTRY, reader_parse_schema_schema );
+
+	for( iter = root->children ; iter ; iter = iter->next ){
+
+		if( iter->type != XML_ELEMENT_NODE ){
+			continue;
+		}
+
+		if( strxcmp( iter->name, NAXML_KEY_SCHEMA_LIST )){
+			add_message( reader,
+					ERR_WAITED_IGNORED_NODE,
+					NAXML_KEY_SCHEMA_LIST, ( const char * ) iter->name, iter->line );
+			continue;
+		}
+
+		if( found ){
+			add_message( reader, ERR_IGNORED_NODE, ( const char * ) iter->name, iter->line );
+			continue;
+		}
+
+		found = TRUE;
+		reader_parse_schemalist( reader, iter );
+	}
+}
+#endif
+
+#if 0
 static void
 iter_on_elements_list( NAXMLReader *reader )
 {
@@ -817,20 +794,107 @@ iter_on_elements_list( NAXMLReader *reader )
 		reader->private->item = NULL;
 	}
 }
+#endif
 
 /*
- * first run: only search for a 'Type' key, and allocate the item
- * this suppose that the entry 'key' is found _before_ the 'applyto' one
- * second run: load data
+ * this callback function is called by NAIFactoryObject once for each
+ * serializable data for the object
+ */
+NADataBoxed *
+naxml_reader_read_data( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, const NADataDef *def, GSList **messages )
+{
+	static const gchar *thisfn = "naxml_reader_read_data";
+	GList *ielt;
+
+	g_return_val_if_fail( NA_IS_IFACTORY_PROVIDER( provider ), NULL );
+	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
+
+	g_debug( "%s: data=%s", thisfn, def->name );
+
+	if( !def->gconf_entry || !strlen( def->gconf_entry )){
+		g_warning( "%s: GConf entry is not set for NADataDef %s", thisfn, def->name );
+		return( NULL );
+	}
+
+	gboolean found = FALSE;
+	NADataBoxed *boxed = NULL;
+	NAXMLReader *reader = NAXML_READER( reader_data );
+
+	for( ielt = reader->private->nodes ; ielt && !found ; ielt = ielt->next ){
+
+		xmlNode *schema = ( xmlNode * ) ielt->data;
+		xmlNode *applyto = search_for_child_node( schema, NAXML_KEY_SCHEMA_NODE_APPLYTO );
+
+		if( !applyto ){
+			g_warning( "%s: no 'applyto' node in schema at line %u", thisfn, schema->line );
+
+		} else {
+			xmlChar *text = xmlNodeGetContent( applyto );
+			gchar *entry = g_path_get_basename(( const gchar * ) text );
+
+			if( !strcmp( entry, def->gconf_entry )){
+				found = TRUE;
+
+				if( reader->private->root_node_str->fn_get_value ){
+					gchar *value = ( *reader->private->root_node_str->fn_get_value )( reader, schema, def );
+					boxed = na_data_boxed_new( def );
+					na_data_boxed_set_from_string( boxed, value );
+					g_free( value );
+				}
+			}
+
+			g_free( entry );
+			xmlFree( text );
+		}
+	}
+
+	return( boxed );
+}
+
+/*
+ * all serializable data of the object has been readen
  */
+void
+naxml_reader_read_done( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, GSList **messages  )
+{
+	static const gchar *thisfn = "naxml_reader_read_done";
+
+	g_return_if_fail( NA_IS_IFACTORY_PROVIDER( provider ));
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
+
+	g_debug( "%s: provider=%p, reader_data=%p, object=%p, messages=%p",
+			thisfn, ( void * ) provider, ( void * ) reader_data, ( void * ) object, ( void * ) messages );
+
+	if( NA_IS_OBJECT_ACTION( object )){
+		factory_provider_read_done_action( NAXML_READER( reader_data ), messages );
+	}
+}
+
 static void
-reader_parse_schema_schema_content( NAXMLReader *reader, xmlNode *schema )
+factory_provider_read_done_action( NAXMLReader *reader, GSList **messages )
+{
+	/* do we have a pre-v2 action ?
+	 */
+
+}
+/*
+ * 'key' and 'applyto' keys: check the id
+ * 'applyto' key: check for type
+ * returns set node_ok if:
+ * - each key appears is known and appears only once
+ * - there is an applyto key
+ */
+static guint
+schema_parse_schema_content( NAXMLReader *reader, xmlNode *schema )
 {
 	xmlNode *iter;
 	NAXMLKeyStr *str;
 	int i;
+	guint code;
 
-	for( iter = schema->children ; iter && reader->private->ok ; iter = iter->next ){
+	code = IMPORTER_CODE_OK;
+
+	for( iter = schema->children ; iter && code == IMPORTER_CODE_OK ; iter = iter->next ){
 
 		if( iter->type != XML_ELEMENT_NODE ){
 			continue;
@@ -843,77 +907,119 @@ reader_parse_schema_schema_content( NAXMLReader *reader, xmlNode *schema )
 			}
 		}
 
-		if( str ){
-			if( str->reader_found ){
-				add_message( reader,
-						ERR_NODE_ALREADY_FOUND,
-						( const char * ) iter->name, iter->line );
-				reader->private->ok = FALSE;
-
-			} else {
-				str->reader_found = TRUE;
+		if( !str ){
+			gchar *node_list = build_key_node_list( naxml_schema_key_schema_str );
+			add_message( reader,
+					ERR_NODE_UNKNOWN,
+					( const char * ) iter->name, iter->line, node_list );
+			g_free( node_list );
+			reader->private->node_ok = FALSE;
+			continue;
+		}
 
-				if( !strxcmp( iter->name, NAXML_KEY_SCHEMA_NODE_APPLYTO )){
-					xmlChar *text = xmlNodeGetContent( iter );
-					reader->private->applyto_key = g_strdup(( const gchar * ) text );
-					xmlFree( text );
+		if( str->reader_found ){
+			add_message( reader,
+					ERR_NODE_ALREADY_FOUND,
+					( const char * ) iter->name, iter->line );
+			reader->private->node_ok = FALSE;
+			continue;
+		}
 
-					gchar *entry = g_path_get_basename( reader->private->applyto_key );
+		str->reader_found = TRUE;
 
-					if( !strcmp( entry, NAGP_ENTRY_TYPE )){
-						reader->private->type_found = TRUE;
-						gchar *type = get_default_value( iter->parent );
+		/* set the item id the first time, check after
+		 */
+		if( !strxcmp( iter->name, NAXML_KEY_SCHEMA_NODE_KEY ) ||
+			!strxcmp( iter->name, NAXML_KEY_SCHEMA_NODE_APPLYTO )){
 
-						if( !strcmp( type, NAGP_VALUE_TYPE_ACTION )){
-							reader->private->item = NA_OBJECT_ITEM( na_object_action_new());
+			schema_check_for_id( reader, iter );
 
-						} else if( !strcmp( type, NAGP_VALUE_TYPE_MENU )){
-							reader->private->item = NA_OBJECT_ITEM( na_object_menu_new());
+			if( !reader->private->node_ok ){
+				continue;
+			}
+		}
 
-						} else {
-							add_message( reader, ERR_NODE_UNKNOWN_TYPE, type, iter->line );
-							reader->private->ok = FALSE;
-						}
-						g_free( type );
-					}
+		/* search for the type of the item
+		 */
+		if( !strxcmp( iter->name, NAXML_KEY_SCHEMA_NODE_APPLYTO )){
 
-					set_schema_applyto_value( reader, iter->parent, entry );
+			schema_check_for_type( reader, iter );
 
-					g_free( entry );
-				}
+			if( !reader->private->node_ok ){
+				continue;
 			}
+		}
+	}
 
-		} else {
-			gchar *node_list = build_key_node_list( naxml_schema_key_schema_str );
+	return( code );
+}
+
+/*
+ * check the id on 'key' and 'applyto' keys
+ */
+static void
+schema_check_for_id( NAXMLReader *reader, xmlNode *iter )
+{
+	guint idx = 1;
+
+	if( !strxcmp( iter->name, NAXML_KEY_SCHEMA_NODE_KEY )){
+		idx = 2;
+	}
+
+	xmlChar *text = xmlNodeGetContent( iter );
+	gchar **path_elts = g_strsplit(( const gchar * ) text, "/", -1 );
+	gchar *id = g_strdup( path_elts[ SCHEMA_PATH_ID_IDX+idx-1 ] );
+	g_strfreev( path_elts );
+	xmlFree( text );
+
+	if( reader->private->item_id ){
+		if( strcmp( reader->private->item_id, id ) != 0 ){
 			add_message( reader,
-					ERR_NODE_UNKNOWN,
-					( const char * ) iter->name, iter->line, node_list );
-			g_free( node_list );
-			reader->private->ok = FALSE;
+					ERR_NODE_INVALID_ID,
+					reader->private->item_id, id, iter->line );
+			reader->private->node_ok = FALSE;
 		}
+	} else {
+		reader->private->item_id = g_strdup( id );
 	}
+
+	g_free( id );
 }
 
+/*
+ * check 'applyto' key for 'Type'
+ */
 static void
-set_schema_applyto_value( NAXMLReader *reader, xmlNode *node, const gchar *entry )
+schema_check_for_type( NAXMLReader *reader, xmlNode *iter )
 {
-	gchar *value;
+	xmlChar *text = xmlNodeGetContent( iter );
+
+	gchar *entry = g_path_get_basename(( const gchar * ) text );
+
+	if( !strcmp( entry, NAGP_ENTRY_TYPE )){
+		reader->private->type_found = TRUE;
+		gchar *type = schema_get_value( iter->parent );
+
+		if( !strcmp( type, NAGP_VALUE_TYPE_ACTION )){
+			reader->private->parms->item = NA_OBJECT_ITEM( na_object_action_new());
+
+		} else if( !strcmp( type, NAGP_VALUE_TYPE_MENU )){
+			reader->private->parms->item = NA_OBJECT_ITEM( na_object_menu_new());
 
-	NadfIdType *iddef = na_ifactory_provider_get_idtype_from_gconf_key( entry );
-	if( iddef ){
-		reader->private->iddef = iddef;
-		g_debug( "%s: localizable=%s", iddef->name, iddef->localizable ? "True":"False" );
-		if( iddef->localizable ){
-			value = get_locale_default_value( node );
 		} else {
-			value = get_default_value( node );
+			add_message( reader, ERR_NODE_UNKNOWN_TYPE, type, iter->line );
+			reader->private->node_ok = FALSE;
 		}
-		reader->private->applyto_value = value;
+
+		g_free( type );
 	}
+
+	g_free( entry );
+	xmlFree( text );
 }
 
 static gchar *
-get_default_value( xmlNode *node )
+schema_get_value( xmlNode *node )
 {
 	gchar *value = NULL;
 
@@ -930,7 +1036,7 @@ get_default_value( xmlNode *node )
 }
 
 static gchar *
-get_locale_default_value( xmlNode *node )
+schema_get_locale_value( xmlNode *node )
 {
 	gchar *value = NULL;
 
@@ -949,63 +1055,52 @@ get_locale_default_value( xmlNode *node )
 	return( value );
 }
 
-static xmlNode *
-search_for_child_node( xmlNode *node, const gchar *key )
-{
-	xmlNode *iter;
-
-	for( iter = node->children ; iter ; iter = iter->next ){
-		if( iter->type == XML_ELEMENT_NODE ){
-			if( !strxcmp( iter->name, key )){
-				return( iter );
-			}
-		}
-	}
-
-	return( NULL );
-}
-
 static gchar *
-build_key_node_list( NAXMLKeyStr *strlist )
+schema_read_value( NAXMLReader *reader, xmlNode *node, const NADataDef *def )
 {
-	NAXMLKeyStr *next;
-
-	NAXMLKeyStr *istr = strlist;
-	GString *string = g_string_new( "" );
+	gchar *value;
 
-	while( istr->key ){
-		next = istr+1;
-		if( string->len ){
-			if( next->key ){
-				string = g_string_append( string, ", " );
-			} else {
-				string = g_string_append( string, " or " );
-			}
-		}
-		string = g_string_append( string, istr->key );
-		istr++;
+	if( def->localizable ){
+		value = schema_get_locale_value( node );
+	} else {
+		value = schema_get_value( node );
 	}
 
-	return( g_string_free( string, FALSE ));
+	return( value );
 }
 
 /*
  * first run: do nothing
  * second run: get the id
  */
-static void
-reader_parse_dump_list_parms( NAXMLReader *reader, xmlNode *node )
+static guint
+dump_parse_list_parms( NAXMLReader *reader, xmlNode *node )
 {
+	guint code;
+
+	code = IMPORTER_CODE_OK;
 
+	return( code );
 }
 
 /*
  * first_run: only search for a 'Type' key, and allocate the item
  * second run: load data
  */
-static void
-reader_parse_dump_entry_content( NAXMLReader *reader, xmlNode *node )
+static guint
+dump_parse_entry_content( NAXMLReader *reader, xmlNode *node )
 {
+	guint code;
+
+	code = IMPORTER_CODE_OK;
+
+	return( code );
+}
+
+static gchar *
+dump_read_value( NAXMLReader *reader, xmlNode *node, const NADataDef *def )
+{
+	return( NULL );
 }
 
 #if 0
@@ -1820,12 +1915,111 @@ add_message( NAXMLReader *reader, const gchar *format, ... )
 	va_list va;
 	gchar *tmp;
 
-	g_debug( "naxml_reader_add_message: format=%s", format );
-
 	va_start( va, format );
 	tmp = g_markup_vprintf_escaped( format, va );
 	va_end( va );
-	reader->private->messages = g_slist_append( reader->private->messages, tmp );
+
+	reader->private->parms->messages = g_slist_append( reader->private->parms->messages, tmp );
+}
+
+static gchar *
+build_key_node_list( NAXMLKeyStr *strlist )
+{
+	NAXMLKeyStr *next;
+
+	NAXMLKeyStr *istr = strlist;
+	GString *string = g_string_new( "" );
+
+	while( istr->key ){
+		next = istr+1;
+		if( string->len ){
+			if( next->key ){
+				string = g_string_append( string, ", " );
+			} else {
+				string = g_string_append( string, " or " );
+			}
+		}
+		string = g_string_append( string, istr->key );
+		istr++;
+	}
+
+	return( g_string_free( string, FALSE ));
+}
+
+static gchar *
+build_root_node_list( void )
+{
+	RootNodeStr *next;
+
+	RootNodeStr *istr = st_root_node_str;
+	GString *string = g_string_new( "" );
+
+	while( istr->root_key ){
+		next = istr+1;
+		if( string->len ){
+			if( next->root_key ){
+				string = g_string_append( string, ", " );
+			} else {
+				string = g_string_append( string, " or " );
+			}
+		}
+		string = g_string_append( string, istr->root_key );
+		istr++;
+	}
+
+	return( g_string_free( string, FALSE ));
+}
+
+#if 0
+static void
+free_naxml_element_str( NAXMLElementStr *str, void *data )
+{
+	g_free( str->key );
+	g_free( str );
+}
+#endif
+
+/*
+ * data are reset before first run on nodes for an item
+ */
+static void
+reset_node_data( NAXMLReader *reader )
+{
+	int i;
+
+	for( i=0 ; naxml_schema_key_schema_str[i].key ; ++i ){
+		naxml_schema_key_schema_str[i].reader_found = FALSE;
+	}
+
+	reader->private->node_ok = TRUE;
+}
+
+#if 0
+/*
+ * reset here static data which should be reset before each object
+ * (so, obviously, not reader data as a new reader is reallocated
+ *  for each import operation)
+ */
+static void
+reset_item_data( NAXMLReader *reader )
+{
+}
+#endif
+
+static xmlNode *
+search_for_child_node( xmlNode *node, const gchar *key )
+{
+	xmlNode *iter;
+
+	for( iter = node->children ; iter ; iter = iter->next ){
+		if( iter->type == XML_ELEMENT_NODE ){
+			if( !strxcmp( iter->name, key )){
+				return( iter );
+			}
+		}
+	}
+
+	return( NULL );
 }
 
 /*
@@ -1887,53 +2081,12 @@ get_entry_from_key( const gchar *key )
 #endif
 
 /*
- * data are reset before first run on nodes for an item
- */
-static void
-reset_element_data( NAXMLReader *reader )
-{
-	int i;
-
-	for( i=0 ; naxml_schema_key_schema_str[i].key ; ++i ){
-		naxml_schema_key_schema_str[i].reader_found = FALSE;
-	}
-
-	reader->private->ok = TRUE;
-
-	g_free( reader->private->applyto_key );
-	reader->private->applyto_key = NULL;
-
-	g_free( reader->private->applyto_value );
-	reader->private->applyto_value = NULL;
-
-	reader->private->iddef = NULL;
-}
-
-/*
- * reset here static data which should be reset before each object
- * (so, obviously, not reader data as a new reader is reallocated
- *  for each import operation)
- */
-static void
-reset_item_data( NAXMLReader *reader )
-{
-}
-
-static void
-free_naxml_element_str( NAXMLElementStr *str, void *data )
-{
-	g_free( str->key_path );
-	g_free( str->key_value );
-	g_free( str );
-}
-
-/*
- * returns TRUE if we can safely insert the action
+ * returns IMPORTER_CODE_OK if we can safely insert the action
  * - the id doesn't already exist
  * - the id already exist, but import mode is renumber
  * - the id already exists, but import mode is override
  */
-static gboolean
+static guint
 manage_import_mode( NAXMLReader *reader )
 {
 #if 0
@@ -1993,7 +2146,7 @@ manage_import_mode( NAXMLReader *reader )
 	g_free( uuid );
 	return( ret );
 #endif
-	return( TRUE );
+	return( IMPORTER_CODE_OK );
 }
 
 #if 0
diff --git a/src/io-xml/naxml-reader.h b/src/io-xml/naxml-reader.h
index 657ad39..0072a9b 100644
--- a/src/io-xml/naxml-reader.h
+++ b/src/io-xml/naxml-reader.h
@@ -37,10 +37,16 @@
  * @include: naxml-reader.h
  *
  * This is the base class for importing items from XML files.
+ *
+ * If the imported file is not an XML one, with a known document root,
+ * then we returned IMPORTER_CODE_NOT_WILLING_TO.
+ * In all other cases, errors or inconsistancies are signaled, but
+ * we do our best to actually import the file and produce a valuable
+ * #NAObjectItem-derived object.
  */
 
+#include <api/na-data-boxed.h>
 #include <api/na-iimporter.h>
-#include <api/na-object-item.h>
 
 G_BEGIN_DECLS
 
@@ -67,9 +73,13 @@ typedef struct {
 }
 	NAXMLReaderClass;
 
-GType         naxml_reader_get_type( void );
+GType        naxml_reader_get_type( void );
+
+guint        naxml_reader_import_from_uri( const NAIImporter *instance, NAIImporterParms *parms );
+
+NADataBoxed *naxml_reader_read_data( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, const NADataDef *def, GSList **messages );
 
-NAObjectItem *naxml_reader_import_uri( const NAIImporter *instance, const gchar *uri, guint mode, ImporterCheckFn fn, void *fn_data, GSList **messages );
+void         naxml_reader_read_done( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, GSList **messages  );
 
 G_END_DECLS
 
diff --git a/src/nact/nact-assistant-import.c b/src/nact/nact-assistant-import.c
index 7a739d1..f97e48e 100644
--- a/src/nact/nact-assistant-import.c
+++ b/src/nact/nact-assistant-import.c
@@ -650,14 +650,15 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
 	static const gchar *thisfn = "nact_assistant_import_assistant_apply";
 	NactAssistantImport *window;
 	GtkWidget *chooser;
-	GSList *uris, *is, *msg;
-	NAObjectItem *item;
+	GSList *uris, *is;
 	ImportUriStruct *str;
 	GList *items;
 	BaseWindow *mainwnd;
-	gint mode;
+	guint mode;
 	NactApplication *application;
 	NAUpdater *updater;
+	NAIImporterParms parms;
+	guint code;
 
 	g_debug( "%s: window=%p, assistant=%p", thisfn, ( void * ) wnd, ( void * ) assistant );
 	g_assert( NACT_IS_ASSISTANT_IMPORT( wnd ));
@@ -679,14 +680,20 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
 	items = NULL;
 	for( is = uris ; is ; is = is->next ){
 
-		msg = NULL;
-		item = na_importer_import( NA_PIVOT( updater ), ( const gchar * ) is->data, mode, NULL, NULL, &msg );
+		parms.version = 1;
+		parms.uri = ( gchar * ) is->data;
+		parms.mode = mode;
+		parms.messages = NULL;
+		parms.item = NULL;
+		parms.fn = NULL;
+		parms.fn_data = NULL;
+
+		code = na_importer_import_from_uri( NA_PIVOT( updater ), &parms );
 
 		str = g_new0( ImportUriStruct, 1 );
-		str->uri = g_strdup(( const gchar * ) is->data );
-		str->item = item;
-		str->msg = na_core_utils_slist_duplicate( msg );
-		na_core_utils_slist_free( msg );
+		str->uri = g_strdup( parms.uri );
+		str->item = parms.item;
+		str->msg = parms.messages;
 
 		if( str->item ){
 			na_object_check_status( str->item );
diff --git a/src/nact/nact-tree-model-dnd.c b/src/nact/nact-tree-model-dnd.c
index de6e0be..558f05b 100644
--- a/src/nact/nact-tree-model-dnd.c
+++ b/src/nact/nact-tree-model-dnd.c
@@ -746,14 +746,15 @@ drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selec
 {
 	/*static const gchar *thisfn = "nact_tree_model_drop_uri_list";*/
 	gboolean drop_done = FALSE;
-	GSList *uri_list, *is, *msg;
+	GSList *uri_list, *is;
 	NactApplication *application;
 	NAUpdater *updater;
 	gint import_mode;
-	NAObjectItem *item;
 	NactMainWindow *main_window;
 	GtkTreePath *new_dest;
 	GList *object_list;
+	NAIImporterParms parms;
+	guint code;
 
 	application = NACT_APPLICATION( base_window_get_application( model->private->window ));
 	updater = nact_application_get_updater( application );
@@ -771,28 +772,30 @@ drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selec
 
 	for( is = uri_list ; is ; is = is->next ){
 
-		item = na_importer_import(
-				NA_PIVOT( updater ),
-				( const gchar * ) is->data,
-				import_mode,
-				NULL,
-				NULL,
-				&msg );
+		parms.version = 1;
+		parms.uri = ( gchar * ) is->data;
+		parms.mode = import_mode;
+		parms.messages = NULL;
+		parms.item = NULL;
+		parms.fn = NULL;
+		parms.fn_data = NULL;
 
-		if( msg ){
+		code = na_importer_import_from_uri( NA_PIVOT( updater ), &parms );
+
+		if( parms.messages ){
 			main_window = NACT_MAIN_WINDOW( base_application_get_main_window( BASE_APPLICATION( application )));
 			nact_main_statusbar_display_with_timeout(
 					main_window,
 					TREE_MODEL_STATUSBAR_CONTEXT,
-					msg->data );
-			na_core_utils_slist_free( msg );
+					parms.messages->data );
+			na_core_utils_slist_free( parms.messages );
 		}
 
-		if( item ){
-			g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), FALSE );
-			object_list = g_list_prepend( object_list, item );
-			na_object_check_status( item );
-			na_object_dump( item );
+		if( parms.item ){
+			g_return_val_if_fail( NA_IS_OBJECT_ITEM( parms.item ), FALSE );
+			object_list = g_list_prepend( object_list, parms.item );
+			na_object_check_status( parms.item );
+			na_object_dump( parms.item );
 			drop_done = TRUE;
 		}
 	}
diff --git a/src/test/test-include.c b/src/test/test-include.c
index 9c62f2a..1831a55 100644
--- a/src/test/test-include.c
+++ b/src/test/test-include.c
@@ -1,6 +1,6 @@
 #include <stdio.h>
 
-#include <api/na-ifactory-object.h>
+#include <api/na-iimporter.h>
 
 int
 main()
diff --git a/src/test/test-reader.c b/src/test/test-reader.c
index 381bf5e..d4463b6 100755
--- a/src/test/test-reader.c
+++ b/src/test/test-reader.c
@@ -28,24 +28,151 @@
  *   ... and many others (see AUTHORS)
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include <stdlib.h>
+
 #include <api/na-core-utils.h>
 
 #include <core/na-pivot.h>
 #include <core/na-importer.h>
 
+static gchar     *uri     = "";
+static gboolean   version = FALSE;
+
+static GOptionEntry entries[] = {
+
+	{ "uri"                  , 'u', 0, G_OPTION_ARG_STRING        , &uri,
+			N_( "The URI of the file to be imported" ), N_( "<URI>" ) },
+	{ NULL }
+};
+
+static GOptionEntry misc_entries[] = {
+
+	{ "version"              , 'v', 0, G_OPTION_ARG_NONE        , &version,
+			N_( "Output the version number" ), NULL },
+	{ NULL }
+};
+
+static GOptionContext  *init_options( void );
+static void             check_options( int argc, char **argv, GOptionContext *context );
+static void             exit_with_usage( void );
+
 int
 main( int argc, char **argv )
 {
+	NAIImporterParms parms;
+
 	g_type_init();
 
+	GOptionContext *context = init_options();
+	check_options( argc, argv, context );
+
 	NAPivot *pivot = na_pivot_new();
-	GSList *msg = NULL;
-	gchar *uri = "file:///net/pierre/eclipse/nautilus-actions/exports/config_0af5a47e-96d9-441c-a3b8-d1185ced0351.schemas";
-	NAObjectItem *item = na_importer_import( pivot, uri, IMPORTER_MODE_ASK, NULL, NULL, &msg );
-	if( item ){
-		na_object_dump( item );
-		g_object_unref( item );
+
+	parms.version = 1;
+	parms.uri = uri;
+	parms.mode = IMPORTER_MODE_ASK;
+	parms.item = NULL;
+	parms.fn = NULL;
+	parms.fn_data = NULL;
+	parms.messages = NULL;
+
+	guint code = na_importer_import_from_uri( pivot, &parms );
+
+	g_print( "%s: return code from import is %u.\n", g_get_prgname(), code );
+
+	if( parms.item ){
+		na_object_dump( parms.item );
+		g_object_unref( parms.item );
 	}
-	na_core_utils_slist_dump( msg );
+
+	na_core_utils_slist_dump( parms.messages );
+	na_core_utils_slist_free( parms.messages );
+
 	return( 0 );
 }
+
+static GOptionContext *
+init_options( void )
+{
+	GOptionContext *context;
+	gchar* description;
+	GOptionGroup *misc_group;
+
+	context = g_option_context_new( _( "Import a file." ));
+
+#ifdef ENABLE_NLS
+	bindtextdomain( GETTEXT_PACKAGE, GNOMELOCALEDIR );
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+	bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
+# endif
+	textdomain( GETTEXT_PACKAGE );
+	g_option_context_add_main_entries( context, entries, GETTEXT_PACKAGE );
+#else
+	g_option_context_add_main_entries( context, entries, NULL );
+#endif
+
+	description = g_strdup_printf( "%s.\n%s", PACKAGE_STRING,
+			_( "Bug reports are welcomed at http://bugzilla.gnome.org,";
+				" or you may prefer to mail to <maintainer nautilus-actions org>.\n" ));
+
+	g_option_context_set_description( context, description );
+
+	g_free( description );
+
+	misc_group = g_option_group_new(
+			"misc", _( "Miscellaneous options" ), _( "Miscellaneous options" ), NULL, NULL );
+	g_option_group_add_entries( misc_group, misc_entries );
+	g_option_context_add_group( context, misc_group );
+
+	return( context );
+}
+
+static void
+check_options( int argc, char **argv, GOptionContext *context )
+{
+	GError *error = NULL;
+
+	if( argc == 1 ){
+		g_set_prgname( argv[0] );
+		gchar *help = g_option_context_get_help( context, FALSE, NULL );
+		g_print( "\n%s", help );
+		g_free( help );
+		exit( EXIT_SUCCESS );
+	}
+
+	if( !g_option_context_parse( context, &argc, &argv, &error )){
+		g_printerr( _( "Syntax error: %s\n" ), error->message );
+		g_error_free (error);
+		exit_with_usage();
+	}
+
+	g_option_context_free( context );
+
+	if( version ){
+		na_core_utils_print_version();
+		exit( EXIT_SUCCESS );
+	}
+
+	gint errors = 0;
+
+	if( !uri || !strlen( uri )){
+		g_printerr( _( "Error: uri is mandatory.\n" ));
+		errors += 1;
+	}
+
+	if( errors ){
+		exit_with_usage();
+	}
+}
+
+static void
+exit_with_usage( void )
+{
+	g_printerr( _( "Try %s --help for usage.\n" ), g_get_prgname());
+	exit( EXIT_FAILURE );
+}



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