[nautilus-actions] Create a whole new object model, and defines some communication interfaces



commit a995e7c85fe6474871d215db6b92b2d42abb6cc1
Author: Pierre Wieser <pwieser trychlos org>
Date:   Fri Jun 5 14:27:07 2009 +0200

    Create a whole new object model, and defines some communication interfaces
    
    NactAction and NactActionProfile are object themselves.
    NactIIOProvider is a communication interface with various storage subsystems.
    NactIIOClient is a helper interface for objects which implement NactIIOProvider.
---
 ChangeLog                        |   13 +-
 src/common/Makefile.am           |   12 +-
 src/common/nact-action-profile.c |  142 ++++++---
 src/common/nact-action-profile.h |   14 +-
 src/common/nact-action.c         |  226 ++++++++------
 src/common/nact-action.h         |   37 ++-
 src/common/nact-gconf-keys.h     |    2 +-
 src/common/nact-gconf.c          |  642 +++++++++++++++++++++++++++-----------
 src/common/nact-gconf.h          |   35 ++-
 src/common/nact-iio-client.c     |  154 +++++++++
 src/common/nact-iio-client.h     |   73 +++++
 src/common/nact-iio-provider.c   |  239 ++++++++++++++
 src/common/nact-iio-provider.h   |   83 +++++
 src/common/nact-io-client.c      |  245 +++++++++++++++
 src/common/nact-io-client.h      |   78 +++++
 src/common/nact-object.c         |  165 ++++++++++
 src/common/nact-object.h         |   80 +++++
 src/common/nact-pivot.c          |  214 +++++++++++++
 src/common/nact-pivot.h          |   78 +++++
 src/common/nact-storage.c        |  326 -------------------
 src/common/nact-storage.h        |  102 ------
 src/plugin/nautilus-actions.c    |  188 ++++++------
 src/plugin/nautilus-module.c     |    3 +
 23 files changed, 2283 insertions(+), 868 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1a2b536..f477b03 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2009-06-02 Pierre Wieser <pwieser trychlos org>
 
+	Create a whole new object model, and defines some communication
+	interfaces.
+
 	* src/plugin/nautilus-actions.c:
 	* src/plugin/nautilus-actions.h:
 	Connect and load list of NactAction actions.
@@ -19,10 +22,16 @@
 	* src/common/nact-action-profile.h:
 	* src/common/nact-gconf.c:
 	* src/common/nact-gconf.h:
-	* src/common/nact-storage.c:
-	* src/common/nact-storage.h:
 	Updated accordingly.
 
+	* src/common/nact-iio-client.c:
+	* src/common/nact-iio-client.h:
+	* src/common/nact-iio-provider.c:
+	* src/common/nact-iio-provider.c:
+	* src/common/nact-io-client.c:
+	* src/common/nact-io-client.h:
+	New files.
+
 2009-06-01 Pierre Wieser <pwieser trychlos org>
 
 	* configure.ac: Have a more funny package string.
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index a47375c..83b1804 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -42,8 +42,16 @@ libnact_la_SOURCES = \
 	nact-gconf.c								\
 	nact-gconf.h								\
 	nact-gconf-keys.h							\
-	nact-storage.c								\
-	nact-storage.h								\
+	nact-iio-client.c							\
+	nact-iio-client.h							\
+	nact-iio-provider.c							\
+	nact-iio-provider.h							\
+	nact-io-client.c							\
+	nact-io-client.h							\
+	nact-object.c								\
+	nact-object.h								\
+	nact-pivot.c								\
+	nact-pivot.h								\
 	nautilus-actions-config.c					\
 	nautilus-actions-config.h					\
 	nautilus-actions-config-gconf.c				\
diff --git a/src/common/nact-action-profile.c b/src/common/nact-action-profile.c
index d60193d..a895997 100644
--- a/src/common/nact-action-profile.c
+++ b/src/common/nact-action-profile.c
@@ -31,39 +31,15 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-#include <libnautilus-extension/nautilus-file-info.h>
-#include <string.h>
-#include "nact-action-profile.h"
-#include "uti-lists.h"
 
-static NactStorageClass *st_parent_class = NULL;
+#include <string.h>
 
-static GType  register_type( void );
-static void   class_init( NactActionProfileClass *klass );
-static void   instance_init( GTypeInstance *instance, gpointer klass );
-static void   instance_dispose( GObject *object );
-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_finalize( GObject *object );
-static gchar *get_id( const NactStorage *profile );
-static void   do_dump( const NactStorage *profile );
-static void   do_dump_list( const gchar *thisfn, const gchar *label, GSList *list );
-static int    validate_schemes( GSList* schemes2test, NautilusFileInfo* file );
+#include <libnautilus-extension/nautilus-file-info.h>
 
-enum {
-	PROP_ACTION = 1,
-	PROP_PROFILE_NAME,
-	PROP_LABEL,
-	PROP_PATH,
-	PROP_PARAMETERS,
-	PROP_ACCEPT_MULTIPLE,
-	PROP_BASENAMES,
-	PROP_ISDIR,
-	PROP_ISFILE,
-	PROP_MATCHCASE,
-	PROP_MIMETYPES,
-	PROP_SCHEMES
-};
+#include "nact-action-profile.h"
+#include "nact-iio-client.h"
+#include "nact-iio-provider.h"
+#include "uti-lists.h"
 
 struct NactActionProfilePrivate {
 	gboolean  dispose_has_run;
@@ -74,7 +50,7 @@ struct NactActionProfilePrivate {
 
 	/* profile properties
 	 */
-	gchar    *name;
+	gchar    *name;		/* GConf key = id */
 	gchar    *label;
 	gchar    *path;
 	gchar    *parameters;
@@ -90,6 +66,35 @@ struct NactActionProfilePrivate {
 struct NactActionProfileClassPrivate {
 };
 
+enum {
+	PROP_ACTION = 1,
+	PROP_PROFILE_NAME,
+	PROP_LABEL,
+	PROP_PATH,
+	PROP_PARAMETERS,
+	PROP_ACCEPT_MULTIPLE,
+	PROP_BASENAMES,
+	PROP_ISDIR,
+	PROP_ISFILE,
+	PROP_MATCHCASE,
+	PROP_MIMETYPES,
+	PROP_SCHEMES
+};
+
+static NactObjectClass *st_parent_class = NULL;
+
+static GType register_type( void );
+static void  class_init( NactActionProfileClass *klass );
+static void  instance_init( GTypeInstance *instance, gpointer klass );
+static void  instance_dispose( GObject *object );
+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_finalize( GObject *object );
+
+static void  do_dump( const NactObject *profile );
+static void  do_dump_list( const gchar *thisfn, const gchar *label, GSList *list );
+static int   validate_schemes( GSList* schemes2test, NautilusFileInfo* file );
+
 GType
 nact_action_profile_get_type( void )
 {
@@ -117,7 +122,7 @@ register_type( void )
 		( GInstanceInitFunc ) instance_init
 	};
 
-	return( g_type_register_static( NACT_STORAGE_TYPE, "NactActionProfile", &info, 0 ));
+	return( g_type_register_static( NACT_OBJECT_TYPE, "NactActionProfile", &info, 0 ));
 }
 
 static void
@@ -222,8 +227,7 @@ class_init( NactActionProfileClass *klass )
 
 	klass->private = g_new0( NactActionProfileClassPrivate, 1 );
 
-	NACT_STORAGE_CLASS( klass )->get_id = get_id;
-	NACT_STORAGE_CLASS( klass )->do_dump = do_dump;
+	NACT_OBJECT_CLASS( klass )->dump = do_dump;
 }
 
 static void
@@ -412,9 +416,9 @@ instance_finalize( GObject *object )
 }
 
 NactActionProfile *
-nact_action_profile_new( const NactStorage *action, const gchar *name )
+nact_action_profile_new( const NactObject *action, const gchar *name )
 {
-	g_assert( NACT_IS_STORAGE( action ));
+	g_assert( NACT_IS_OBJECT( action ));
 	g_assert( name && strlen( name ));
 
 	NactActionProfile *profile =
@@ -422,25 +426,31 @@ nact_action_profile_new( const NactStorage *action, const gchar *name )
 	return( profile );
 }
 
-static gchar *
-get_id( const NactStorage *profile )
+/**
+ * Load an action.
+ *
+ * @action: a NactAction previously allocated via nact_action_new.
+ */
+void
+nact_action_profile_load( NactObject *object )
 {
-	g_assert( NACT_IS_ACTION_PROFILE( profile ));
-	gchar *id;
-	g_object_get( G_OBJECT( profile ), "name", &id, NULL );
-	return( id );
+	g_assert( NACT_IS_ACTION_PROFILE( object ));
+
+	/*NactActionProfile *profile = NACT_ACTION_PROFILE( object );*/
+
+	nact_iio_provider_load_profile_properties( object );
 }
 
 static void
-do_dump( const NactStorage *object )
+do_dump( const NactObject *object )
 {
 	static const gchar *thisfn = "nact_action_profile_do_dump";
 
 	g_assert( NACT_IS_ACTION_PROFILE( object ));
 	NactActionProfile *self = NACT_ACTION_PROFILE( object );
 
-	if( st_parent_class->do_dump ){
-		st_parent_class->do_dump( object );
+	if( st_parent_class->dump ){
+		st_parent_class->dump( object );
 	}
 
 	g_debug( "%s:         profile_name='%s'", thisfn, self->private->name );
@@ -473,6 +483,43 @@ do_dump_list( const gchar *thisfn, const gchar *label, GSList *list )
 	g_string_free( str, TRUE );
 }
 
+/**
+ * Returns a pointer to the action for this profile.
+ */
+NactObject *
+nact_action_profile_get_action( const NactActionProfile *profile )
+{
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+
+	gpointer action;
+	g_object_get( G_OBJECT( profile ), "action", &action, NULL );
+
+	return( NACT_OBJECT( action ));
+}
+
+/**
+ * Returns the profile name.
+ *
+ * The returned string should be g_freed by the caller.
+ *
+ * The profile name is also the GConf-key of the profile.
+ */
+gchar *
+nact_action_profile_get_id( const NactActionProfile *profile )
+{
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+
+	gchar *id;
+	g_object_get( G_OBJECT( profile ), "name", &id, NULL );
+
+	return( id );
+}
+
+/**
+ * Returns the path of the command in the profile.
+ *
+ * The returned string should be g_freed by the caller.
+ */
 gchar *
 nact_action_profile_get_path( const NactActionProfile *profile )
 {
@@ -484,6 +531,11 @@ nact_action_profile_get_path( const NactActionProfile *profile )
 	return( path );
 }
 
+/**
+ * Returns the parameters of the command in the profile.
+ *
+ * The returned string should be g_freed by the caller.
+ */
 gchar *
 nact_action_profile_get_parameters( const NactActionProfile *profile )
 {
diff --git a/src/common/nact-action-profile.h b/src/common/nact-action-profile.h
index 672866c..3a3529f 100644
--- a/src/common/nact-action-profile.h
+++ b/src/common/nact-action-profile.h
@@ -38,10 +38,10 @@
  * definition of an action.
  *
  * As NactAction itself, NactActionProfile class is derived from
- * NactStorage which takes care of i/o.
+ * NactObject which takes care of i/o.
  */
 
-#include "nact-storage.h"
+#include "nact-object.h"
 
 G_BEGIN_DECLS
 
@@ -55,7 +55,7 @@ G_BEGIN_DECLS
 typedef struct NactActionProfilePrivate NactActionProfilePrivate;
 
 typedef struct {
-	NactStorage               parent;
+	NactObject                parent;
 	NactActionProfilePrivate *private;
 }
 	NactActionProfile;
@@ -63,15 +63,19 @@ typedef struct {
 typedef struct NactActionProfileClassPrivate NactActionProfileClassPrivate;
 
 typedef struct {
-	NactStorageClass               parent;
+	NactObjectClass                parent;
 	NactActionProfileClassPrivate *private;
 }
 	NactActionProfileClass;
 
 GType              nact_action_profile_get_type( void );
 
-NactActionProfile *nact_action_profile_new( const NactStorage *action, const gchar *name );
+NactActionProfile *nact_action_profile_new( const NactObject *action, const gchar *name );
 
+void               nact_action_profile_load( NactObject *profile );
+
+NactObject        *nact_action_profile_get_action( const NactActionProfile *profile );
+gchar             *nact_action_profile_get_id( const NactActionProfile *profile );
 gchar             *nact_action_profile_get_path( const NactActionProfile *profile );
 gchar             *nact_action_profile_get_parameters( const NactActionProfile *profile );
 
diff --git a/src/common/nact-action.c b/src/common/nact-action.c
index 455fc80..63f022a 100644
--- a/src/common/nact-action.c
+++ b/src/common/nact-action.c
@@ -31,37 +31,25 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
 #include <string.h>
+
 #include "nact-action.h"
 #include "nact-action-profile.h"
+#include "nact-iio-client.h"
+#include "nact-iio-provider.h"
+#include "nact-io-client.h"
 #include "uti-lists.h"
 
-static NactStorageClass *st_parent_class = NULL;
-
-static GType       register_type( void );
-static void        class_init( NactActionClass *klass );
-static void        instance_init( GTypeInstance *instance, gpointer klass );
-static void        instance_dispose( GObject *object );
-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_finalize( GObject *object );
-static gchar      *get_id( const NactStorage *action );
-static void        do_dump( const NactStorage *action );
-
-enum {
-	PROP_UUID = 1,
-	PROP_VERSION,
-	PROP_LABEL,
-	PROP_TOOLTIP,
-	PROP_ICON
-};
-
 struct NactActionPrivate {
 	gboolean  dispose_has_run;
 
+	/* io client
+	 */
+	NactIOClient *io;
+
 	/* action properties
 	 */
-	gchar    *uuid;
 	gchar    *version;
 	gchar    *label;
 	gchar    *tooltip;
@@ -76,6 +64,48 @@ struct NactActionPrivate {
 struct NactActionClassPrivate {
 };
 
+enum {
+	PROP_VERSION = 1,
+	PROP_LABEL,
+	PROP_TOOLTIP,
+	PROP_ICON
+};
+
+static NactObjectClass *st_parent_class = NULL;
+
+static GType    register_type( void );
+static void     class_init( NactActionClass *klass );
+static void     iio_client_iface_init( NactIIOClientInterface *iface );
+static void     instance_init( GTypeInstance *instance, gpointer klass );
+static void     instance_dispose( GObject *object );
+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_finalize( GObject *object );
+
+static void     free_profiles( NactAction *action );
+
+static GObject *do_get_io_client( const NactIIOClient *client );
+static void     do_dump( const NactObject *action );
+
+/**
+ * Allocate a new NactAction object.
+ *
+ * @provider: a gpointer to the instance which implements the storage
+ * subsystem for this action ; the @provider must implement the
+ * NactIIOProvider interface.
+ *
+ * @data: a gpointer to some data internal to the provider ; the
+ * provider may use it to store and retrieve its data on a per-object
+ * basis.
+ */
+NactAction *
+nact_action_new( gpointer provider, gpointer data )
+{
+	NactAction *action = g_object_new( NACT_ACTION_TYPE, NULL );
+	action->private->io = nact_io_client_new( provider, data );
+	return( action );
+}
+
 GType
 nact_action_get_type( void )
 {
@@ -103,7 +133,17 @@ register_type( void )
 		( GInstanceInitFunc ) instance_init
 	};
 
-	return( g_type_register_static( NACT_STORAGE_TYPE, "NactAction", &info, 0 ));
+	GType type = g_type_register_static( NACT_OBJECT_TYPE, "NactAction", &info, 0 );
+
+	static const GInterfaceInfo iio_client_iface_info = {
+		( GInterfaceInitFunc ) iio_client_iface_init,
+		NULL,
+		NULL
+	};
+
+	g_type_add_interface_static( type, NACT_IIO_CLIENT_TYPE, &iio_client_iface_info );
+
+	return( type );
 }
 
 static void
@@ -124,13 +164,6 @@ class_init( NactActionClass *klass )
 
 	/* the id of the object is marked as G_PARAM_CONSTRUCT_ONLY */
 	spec = g_param_spec_string(
-			"uuid",
-			"uuid",
-			"Globally unique identifier of the action", "",
-			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_UUID, spec );
-
-	spec = g_param_spec_string(
 			"version",
 			"version",
 			"Version of the schema", "",
@@ -160,8 +193,16 @@ class_init( NactActionClass *klass )
 
 	klass->private = g_new0( NactActionClassPrivate, 1 );
 
-	NACT_STORAGE_CLASS( klass )->get_id = get_id;
-	NACT_STORAGE_CLASS( klass )->do_dump = do_dump;
+	NACT_OBJECT_CLASS( klass )->dump = do_dump;
+}
+
+static void
+iio_client_iface_init( NactIIOClientInterface *iface )
+{
+	static const gchar *thisfn = "nact_action_iio_client_iface_init";
+	g_debug( "%s: iface=%p", thisfn, iface );
+
+	iface->get_io_client = do_get_io_client;
 }
 
 static void
@@ -184,10 +225,6 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 	NactAction *self = NACT_ACTION( object );
 
 	switch( property_id ){
-		case PROP_UUID:
-			g_value_set_string( value, self->private->uuid );
-			break;
-
 		case PROP_VERSION:
 			g_value_set_string( value, self->private->version );
 			break;
@@ -217,11 +254,6 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 	NactAction *self = NACT_ACTION( object );
 
 	switch( property_id ){
-		case PROP_UUID:
-			g_free( self->private->uuid );
-			self->private->uuid = g_value_dup_string( value );
-			break;
-
 		case PROP_VERSION:
 			g_free( self->private->version );
 			self->private->version = g_value_dup_string( value );
@@ -261,10 +293,14 @@ instance_dispose( GObject *object )
 
 		self->private->dispose_has_run = TRUE;
 
-		GSList *item;
-		for( item = self->private->profiles ; item != NULL ; item = item->next ){
-			g_object_unref( NACT_ACTION_PROFILE( item->data ));
-		}
+		/* release the io_client object */
+		g_object_unref( self->private->io );
+
+		/* release the profiles */
+		free_profiles( self );
+
+		/* release the provider data */
+		nact_iio_provider_release_data( NACT_IIO_CLIENT( self ));
 
 		/* chain up to the parent class */
 		G_OBJECT_CLASS( st_parent_class )->dispose( object );
@@ -280,7 +316,6 @@ instance_finalize( GObject *object )
 	g_assert( NACT_IS_ACTION( object ));
 	NactAction *self = ( NactAction * ) object;
 
-	g_free( self->private->uuid );
 	g_free( self->private->version );
 	g_free( self->private->label );
 	g_free( self->private->tooltip );
@@ -292,28 +327,58 @@ instance_finalize( GObject *object )
 	}
 }
 
-static gchar *
-get_id( const NactStorage *action )
+static void
+free_profiles( NactAction *action )
+{
+	g_assert( NACT_IS_ACTION( action ));
+
+	GSList *ip;
+	for( ip = action->private->profiles ; ip ; ip = ip->next ){
+		g_object_unref( NACT_ACTION_PROFILE( ip->data ));
+	}
+	g_slist_free( action->private->profiles );
+	action->private->profiles = NULL;
+}
+
+static GObject *
+do_get_io_client( const NactIIOClient *client )
+{
+	g_assert( NACT_IS_IIO_CLIENT( client ));
+	g_assert( NACT_IS_ACTION( client ));
+	NactAction *action = NACT_ACTION( client );
+	return( G_OBJECT( action->private->io ));
+}
+
+/**
+ * Load an action.
+ *
+ * @action: a NactAction previously allocated via nact_action_new.
+ */
+void
+nact_action_load( NactAction *action )
 {
 	g_assert( NACT_IS_ACTION( action ));
-	gchar *id;
-	g_object_get( G_OBJECT( action ), "uuid", &id, NULL );
-	return( id );
+	g_assert( NACT_IS_IIO_CLIENT( action ));
+
+	nact_iio_provider_load_action_properties( NACT_IIO_CLIENT( action ));
+
+	action->private->profiles = nact_iio_provider_load_profiles( NACT_IIO_CLIENT( action ));
+
+	nact_object_dump( NACT_OBJECT( action ));
 }
 
 static void
-do_dump( const NactStorage *action )
+do_dump( const NactObject *action )
 {
 	static const gchar *thisfn = "nact_action_do_dump";
 
 	g_assert( NACT_IS_ACTION( action ));
 	NactAction *self = NACT_ACTION( action );
 
-	if( st_parent_class->do_dump ){
-		st_parent_class->do_dump( action );
+	if( st_parent_class->dump ){
+		st_parent_class->dump( action );
 	}
 
-	g_debug( "%s:    uuid='%s'", thisfn, self->private->uuid );
 	g_debug( "%s: version='%s'", thisfn, self->private->version );
 	g_debug( "%s:   label='%s'", thisfn, self->private->label );
 	g_debug( "%s: tooltip='%s'", thisfn, self->private->tooltip );
@@ -323,43 +388,8 @@ do_dump( const NactStorage *action )
 	g_debug( "%s: %d profile(s) at %p", thisfn, nact_action_get_profiles_count( self ), self->private->profiles );
 	GSList *item;
 	for( item = self->private->profiles ;	item != NULL ; item = item->next ){
-		nact_storage_dump(( const NactStorage * ) item->data );
-	}
-}
-
-/**
- * Allocate and return the list of defined actions.
- *
- * Delegate to NactStorage how to search for locations of actions. The
- * class will ask for this to each registered storage subsystem (GConf
- * only for now).
- *
- * NactStorage concatenates received lists and return the result as a
- * list of pre-initialized NactStorage (actually NactAction) objects,
- * each of them being able to address its own location.
- */
-GSList *
-nact_action_load_actions( void )
-{
-	static gchar *thisfn = "nact_action_load_actions";
-	g_debug( "%s", thisfn );
-
-	/* we read a first list which contains the list of actions
-	 * as NactStorage-initialized objects
-	 */
-	GSList *actions = nact_storage_load_actions( NACT_ACTION_TYPE );
-
-	GSList *item;
-	for( item = actions ; item != NULL ; item = item->next ){
-
-		NactAction *obj = ( NactAction * ) item->data;
-		obj->private->profiles =
-				nact_storage_load_profiles(( NactStorage * ) obj, NACT_ACTION_PROFILE_TYPE );
-
-		nact_storage_dump( NACT_STORAGE( item->data ));
+		nact_object_dump(( const NactObject * ) item->data );
 	}
-
-	return( actions );
 }
 
 /**
@@ -462,6 +492,18 @@ nact_action_get_profiles( const NactAction *action )
 	return( action->private->profiles );
 }
 
+/**
+ * Set the list of the profiles for the action.
+ */
+void
+nact_action_set_profiles( NactAction *action, GSList *list )
+{
+	g_assert( NACT_IS_ACTION( action ));
+
+	free_profiles( action );
+	action->private->profiles = list;
+}
+
 guint
 nact_action_get_profiles_count( const NactAction *action )
 {
@@ -495,7 +537,7 @@ nact_action_free_profile_ids( GSList *list )
 	nactuti_free_string_list( list );
 }
 
-NactActionProfile*
+NactObject*
 nact_action_get_profile( const NactAction *action, const gchar *profile_name )
 {
 	g_assert( NACT_IS_ACTION( action ));
@@ -514,5 +556,5 @@ nact_action_get_profile( const NactAction *action, const gchar *profile_name )
 		}
 		g_free( name );
 	}
-	return( found );
+	return( NACT_OBJECT( found ));
 }
diff --git a/src/common/nact-action.h b/src/common/nact-action.h
index 4e54bb9..827de03 100644
--- a/src/common/nact-action.h
+++ b/src/common/nact-action.h
@@ -36,13 +36,10 @@
  *
  * This is the class which maintains an action.
  *
- * Note that an action is globally identified by its uuid.
- *
- * NactAction class is derived from NactStorage which takes care of i/o.
+ * NactAction class is derived from NactObject.
  */
 
-#include "nact-storage.h"
-#include "nact-action-profile.h"
+#include "nact-object.h"
 
 G_BEGIN_DECLS
 
@@ -56,7 +53,7 @@ G_BEGIN_DECLS
 typedef struct NactActionPrivate NactActionPrivate;
 
 typedef struct {
-	NactStorage        parent;
+	NactObject         parent;
 	NactActionPrivate *private;
 }
 	NactAction;
@@ -64,26 +61,30 @@ typedef struct {
 typedef struct NactActionClassPrivate NactActionClassPrivate;
 
 typedef struct {
-	NactStorageClass        parent;
+	NactObjectClass         parent;
 	NactActionClassPrivate *private;
 }
 	NactActionClass;
 
-GType   nact_action_get_type( void );
+GType       nact_action_get_type( void );
+
+NactAction *nact_action_new( gpointer provider, gpointer data );
+
+void        nact_action_load( NactAction *action );
 
-GSList *nact_action_load_actions( void );
+gchar      *nact_action_get_uuid( const NactAction *action );
+gchar      *nact_action_get_label( const NactAction *action );
+gchar      *nact_action_get_tooltip( const NactAction *action );
+gchar      *nact_action_get_verified_icon_name( const NactAction *action );
 
-gchar  *nact_action_get_uuid( const NactAction *action );
-gchar  *nact_action_get_label( const NactAction *action );
-gchar  *nact_action_get_tooltip( const NactAction *action );
-gchar  *nact_action_get_verified_icon_name( const NactAction *action );
+GSList     *nact_action_get_profiles( const NactAction *action );
+void        nact_action_set_profiles( NactAction *action, GSList *list );
 
-GSList *nact_action_get_profiles( const NactAction *action );
-guint   nact_action_get_profiles_count( const NactAction *action );
-GSList *nact_action_get_profile_ids( const NactAction *action );
-void    nact_action_free_profile_ids( GSList *list );
+guint       nact_action_get_profiles_count( const NactAction *action );
+GSList     *nact_action_get_profile_ids( const NactAction *action );
+void        nact_action_free_profile_ids( GSList *list );
 
-NactActionProfile *nact_action_get_profile( const NactAction *action, const gchar *name );
+NactObject *nact_action_get_profile( const NactAction *action, const gchar *name );
 
 G_END_DECLS
 
diff --git a/src/common/nact-gconf-keys.h b/src/common/nact-gconf-keys.h
index 5acdc9a..365c95b 100644
--- a/src/common/nact-gconf-keys.h
+++ b/src/common/nact-gconf-keys.h
@@ -32,6 +32,6 @@
 #define __NACT_GCONF_KEYS_H__
 
 /* GConf general information */
-#define NACT_GCONF_CONFIG		NAUTILUS_ACTIONS_CONFIG_GCONF_BASEDIR "/configurations"
+#define NACT_GCONF_CONFIG_PATH		NAUTILUS_ACTIONS_CONFIG_GCONF_BASEDIR "/configurations"
 
 #endif /* __NACT_GCONF_KEYS_H__ */
diff --git a/src/common/nact-gconf.c b/src/common/nact-gconf.c
index c9ee56f..b66b5f8 100644
--- a/src/common/nact-gconf.c
+++ b/src/common/nact-gconf.c
@@ -31,101 +31,386 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
+#include <string.h>
+
 #include <gconf/gconf.h>
 #include <gconf/gconf-client.h>
-#include <string.h>
+
+#include "nact-action.h"
+#include "nact-action-profile.h"
 #include "nact-gconf.h"
 #include "nact-gconf-keys.h"
+#include "nact-iio-client.h"
+#include "nact-iio-provider.h"
+#include "nact-pivot.h"
 #include "uti-lists.h"
 
+struct NactGConfPrivate {
+	gboolean     dispose_has_run;
+	NactPivot   *pivot;
+	GConfClient *gconf;
+	guint        notify_id;
+};
+
+struct NactGConfClassPrivate {
+};
+
 typedef struct {
 	gchar *key;
 	gchar *path;
 }
 	NactGConfIO;
 
-static GConfClient *st_gconf = NULL;
-
-static void         free_keys_values( GSList *list );
-static void         initialize( void );
-static void         load_action_properties( NactStorage *action );
-static GSList      *load_items( const gchar *root, GType type );
-static GSList      *load_keys_values( const gchar *path );
-static GSList      *load_list_actions( GType type );
-static GSList      *load_list_profiles( NactStorage *action, GType type );
-static void         load_profile_properties( NactStorage *profile );
-static GSList      *load_subdirs( const gchar *path );
+enum {
+	PROP_PIVOT = 1
+};
+
+static GObjectClass *st_parent_class = NULL;
+
+static GType        register_type( void );
+static void         class_init( NactGConfClass *klass );
+static void         iio_provider_iface_init( NactIIOProviderInterface *iface );
+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 guint        install_gconf_watch( NactGConf *gconf );
+static void         remove_gconf_watch( NactGConf *gconf );
+
+static void         actions_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data );
+
+static void         free_keys_values( GSList *keys );
+static GSList      *load_keys_values( const NactGConf *gconf, const gchar *path );
+static GSList      *load_subdirs( const NactGConf *gconf, const gchar *path );
 static gchar       *path_to_key( const gchar *path );
 static NactGConfIO *path_to_struct( const gchar *path );
+static void         set_item_properties( NactObject *object, GSList *properties );
+
+static GSList      *do_load_actions( NactIIOProvider *provider );
+static void         do_load_action_properties( NactIIOClient *client );
+static GSList      *do_load_profiles( NactIIOClient *client );
+static void         do_load_profile_properties( NactObject *profile );
+static void         do_release_data( NactIIOClient *client );
+
+NactGConf *
+nact_gconf_new( const GObject *pivot )
+{
+	g_assert( NACT_IS_PIVOT( pivot ));
+	return( g_object_new( NACT_GCONF_TYPE, "pivot", pivot, NULL ));
+}
+
+GType
+nact_gconf_get_type( void )
+{
+	static GType object_type = 0;
+
+	if( !object_type ){
+		object_type = register_type();
+	}
+
+	return( object_type );
+}
+
+static GType
+register_type( void )
+{
+	static GTypeInfo info = {
+		sizeof( NactGConfClass ),
+		NULL,
+		NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( NactGConf ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	GType type = g_type_register_static( G_TYPE_OBJECT, "NactGConf", &info, 0 );
+
+	static const GInterfaceInfo iio_provider_iface_info = {
+		( GInterfaceInitFunc ) iio_provider_iface_init,
+		NULL,
+		NULL
+	};
+
+	g_type_add_interface_static( type, NACT_IIO_PROVIDER_TYPE, &iio_provider_iface_info );
+
+	return( type );
+}
 
 static void
-free_keys_values( GSList *list )
+class_init( NactGConfClass *klass )
 {
-	GSList *item;
-	for( item = list ; item != NULL ; item = item->next ){
-		GConfEntry *entry = ( GConfEntry * ) item->data;
-		gconf_entry_unref( entry );
+	static const gchar *thisfn = "nact_gconf_class_init";
+	g_debug( "%s: klass=%p", thisfn, klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	GObjectClass *object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
+	object_class->set_property = instance_set_property;
+	object_class->get_property = instance_get_property;
+
+	GParamSpec *spec;
+	spec = g_param_spec_pointer(
+			"pivot",
+			"pivot",
+			"A pointer to NactPivot object",
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_PIVOT, spec );
+
+	klass->private = g_new0( NactGConfClassPrivate, 1 );
+}
+
+static void
+iio_provider_iface_init( NactIIOProviderInterface *iface )
+{
+	static const gchar *thisfn = "nact_gconf_iio_provider_iface_init";
+	g_debug( "%s: iface=%p", thisfn, iface );
+
+	iface->load_actions = do_load_actions;
+	iface->load_action_properties = do_load_action_properties;
+	iface->load_profiles = do_load_profiles;
+	iface->load_profile_properties = do_load_profile_properties;
+	iface->release_data = do_release_data;
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+	static const gchar *thisfn = "nact_gconf_instance_init";
+	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );
+
+	g_assert( NACT_IS_GCONF( instance ));
+	NactGConf *self = NACT_GCONF( instance );
+
+	self->private = g_new0( NactGConfPrivate, 1 );
+
+	self->private->dispose_has_run = FALSE;
+	self->private->gconf = gconf_client_get_default();
+	self->private->notify_id = install_gconf_watch( self );
+}
+
+static void
+instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
+{
+	g_assert( NACT_IS_GCONF( object ));
+	NactGConf *self = NACT_GCONF( object );
+
+	switch( property_id ){
+		case PROP_PIVOT:
+			g_value_set_pointer( value, self->private->pivot );
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+			break;
 	}
-	g_slist_free( list );
 }
 
-/*
- * we have to initialize this early in the process as nautilus-actions
- * will try to load actions before even any NactAction has been created
- */
 static void
-initialize( void )
+instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
 {
-	static const gchar *thisfn = "nact_gconf_initialize";
-	g_debug( "%s", thisfn );
+	g_assert( NACT_IS_GCONF( object ));
+	NactGConf *self = NACT_GCONF( object );
+
+	switch( property_id ){
+		case PROP_PIVOT:
+			self->private->pivot = g_value_get_pointer( value );
+			break;
 
-	st_gconf = gconf_client_get_default();
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+			break;
+	}
 }
 
-/*
- * allocate the whole list of items under the specified dir.
- * each item of the list is a NactStorage-derived initialized GObject
- */
-static GSList *
-load_items( const gchar *root, GType type )
+static void
+instance_dispose( GObject *object )
 {
-	GSList *items = NULL;
+	g_assert( NACT_IS_GCONF( object ));
+	NactGConf *self = NACT_GCONF( object );
 
-	GSList *listpath = load_subdirs( root );
-	GSList *path;
-	for( path = listpath ; path != NULL ; path = path->next ){
+	if( !self->private->dispose_has_run ){
 
-		NactGConfIO *io = path_to_struct(( const gchar * ) path->data );
+		self->private->dispose_has_run = TRUE;
 
-		GObject *object = g_object_new(
-				type, PROP_ORIGIN_STR, ORIGIN_GCONF, PROP_SUBSYSTEM_STR, io, NULL  );
+		/* release the GConf connexion */
+		remove_gconf_watch( self );
+		g_object_unref( self->private->gconf );
 
-		items = g_slist_prepend( items, object );
+		/* chain up to the parent class */
+		G_OBJECT_CLASS( st_parent_class )->dispose( object );
 	}
-	nactuti_free_string_list( listpath );
+}
 
-	return( items );
+static void
+instance_finalize( GObject *object )
+{
+	g_assert( NACT_IS_GCONF( object ));
+	/*NactGConf *self = NACT_GCONF( object );*/
+
+	/* chain call to parent class */
+	if( st_parent_class->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( object );
+	}
+}
+
+static guint
+install_gconf_watch( NactGConf *gconf )
+{
+	static const gchar *thisfn = "install_gconf_watch";
+	GError *error = NULL;
+
+	gconf_client_add_dir(
+			gconf->private->gconf, NACT_GCONF_CONFIG_PATH, GCONF_CLIENT_PRELOAD_RECURSIVE, &error );
+	if( error ){
+		g_error( "%s: error=%s", thisfn, error->message );
+		g_error_free( error );
+		return( 0 );
+	}
+
+	guint notify_id =
+		gconf_client_notify_add(
+			gconf->private->gconf,
+			NACT_GCONF_CONFIG_PATH,
+			( GConfClientNotifyFunc ) actions_changed_cb,
+			gconf,
+			NULL,
+			&error
+		);
+	if( error ){
+		g_error( "%s: error=%s", thisfn, error->message );
+		g_error_free( error );
+		return( 0 );
+	}
+
+	return( notify_id );
+}
+
+static void
+remove_gconf_watch( NactGConf *gconf )
+{
+	static const gchar *thisfn = "remove_gconf_watch";
+	GError *error = NULL;
+
+	if( gconf->private->notify_id ){
+		gconf_client_notify_remove( gconf->private->gconf, gconf->private->notify_id );
+	}
+
+	gconf_client_remove_dir( gconf->private->gconf, NACT_GCONF_CONFIG_PATH, &error );
+	if( error ){
+		g_error( "%s: error=%s", thisfn, error->message );
+		g_error_free( error );
+	}
+}
+
+/*
+ * this callback is triggered each time a value is changed under our
+ * actions directory
+ *
+ * if the modification is made from nautilus-actions-config ui, then
+ * the callback is triggered several times (one time for each rewritten
+ * property) as action/profile are edited as blocs of data ; in this
+ * case, the ui takes care (aso of 1.10) of also writing at last a
+ * particular key of the form xxx:yyyyyyyy-yyyy-yyyy-..., where :
+ *    xxx is a sequential number (inside of the ui session)
+ *    yyyyyyyy-yyyy-yyyy-... is the uuid of the involved action
+ *
+ * this is so a sort of hack which simplifies a lot the notification
+ * system (take the new action, replace it in the current global list)
+ * but doesn't work if the modification is made from outside of the ui
+ *
+ * if the modification is made elsewhere (an action is imported as a
+ * xml file in gconf, of gconf is directly edited), we'd have to rely
+ * on the key of the value
+ */
+static void
+actions_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data )
+{
+	static const gchar *thisfn = "actions_changed_cb";
+	g_debug( "%s: client=%p, cnxnid=%u, entry=%p, user_data=%p", thisfn, client, cnxn_id, entry, user_data );
+
+	/*NactGConf *gconf = NACT_GCONF( user_data );*/
+
+	/* The Key value format is XXX:YYYY-YYYY-... where XXX is an number incremented to make key
+	 * effectively changed each time and YYYY-YYYY-... is the modified uuid */
+	const GConfValue* value = gconf_entry_get_value (entry);
+	const gchar* notify_value = gconf_value_get_string (value);
+	const gchar *key = gconf_entry_get_key( entry );
+	g_debug( "%s: notify_value='%s', key='%s'", thisfn, notify_value, key );
+	/*const gchar* uuid = notify_value + 4;*/
+
+	/* Get the modified action from the internal list if any */
+	/*NautilusActionsConfigAction *old_action = nautilus_actions_config_get_action (config, uuid);*/
+
+	/* Get the new version from GConf if any */
+	/*NautilusActionsConfigAction *new_action = nautilus_actions_config_gconf_get_action (NAUTILUS_ACTIONS_CONFIG_GCONF (config), uuid);*/
+
+	/* If modified action is unknown internally */
+	/*if (old_action == NULL)
+	{
+		if (new_action != NULL)
+		{*/
+			/* new action */
+			/*nautilus_actions_config_add_action (config, new_action, NULL);
+		}
+		else
+		{*/
+			/* This case should not happen */
+			/*g_assert_not_reached ();
+		}
+	}
+	else
+	{
+		if (new_action != NULL)
+		{*/
+			/* action modified */
+			/*nautilus_actions_config_update_action (config, new_action);
+		}
+		else
+		{*/
+			/* action removed */
+			/*nautilus_actions_config_remove_action (config, uuid);
+		}
+	}*/
+
+	/* Add & change handler duplicate actions before adding them,
+	 * so we can free the new action
+	 */
+	/*nautilus_actions_config_action_free (new_action);*/
+}
+
+static void
+free_keys_values( GSList *list )
+{
+	GSList *item;
+	for( item = list ; item != NULL ; item = item->next ){
+		GConfEntry *entry = ( GConfEntry * ) item->data;
+		gconf_entry_unref( entry );
+	}
+	g_slist_free( list );
 }
 
 /*
  * load all the key=value pairs of this key (specified as a full path)
  * The list is not recursive, it contains only the immediate children of
- * path. To free the returned list, gconf_entry_free() each list element,
- * then g_slist_free() the list itself.
+ * path.
+ * To free the returned hash table, call free_key_values
  */
 static GSList *
-load_keys_values( const gchar *path )
+load_keys_values( const NactGConf *gconf, const gchar *path )
 {
 	static const gchar *thisfn = "nact_gconf_load_keys_values";
 
-	if( !st_gconf ){
-		initialize();
-	}
-
 	GError *error = NULL;
-	GSList *list_path = gconf_client_all_entries( st_gconf, path, &error );
+	GSList *list_path = gconf_client_all_entries( gconf->private->gconf, path, &error );
 	if( error ){
-		g_error( "%s: %s", thisfn, error->message );
+		g_error( "%s: path=%s, error=%s", thisfn, path, error->message );
 		g_error_free( error );
 		return(( GSList * ) NULL );
 	}
@@ -150,18 +435,14 @@ load_keys_values( const gchar *path )
  * returns a list of keys as full path
  */
 GSList *
-load_subdirs( const gchar *path )
+load_subdirs( const NactGConf *gconf, const gchar *path )
 {
 	static const gchar *thisfn = "nact_gconf_load_subdirs";
 
-	if( !st_gconf ){
-		initialize();
-	}
-
 	GError *error = NULL;
-	GSList *list = gconf_client_all_dirs( st_gconf, path, &error );
+	GSList *list = gconf_client_all_dirs( gconf->private->gconf, path, &error );
 	if( error ){
-		g_error( "%s: %s", thisfn, error->message );
+		g_error( "%s: path=%s, error=%s", thisfn, path, error->message );
 		g_error_free( error );
 		return(( GSList * ) NULL );
 	}
@@ -196,186 +477,187 @@ path_to_struct( const gchar *path )
 	return( io );
 }
 
-/**
- * to be called from NactStorage instance_finalize to free the allocated
- * NactGConfIO structure.
- */
-void
-nact_gconf_dispose( gpointer ptr )
-{
-	NactGConfIO *io = ( NactGConfIO * ) ptr;
-	g_free( io->key );
-	g_free( io->path );
-	g_free( io );
-}
-
-/**
- * Dump the NactGConfIO structure.
- *
- * @pio: a gpointer to the NactGConfIO structure to be dumped.
- */
-void
-nact_gconf_dump( gpointer pio )
-{
-	static const gchar *thisfn = "nact_gconf_dump";
-	NactGConfIO *io = ( NactGConfIO * ) pio;
-	g_debug( "%s: path='%s'", thisfn, io->path );
-	g_debug( "%s: key='%s'", thisfn, io->key );
-}
-
 /*
- * load the action properties from GConf repository and setup action
- * instance accordingly.
+ * set the item properties into the object
  */
 static void
-load_action_properties( NactStorage *action )
+set_item_properties( NactObject *object, GSList *properties )
 {
-	g_assert( NACT_IS_STORAGE( action ));
+	g_assert( NACT_IS_OBJECT( object ));
 
-	gpointer pio;
-	g_object_get( G_OBJECT( action ), PROP_SUBSYSTEM_STR, &pio, NULL );
-	NactGConfIO *io = ( NactGConfIO * ) pio;
+	GSList *item, *listvalues, *iv, *strings;
 
-	GSList *list = load_keys_values( io->path );
+	for( item = properties ; item != NULL ; item = item->next ){
 
-	GSList *item;
-	for( item = list ; item != NULL ; item = item->next ){
 		GConfEntry *entry = ( GConfEntry * ) item->data;
+
 		const char *key = gconf_entry_get_key( entry );
 		GConfValue *value = gconf_entry_get_value( entry );
+
 		switch( value->type ){
+
 			case GCONF_VALUE_STRING:
-				g_object_set( G_OBJECT( action ), key, gconf_value_get_string( value ), NULL );
+				g_object_set( G_OBJECT( object ), key, gconf_value_get_string( value ), NULL );
 				break;
+
+			case GCONF_VALUE_BOOL:
+				g_object_set( G_OBJECT( object ), key, gconf_value_get_bool( value ), NULL );
+				break;
+
+			case GCONF_VALUE_LIST:
+				listvalues = gconf_value_get_list( value );
+				strings = NULL;
+				for( iv = listvalues ; iv != NULL ; iv = iv->next ){
+					strings = g_slist_prepend( strings,
+							( gpointer ) gconf_value_get_string(( GConfValue * ) iv->data ));
+				}
+				g_object_set( G_OBJECT( object ), key, strings, NULL );
+				/*g_slist_free( strings );*/
+				break;
+
 			default:
 				g_assert_not_reached();
 				break;
 		}
 	}
-
-	free_keys_values( list );
 }
 
 /*
- * allocate the whole list of the actions
- * each item of the list is an action GObject, with the NactStorage
- * stuff being initialized
+ * NactIIOProviderInterface implementation
+ * load the list of actions and returns them as a GSList
  */
 static GSList *
-load_list_actions( GType type )
+do_load_actions( NactIIOProvider *provider )
 {
-	return( load_items( NACT_GCONF_CONFIG, type ));
-}
+	static const gchar *thisfn = "nacf_gconf_do_load_actions";
+	g_debug( "%s: provider=%p", thisfn, provider );
 
-/**
- * Return the list of actions as NactStorage-initialized objects.
- *
- * @type: actual GObject type to be allocated.
- */
-GSList *
-nact_gconf_load_actions( GType type )
-{
-	static const gchar *thisfn = "nact_gconf_load_actions";
-	g_debug( "%s", thisfn );
+	g_assert( NACT_IS_IIO_PROVIDER( provider ));
+	g_assert( NACT_IS_GCONF( provider ));
+	NactGConf *self = NACT_GCONF( provider );
 
-	GSList *list = load_list_actions( type );
+	GSList *items = NULL;
 
-	GSList *it;
-	for( it = list ; it ; it = it->next ){
-		load_action_properties( NACT_STORAGE( it->data ));
+	GSList *listpath = load_subdirs( self, NACT_GCONF_CONFIG_PATH );
+	GSList *ip;
+	for( ip = listpath ; ip ; ip = ip->next ){
+
+		NactGConfIO *io = path_to_struct(( const gchar * ) ip->data );
+
+		NactAction *action = nact_action_new( self, io );
+		nact_action_load( action );
+
+		items = g_slist_prepend( items, action );
 	}
+	nactuti_free_string_list( listpath );
 
-	return( list );
+	return( items );
 }
 
 /*
- * read the properties of the profile and fill-up the object accordingly.
+ * NactIIOProviderInterface implementation
+ * load and set the properties of the specified action
  */
 static void
-load_profile_properties( NactStorage *profile )
+do_load_action_properties( NactIIOClient *client )
 {
-	GSList *listvalues, *iv, *strings;
+	static const gchar *thisfn = "nacf_gconf_do_load_action_properties";
+	g_debug( "%s: client=%p", thisfn, client );
 
-	g_assert( NACT_IS_STORAGE( profile ));
+	g_assert( NACT_IS_IIO_CLIENT( client ));
+	g_assert( NACT_IS_ACTION( client ));
+	NactAction *action = NACT_ACTION( client );
 
-	gpointer pio;
-	g_object_get( G_OBJECT( profile ), PROP_SUBSYSTEM_STR, &pio, NULL );
-	NactGConfIO *io = ( NactGConfIO * ) pio;
+	NactGConfIO *io = ( NactGConfIO * ) nact_iio_client_get_provider_data( client );
+	NactGConf *self = NACT_GCONF( nact_iio_client_get_provider_id( client ));
 
-	GSList *list = load_keys_values( io->path );
+	GSList *properties = load_keys_values( self, io->path );
 
-	GSList *item;
-	for( item = list ; item != NULL ; item = item->next ){
+	set_item_properties( NACT_OBJECT( action ), properties );
 
-		GConfEntry *entry = ( GConfEntry * ) item->data;
+	free_keys_values( properties );
+}
 
-		const char *key = gconf_entry_get_key( entry );
-		GConfValue *value = gconf_entry_get_value( entry );
+/*
+ * NactIIOProviderInterface implementation
+ * load the list of profiles for an action and returns them as a GSList
+ */
+static GSList *
+do_load_profiles( NactIIOClient *client )
+{
+	static const gchar *thisfn = "nacf_gconf_do_load_profiles";
+	g_debug( "%s: client=%p", thisfn, client );
 
-		switch( value->type ){
+	g_assert( NACT_IS_IIO_CLIENT( client ));
+	g_assert( NACT_IS_ACTION( client ));
+	NactAction *action = NACT_ACTION( client );
 
-			case GCONF_VALUE_STRING:
-				g_object_set( G_OBJECT( profile ), key, gconf_value_get_string( value ), NULL );
-				break;
+	NactGConfIO *io = ( NactGConfIO * ) nact_iio_client_get_provider_data( client );
+	NactGConf *self = NACT_GCONF( nact_iio_client_get_provider_id( client ));
 
-			case GCONF_VALUE_BOOL:
-				g_object_set( G_OBJECT( profile ), key, gconf_value_get_bool( value ), NULL );
-				break;
+	GSList *items = NULL;
 
-			case GCONF_VALUE_LIST:
-				listvalues = gconf_value_get_list( value );
-				strings = NULL;
-				for( iv = listvalues ; iv != NULL ; iv = iv->next ){
-					/*g_debug( "get '%s'", gconf_value_get_string(( GConfValue * ) iv->data ));*/
-					strings = g_slist_prepend( strings,
-							( gpointer ) gconf_value_get_string(( GConfValue * ) iv->data ));
-				}
-				g_object_set( G_OBJECT( profile ), key, strings, NULL );
-				/*g_slist_free( strings );*/
-				break;
+	GSList *listpath = load_subdirs( self, io->path );
+	GSList *ip;
+	for( ip = listpath ; ip ; ip = ip->next ){
 
-			default:
-				break;
-		}
+		gchar *key = path_to_key(( const gchar * ) ip->data );
+		NactActionProfile *profile = nact_action_profile_new( NACT_OBJECT( action ), key );
+		nact_action_profile_load( NACT_OBJECT( profile ));
+
+		items = g_slist_prepend( items, profile );
 	}
+	nactuti_free_string_list( listpath );
 
-	free_keys_values( list );
+	return( items );
 }
 
 /*
- * allocate the whole list of the profile for the action
- * each item of the list is a profile GObject, with the NactStorage
- * stuff being initialized
+ * NactIIOProviderInterface implementation
+ * load and set the properties of the specified profile
  */
-static GSList *
-load_list_profiles( NactStorage *action, GType type )
+static void
+do_load_profile_properties( NactObject *profile )
 {
-	gpointer pio;
-	g_object_get( G_OBJECT( action ), PROP_SUBSYSTEM_STR, &pio, NULL );
-	NactGConfIO *io = ( NactGConfIO * ) pio;
+	static const gchar *thisfn = "nacf_gconf_do_load_profile_properties";
+	g_debug( "%s: profile=%p", thisfn, profile );
+
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+
+	NactAction *action =
+		NACT_ACTION( nact_action_profile_get_action( NACT_ACTION_PROFILE( profile )));
+
+	g_assert( NACT_IS_ACTION( action ));
+	g_assert( NACT_IS_IIO_CLIENT( action ));
+
+	NactIIOClient *client = NACT_IIO_CLIENT( action );
+
+	NactGConfIO *io = ( NactGConfIO * ) nact_iio_client_get_provider_data( client );
+	NactGConf *self = NACT_GCONF( nact_iio_client_get_provider_id( client ));
+
+	gchar *path = g_strdup_printf(
+			"%s/%s", io->path, nact_action_profile_get_id( NACT_ACTION_PROFILE( profile )));
+
+	GSList *properties = load_keys_values( self, path );
 
-	return( load_items( io->path, type ));
+	g_free( path );
+
+	set_item_properties( profile, properties );
+
+	free_keys_values( properties );
 }
 
-/**
- * Return the list of profiles as NactStorage-initialized objects.
- *
- * @action: the action.
- *
- * @type: actual GObject type to be allocated.
+/*
+ * NactIIOProviderInterface implementation
  */
-GSList *
-nact_gconf_load_profiles( NactStorage *action, GType type )
+static void
+do_release_data( NactIIOClient *client )
 {
-	static const gchar *thisfn = "nact_gconf_load_profiles";
-	g_debug( "%s", thisfn );
+	g_assert( NACT_IS_IIO_CLIENT( client ));
 
-	GSList *list = load_list_profiles( action, type );
+	NactGConfIO *io = ( NactGConfIO * ) nact_iio_client_get_provider_data( client );
 
-	GSList *it;
-	for( it = list ; it ; it = it->next ){
-		load_profile_properties( NACT_STORAGE( it->data ));
-	}
-
-	return( list );
+	g_free( io->key );
+	g_free( io->path );
+	g_free( io );
 }
diff --git a/src/common/nact-gconf.h b/src/common/nact-gconf.h
index f016ce6..74d2ee1 100644
--- a/src/common/nact-gconf.h
+++ b/src/common/nact-gconf.h
@@ -32,20 +32,41 @@
 #define __NACT_GCONF_H__
 
 /*
- * read/write api for the GCong storage subsystem
+ * NactGConf class definition.
+ *
+ * Implements the NactIIOProvider (I/O storage subsystem) interface.
  */
 
-#include <glib.h>
-#include "nact-storage.h"
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
-void     nact_gconf_dispose( gpointer io );
-void     nact_gconf_dump( gpointer io );
+#define NACT_GCONF_TYPE					( nact_gconf_get_type())
+#define NACT_GCONF( object )			( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_GCONF_TYPE, NactGConf ))
+#define NACT_GCONF_CLASS( klass )		( G_TYPE_CHECK_CLASS_CAST( klass, NACT_GCONF_TYPE, NactGConfClass ))
+#define NACT_IS_GCONF( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_GCONF_TYPE ))
+#define NACT_IS_GCONF_CLASS( klass )	( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_GCONF_TYPE ))
+#define NACT_GCONF_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_GCONF_TYPE, NactGConfClass ))
+
+typedef struct NactGConfPrivate NactGConfPrivate;
+
+typedef struct {
+	GObject           parent;
+	NactGConfPrivate *private;
+}
+	NactGConf;
+
+typedef struct NactGConfClassPrivate NactGConfClassPrivate;
+
+typedef struct {
+	GObjectClass           parent;
+	NactGConfClassPrivate *private;
+}
+	NactGConfClass;
 
-GSList  *nact_gconf_load_actions( GType type );
+GType      nact_gconf_get_type( void );
 
-GSList  *nact_gconf_load_profiles( NactStorage *action, GType type );
+NactGConf *nact_gconf_new( const GObject *pivot );
 
 G_END_DECLS
 
diff --git a/src/common/nact-iio-client.c b/src/common/nact-iio-client.c
new file mode 100644
index 0000000..09d16ec
--- /dev/null
+++ b/src/common/nact-iio-client.c
@@ -0,0 +1,154 @@
+/*
+ * 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 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 "nact-iio-client.h"
+#include "nact-io-client.h"
+
+struct NactIIOClientInterfacePrivate {
+};
+
+static GType register_type( void );
+static void  interface_base_init( NactIIOClientInterface *klass );
+static void  interface_base_finalize( NactIIOClientInterface *klass );
+
+GType
+nact_iio_client_get_type( void )
+{
+	static GType object_type = 0;
+
+	if( !object_type ){
+		object_type = register_type();
+	}
+
+	return( object_type );
+}
+
+static GType
+register_type( void )
+{
+	static const GTypeInfo info = {
+		sizeof( NactIIOClientInterface ),
+		( GBaseInitFunc ) interface_base_init,
+		( GBaseFinalizeFunc ) interface_base_finalize,
+		NULL,
+		NULL,
+		NULL,
+		0,
+		0,
+		NULL
+	};
+
+	GType type = g_type_register_static( G_TYPE_INTERFACE, "NactIIOClient", &info, 0 );
+
+	g_type_interface_add_prerequisite( type, G_TYPE_OBJECT );
+
+	return( type );
+}
+
+static void
+interface_base_init( NactIIOClientInterface *klass )
+{
+	static const gchar *thisfn = "nact_iio_client_interface_base_init";
+	static gboolean initialized = FALSE;
+
+	if( !initialized ){
+		g_debug( "%s: klass=%p", thisfn, klass );
+
+		klass->private = g_new0( NactIIOClientInterfacePrivate, 1 );
+
+		klass->get_io_client = NULL;
+
+		initialized = TRUE;
+	}
+}
+
+static void
+interface_base_finalize( NactIIOClientInterface *klass )
+{
+	static const gchar *thisfn = "nact_iio_client_interface_base_finalize";
+	static gboolean finalized = FALSE ;
+
+	if( !finalized ){
+		g_debug( "%s: klass=%p", thisfn, klass );
+
+		g_free( klass->private );
+
+		finalized = TRUE;
+	}
+}
+
+/**
+ * Returns the provider id, usually a pointer to an object which
+ * implements the NactIIOProvider interface.
+ *
+ * @client: a pointer to an object which implements the NactIIOClient
+ * interface.
+ */
+gpointer
+nact_iio_client_get_provider_id( const NactIIOClient *client )
+{
+	g_return_val_if_fail( NACT_IS_IIO_CLIENT( client ), NULL );
+
+	if( NACT_IIO_CLIENT_GET_INTERFACE( client )->get_io_client ){
+
+		NactIOClient *io_client =
+			NACT_IO_CLIENT( NACT_IIO_CLIENT_GET_INTERFACE( client )->get_io_client( client ));
+
+		return( nact_io_client_get_provider_id( io_client ));
+	}
+
+	return( NULL );
+}
+
+/**
+ * Returns the provider data, usually a pointer to some data structure
+ * allocated by the provider to handle object treatments.
+ *
+ * @client: a pointer to an object which implements the NactIIOClient
+ * interface.
+ */
+gpointer
+nact_iio_client_get_provider_data( const NactIIOClient *client )
+{
+	g_return_val_if_fail( NACT_IS_IIO_CLIENT( client ), NULL );
+
+	if( NACT_IIO_CLIENT_GET_INTERFACE( client )->get_io_client ){
+
+		NactIOClient *io_client =
+			NACT_IO_CLIENT( NACT_IIO_CLIENT_GET_INTERFACE( client )->get_io_client( client ));
+
+		return( nact_io_client_get_provider_data( io_client ));
+	}
+
+	return( NULL );
+}
diff --git a/src/common/nact-iio-client.h b/src/common/nact-iio-client.h
new file mode 100644
index 0000000..cab26dc
--- /dev/null
+++ b/src/common/nact-iio-client.h
@@ -0,0 +1,73 @@
+/*
+ * 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 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 __NACT_IIO_CLIENT_H__
+#define __NACT_IIO_CLIENT_H__
+
+/*
+ * NactIIOClient interface definition.
+ *
+ * This is the NactAction base class.
+ *
+ * All objects which take advantage of an NactIIOProvider should
+ * implement this interface ; it will give them an easy access to
+ * NactIIOProvider data.
+ */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NACT_IIO_CLIENT_TYPE					( nact_iio_client_get_type())
+#define NACT_IIO_CLIENT( object )				( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_IIO_CLIENT_TYPE, NactIIOClient ))
+#define NACT_IS_IIO_CLIENT( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_IIO_CLIENT_TYPE ))
+#define NACT_IIO_CLIENT_GET_INTERFACE( object )	( G_TYPE_INSTANCE_GET_INTERFACE(( object ), NACT_IIO_CLIENT_TYPE, NactIIOClientInterface ))
+
+typedef struct NactIIOClient NactIIOClient;
+
+typedef struct NactIIOClientInterfacePrivate NactIIOClientInterfacePrivate;
+
+typedef struct {
+	GTypeInterface                 parent;
+	NactIIOClientInterfacePrivate *private;
+
+	/* api */
+	GObject * ( *get_io_client )( const NactIIOClient *client );
+}
+	NactIIOClientInterface;
+
+GType    nact_iio_client_get_type( void );
+
+gpointer nact_iio_client_get_provider_id( const NactIIOClient *client );
+gpointer nact_iio_client_get_provider_data( const NactIIOClient *client );
+
+G_END_DECLS
+
+#endif /* __NACT_IIO_CLIENT_H__ */
diff --git a/src/common/nact-iio-provider.c b/src/common/nact-iio-provider.c
new file mode 100644
index 0000000..1407b9a
--- /dev/null
+++ b/src/common/nact-iio-provider.c
@@ -0,0 +1,239 @@
+/*
+ * 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 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 "nact-action.h"
+#include "nact-action-profile.h"
+#include "nact-iio-provider.h"
+#include "nact-pivot.h"
+
+struct NactIIOProviderInterfacePrivate {
+};
+
+static GType register_type( void );
+static void  interface_base_init( NactIIOProviderInterface *klass );
+static void  interface_base_finalize( NactIIOProviderInterface *klass );
+
+/**
+ * Registers the GType of this interface.
+ */
+GType
+nact_iio_provider_get_type( void )
+{
+	static GType object_type = 0;
+
+	if( !object_type ){
+		object_type = register_type();
+	}
+
+	return( object_type );
+}
+
+static GType
+register_type( void )
+{
+	static const gchar *thisfn = "nact_iio_provider_register_type";
+	g_debug( "%s", thisfn );
+
+	static const GTypeInfo info = {
+		sizeof( NactIIOProviderInterface ),
+		( GBaseInitFunc ) interface_base_init,
+		( GBaseFinalizeFunc ) interface_base_finalize,
+		NULL,
+		NULL,
+		NULL,
+		0,
+		0,
+		NULL
+	};
+
+	GType type = g_type_register_static( G_TYPE_INTERFACE, "NactIIOProvider", &info, 0 );
+
+	g_type_interface_add_prerequisite( type, G_TYPE_OBJECT );
+
+	return( type );
+}
+
+static void
+interface_base_init( NactIIOProviderInterface *klass )
+{
+	static const gchar *thisfn = "nact_iio_provider_interface_base_init";
+	static gboolean initialized = FALSE;
+
+	if( !initialized ){
+		g_debug( "%s: klass=%p", thisfn, klass );
+
+		klass->private = g_new0( NactIIOProviderInterfacePrivate, 1 );
+
+		klass->load_actions = NULL;
+		klass->load_action_properties = NULL;
+		klass->load_profiles = NULL;
+		klass->load_profile_properties = NULL;
+		klass->release_data = NULL;
+
+		initialized = TRUE;
+	}
+}
+
+static void
+interface_base_finalize( NactIIOProviderInterface *klass )
+{
+	static const gchar *thisfn = "nact_iio_provider_interface_base_finalize";
+	static gboolean finalized = FALSE ;
+
+	if( !finalized ){
+		g_debug( "%s: klass=%p", thisfn, klass );
+
+		g_free( klass->private );
+
+		finalized = TRUE;
+	}
+}
+
+/**
+ * Load the defined actions.
+ *
+ * Return a GSList of NactAction objects.
+ */
+GSList *
+nact_iio_provider_load_actions( const GObject *object )
+{
+	static const gchar *thisfn = "nact_iio_provider_load_actions";
+	g_debug( "%s", thisfn );
+
+	g_assert( NACT_IS_PIVOT( object ));
+	NactPivot *pivot = NACT_PIVOT( object );
+
+	GSList *actions = NULL;
+	GSList *ip;
+	GSList *list;
+	NactIIOProvider *instance;
+
+	GSList *providers = nact_pivot_get_providers( pivot, NACT_IIO_PROVIDER_TYPE );
+
+	for( ip = providers ; ip ; ip = ip->next ){
+
+		instance = NACT_IIO_PROVIDER( ip->data );
+
+		if( NACT_IIO_PROVIDER_GET_INTERFACE( instance )->load_actions ){
+			list = NACT_IIO_PROVIDER_GET_INTERFACE( instance )->load_actions( instance );
+			actions = g_slist_concat( actions, list );
+		}
+	}
+
+	return( actions );
+}
+
+/**
+ * Load and set properties of the action.
+ */
+void
+nact_iio_provider_load_action_properties( NactIIOClient *client )
+{
+	static const gchar *thisfn = "nact_iio_provider_load_action_properties";
+	g_debug( "%s: client=%p", thisfn, client );
+
+	g_assert( NACT_IS_IIO_CLIENT( client ));
+	g_assert( NACT_IS_ACTION( client ));
+
+	NactIIOProvider *provider = nact_iio_client_get_provider_id( client );
+
+	if( NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_action_properties ){
+		NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_action_properties( client );
+	}
+}
+
+/**
+ * Load the defined profiles for the action.
+ *
+ * Return a GSList of NactActionProfile objects.
+ */
+GSList *
+nact_iio_provider_load_profiles( NactIIOClient *client )
+{
+	static const gchar *thisfn = "nact_iio_provider_load_profiles";
+	g_debug( "%s: client=%p", thisfn, client );
+
+	g_assert( NACT_IS_IIO_CLIENT( client ));
+	g_assert( NACT_IS_ACTION( client ));
+
+	NactIIOProvider *provider = nact_iio_client_get_provider_id( client );
+
+	GSList *profiles = NULL;
+
+	if( NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_profiles ){
+		GSList *list = NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_profiles( client );
+		profiles = g_slist_concat( profiles, list );
+	}
+
+	return( profiles );
+}
+
+/**
+ * Load and set properties of the profile.
+ */
+void
+nact_iio_provider_load_profile_properties( NactObject *profile )
+{
+	static const gchar *thisfn = "nact_iio_provider_load_action_properties";
+	g_debug( "%s", thisfn );
+
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+
+	NactIIOClient *client =
+		NACT_IIO_CLIENT( nact_action_profile_get_action( NACT_ACTION_PROFILE( profile )));
+
+	g_assert( NACT_IS_IIO_CLIENT( client ));
+	g_assert( NACT_IS_ACTION( client ));
+
+	NactIIOProvider *provider = nact_iio_client_get_provider_id( client );
+
+	if( NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_profile_properties ){
+		NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_profile_properties( profile );
+	}
+}
+
+/**
+ * Called by nact_io_client_instance_dispose.
+ */
+void
+nact_iio_provider_release_data( NactIIOClient *client )
+{
+	g_assert( NACT_IS_IIO_CLIENT( client ));
+
+	NactIIOProvider *provider = nact_iio_client_get_provider_id( client );
+
+	if( NACT_IIO_PROVIDER_GET_INTERFACE( provider )->release_data ){
+		NACT_IIO_PROVIDER_GET_INTERFACE( provider )->release_data( client );
+	}
+}
diff --git a/src/common/nact-iio-provider.h b/src/common/nact-iio-provider.h
new file mode 100644
index 0000000..87aa410
--- /dev/null
+++ b/src/common/nact-iio-provider.h
@@ -0,0 +1,83 @@
+/*
+ * 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 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 __NACT_IIO_PROVIDER_H__
+#define __NACT_IIO_PROVIDER_H__
+
+/*
+ * NactIIOProvider interface definition.
+ *
+ * This is the API all storage subsystems should implement in order to
+ * provide i/o resources to NautilusActions.
+ *
+ * In a near or far future, provider subsystems may be extended by
+ * creating extension libraries, this class loading the modules at
+ * startup time (e.g. on the model of provider interfaces in Nautilus).
+ */
+
+#include "nact-object.h"
+#include "nact-iio-client.h"
+
+G_BEGIN_DECLS
+
+#define NACT_IIO_PROVIDER_TYPE						( nact_iio_provider_get_type())
+#define NACT_IIO_PROVIDER( object )					( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_IIO_PROVIDER_TYPE, NactIIOProvider ))
+#define NACT_IS_IIO_PROVIDER( object )				( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_IIO_PROVIDER_TYPE ))
+#define NACT_IIO_PROVIDER_GET_INTERFACE( instance )	( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), NACT_IIO_PROVIDER_TYPE, NactIIOProviderInterface ))
+
+typedef struct NactIIOProvider NactIIOProvider;
+
+typedef struct NactIIOProviderInterfacePrivate NactIIOProviderInterfacePrivate;
+
+typedef struct {
+	GTypeInterface                   parent;
+	NactIIOProviderInterfacePrivate *private;
+
+	/* i/o api */
+	GSList * ( *load_actions )( NactIIOProvider *instance );
+	void     ( *load_action_properties )( NactIIOClient *client );
+	GSList * ( *load_profiles )( NactIIOClient *client );
+	void     ( *load_profile_properties )( NactObject *profile );
+	void     ( *release_data )( NactIIOClient *client );
+}
+	NactIIOProviderInterface;
+
+GType   nact_iio_provider_get_type( void );
+
+GSList *nact_iio_provider_load_actions( const GObject *pivot );
+void    nact_iio_provider_load_action_properties( NactIIOClient *client );
+GSList *nact_iio_provider_load_profiles( NactIIOClient *client );
+void    nact_iio_provider_load_profile_properties( NactObject *profile );
+
+void    nact_iio_provider_release_data( NactIIOClient *client );
+
+G_END_DECLS
+
+#endif /* __NACT_IIO_PROVIDER_H__ */
diff --git a/src/common/nact-io-client.c b/src/common/nact-io-client.c
new file mode 100644
index 0000000..fabd006
--- /dev/null
+++ b/src/common/nact-io-client.c
@@ -0,0 +1,245 @@
+/*
+ * 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 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 "nact-io-client.h"
+
+struct NactIOClientPrivate {
+	gboolean dispose_has_run;
+	gpointer provider_id;
+	gpointer provider_data;
+};
+
+struct NactIOClientClassPrivate {
+};
+
+enum {
+	PROP_PROVIDER_ID = 1,
+	PROP_PROVIDER_DATA
+};
+
+static GObjectClass *st_parent_class = NULL;
+
+static GType   register_type( void );
+static void    class_init( NactIOClientClass *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 );
+
+NactIOClient *
+nact_io_client_new( gpointer provider, gpointer data )
+{
+	return( g_object_new( NACT_IO_CLIENT_TYPE, "provider-id", provider, "provider-data", data, NULL ));
+}
+
+GType
+nact_io_client_get_type( void )
+{
+	static GType object_type = 0;
+
+	if( !object_type ){
+		object_type = register_type();
+	}
+
+	return( object_type );
+}
+
+static GType
+register_type( void )
+{
+	static GTypeInfo info = {
+		sizeof( NactIOClientClass ),
+		( GBaseInitFunc ) NULL,
+		( GBaseFinalizeFunc ) NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( NactIOClient ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	return( g_type_register_static( G_TYPE_OBJECT, "NactIOClient", &info, 0 ));
+}
+
+static void
+class_init( NactIOClientClass *klass )
+{
+	static const gchar *thisfn = "nact_io_client_class_init";
+	g_debug( "%s: klass=%p", thisfn, klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	GObjectClass *object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
+	object_class->set_property = instance_set_property;
+	object_class->get_property = instance_get_property;
+
+	GParamSpec *spec;
+	spec = g_param_spec_pointer(
+			"provider-id",
+			"provider-id",
+			"IIO Provider internal id.",
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_PROVIDER_ID, spec );
+
+	spec = g_param_spec_pointer(
+			"provider-data",
+			"provider-data",
+			"IIO Provider internal data area pointer",
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_PROVIDER_DATA, spec );
+
+	klass->private = g_new0( NactIOClientClassPrivate, 1 );
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+	/*static const gchar *thisfn = "nact_io_client_instance_init";
+	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );*/
+
+	g_assert( NACT_IS_IO_CLIENT( instance ));
+	NactIOClient *self = NACT_IO_CLIENT( instance );
+
+	self->private = g_new0( NactIOClientPrivate, 1 );
+
+	self->private->dispose_has_run = FALSE;
+	self->private->provider_id = NULL;
+	self->private->provider_data = NULL;
+}
+
+static void
+instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
+{
+	g_assert( NACT_IS_IO_CLIENT( object ));
+	NactIOClient *self = NACT_IO_CLIENT( object );
+
+	switch( property_id ){
+		case PROP_PROVIDER_ID:
+			g_value_set_pointer( value, self->private->provider_id );
+			break;
+
+		case PROP_PROVIDER_DATA:
+			g_value_set_pointer( value, self->private->provider_data );
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+			break;
+	}
+}
+
+static void
+instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
+{
+	/*static const gchar *thisfn = "nact_object_instance_set_property";*/
+
+	g_assert( NACT_IS_IO_CLIENT( object ));
+	NactIOClient *self = NACT_IO_CLIENT( object );
+
+	switch( property_id ){
+		case PROP_PROVIDER_ID:
+			self->private->provider_id = g_value_get_pointer( value );
+			/*g_debug( "%s: io_origin=%d", thisfn, self->private->io_origin );*/
+			break;
+
+		case PROP_PROVIDER_DATA:
+			self->private->provider_data = g_value_get_pointer( value );
+			/*g_debug( "%s: io_subsystem=%p", thisfn, self->private->io_subsystem );*/
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+			break;
+	}
+}
+
+static void
+instance_dispose( GObject *object )
+{
+	g_assert( NACT_IS_IO_CLIENT( object ));
+	NactIOClient *self = NACT_IO_CLIENT( object );
+
+	if( !self->private->dispose_has_run ){
+
+		self->private->dispose_has_run = TRUE;
+
+		/* chain up to the parent class */
+		G_OBJECT_CLASS( st_parent_class )->dispose( object );
+	}
+}
+
+static void
+instance_finalize( GObject *object )
+{
+	g_assert( NACT_IS_IO_CLIENT( object ));
+	/*NactIOClient *self = ( NactIOClient * ) object;*/
+
+	/* chain call to parent class */
+	if( st_parent_class->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( object );
+	}
+}
+
+/**
+ * Returns the provider id, usually a pointer to an object which
+ * implements the NactIIOProvider interface.
+ *
+ * @client: a pointer to a NactIOClient object.
+ */
+gpointer
+nact_io_client_get_provider_id( const NactIOClient *client )
+{
+	g_assert( NACT_IS_IO_CLIENT( client ));
+	gpointer id;
+	g_object_get( G_OBJECT( client ), "provider-id", &id, NULL );
+	return( id );
+}
+
+/**
+ * Returns the provider data, usually a pointer to a structure which
+ * holds some NactIIOProvider-relative data.
+ *
+ * @client: a pointer to a NactIOClient object.
+ */
+gpointer
+nact_io_client_get_provider_data( const NactIOClient *client )
+{
+	g_assert( NACT_IS_IO_CLIENT( client ));
+	gpointer data;
+	g_object_get( G_OBJECT( client ), "provider-data", &data, NULL );
+	return( data );
+}
diff --git a/src/common/nact-io-client.h b/src/common/nact-io-client.h
new file mode 100644
index 0000000..b077fd1
--- /dev/null
+++ b/src/common/nact-io-client.h
@@ -0,0 +1,78 @@
+/*
+ * 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 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 __NACT_IO_CLIENT_H__
+#define __NACT_IO_CLIENT_H__
+
+/*
+ * NactIOClient class definition.
+ *
+ * A NactIOClient object should be embedded in every class which
+ * implements NactIIOClient interface. This acts as a companion class
+ * for NactIIOProvider interface.
+ */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NACT_IO_CLIENT_TYPE					( nact_io_client_get_type())
+#define NACT_IO_CLIENT( object )			( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_IO_CLIENT_TYPE, NactIOClient ))
+#define NACT_IO_CLIENT_CLASS( klass )		( G_TYPE_CHECK_CLASS_CAST( klass, NACT_IO_CLIENT_TYPE, NactIOClientClass ))
+#define NACT_IS_IO_CLIENT( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_IO_CLIENT_TYPE ))
+#define NACT_IS_IO_CLIENT_CLASS( klass )	( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_IO_CLIENT_TYPE ))
+#define NACT_IO_CLIENT_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_IO_CLIENT_TYPE, NactIOClientClass ))
+
+typedef struct NactIOClientPrivate NactIOClientPrivate;
+
+typedef struct {
+	GObject              parent;
+	NactIOClientPrivate *private;
+}
+	NactIOClient;
+
+typedef struct NactIOClientClassPrivate NactIOClientClassPrivate;
+
+typedef struct {
+	GObjectClass              parent;
+	NactIOClientClassPrivate *private;
+}
+	NactIOClientClass;
+
+GType         nact_io_client_get_type( void );
+
+NactIOClient *nact_io_client_new( gpointer provider, gpointer data );
+
+gpointer      nact_io_client_get_provider_id( const NactIOClient *client );
+gpointer      nact_io_client_get_provider_data( const NactIOClient *client );
+
+G_END_DECLS
+
+#endif /* __NACT_IO_CLIENT_H__ */
diff --git a/src/common/nact-object.c b/src/common/nact-object.c
new file mode 100644
index 0000000..20c7f92
--- /dev/null
+++ b/src/common/nact-object.c
@@ -0,0 +1,165 @@
+/*
+ * 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 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 "nact-object.h"
+#include "uti-lists.h"
+
+struct NactObjectPrivate {
+	gboolean dispose_has_run;
+};
+
+struct NactObjectClassPrivate {
+};
+
+static GObjectClass *st_parent_class = NULL;
+
+static GType   register_type( void );
+static void    class_init( NactObjectClass *klass );
+static void    instance_init( GTypeInstance *instance, gpointer klass );
+static void    instance_dispose( GObject *object );
+static void    instance_finalize( GObject *object );
+static void    do_dump( const NactObject *object );
+
+GType
+nact_object_get_type( void )
+{
+	static GType object_type = 0;
+
+	if( !object_type ){
+		object_type = register_type();
+	}
+
+	return( object_type );
+}
+
+static GType
+register_type( void )
+{
+	static GTypeInfo info = {
+		sizeof( NactObjectClass ),
+		( GBaseInitFunc ) NULL,
+		( GBaseFinalizeFunc ) NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( NactObject ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	return( g_type_register_static( G_TYPE_OBJECT, "NactObject", &info, 0 ));
+}
+
+static void
+class_init( NactObjectClass *klass )
+{
+	static const gchar *thisfn = "nact_object_class_init";
+	g_debug( "%s: klass=%p", thisfn, klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	GObjectClass *object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
+
+	klass->private = g_new0( NactObjectClassPrivate, 1 );
+
+	klass->dump = do_dump;
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+	/*static const gchar *thisfn = "nact_object_instance_init";
+	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );*/
+
+	g_assert( NACT_IS_OBJECT( instance ));
+	NactObject *self = NACT_OBJECT( instance );
+
+	self->private = g_new0( NactObjectPrivate, 1 );
+
+	self->private->dispose_has_run = FALSE;
+}
+
+static void
+instance_dispose( GObject *object )
+{
+	g_assert( NACT_IS_OBJECT( object ));
+	NactObject *self = NACT_OBJECT( object );
+
+	if( !self->private->dispose_has_run ){
+
+		self->private->dispose_has_run = TRUE;
+
+		/* chain up to the parent class */
+		G_OBJECT_CLASS( st_parent_class )->dispose( object );
+	}
+}
+
+static void
+instance_finalize( GObject *object )
+{
+	g_assert( NACT_IS_OBJECT( object ));
+	/*NactObject *self = ( NactObject * ) object;*/
+
+	/* chain call to parent class */
+	if( st_parent_class->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( object );
+	}
+}
+
+static void
+do_dump( const NactObject *object )
+{
+	static const char *thisfn = "nact_object_do_dump";
+	g_assert( NACT_IS_OBJECT( object ));
+	g_debug( "%s: object=%p", thisfn, object );
+}
+
+/**
+ * Dump the content of the object via g_debug output.
+ *
+ * This is a virtual function which may be implemented by the derived
+ * class ; the derived class may also call its parent class to get a
+ * dump of parent object.
+ *
+ * @object: object to be dumped.
+ */
+void
+nact_object_dump( const NactObject *object )
+{
+	g_assert( NACT_IS_OBJECT( object ));
+
+	NACT_OBJECT_GET_CLASS( object )->dump( object );
+}
diff --git a/src/common/nact-object.h b/src/common/nact-object.h
new file mode 100644
index 0000000..c371716
--- /dev/null
+++ b/src/common/nact-object.h
@@ -0,0 +1,80 @@
+/*
+ * 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 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 __NACT_OBJECT_H__
+#define __NACT_OBJECT_H__
+
+/*
+ * NactObject class definition.
+ *
+ * This is the base class for NactAction and NactActionProfile.
+ *
+ * It takes care of common things such as ids, i/o, etc.
+ * It uses the NactIIOProviderInterface for all storage subsystems
+ * management.
+ */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NACT_OBJECT_TYPE				( nact_object_get_type())
+#define NACT_OBJECT( object )			( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_OBJECT_TYPE, NactObject ))
+#define NACT_OBJECT_CLASS( klass )		( G_TYPE_CHECK_CLASS_CAST( klass, NACT_OBJECT_TYPE, NactObjectClass ))
+#define NACT_IS_OBJECT( object )		( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_OBJECT_TYPE ))
+#define NACT_IS_OBJECT_CLASS( klass )	( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_OBJECT_TYPE ))
+#define NACT_OBJECT_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_OBJECT_TYPE, NactObjectClass ))
+
+typedef struct NactObjectPrivate NactObjectPrivate;
+
+typedef struct {
+	GObject            parent;
+	NactObjectPrivate *private;
+}
+	NactObject;
+
+typedef struct NactObjectClassPrivate NactObjectClassPrivate;
+
+typedef struct {
+	GObjectClass            parent;
+	NactObjectClassPrivate *private;
+
+	/* virtual public functions */
+	void    ( *dump )( const NactObject *object );
+}
+	NactObjectClass;
+
+GType    nact_object_get_type( void );
+
+void     nact_object_dump( const NactObject *object );
+
+G_END_DECLS
+
+#endif /* __NACT_OBJECT_H__ */
diff --git a/src/common/nact-pivot.c b/src/common/nact-pivot.c
new file mode 100644
index 0000000..14ffe43
--- /dev/null
+++ b/src/common/nact-pivot.c
@@ -0,0 +1,214 @@
+/*
+ * Nautilus Pivots
+ * 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 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 "nact-gconf.h"
+#include "nact-pivot.h"
+#include "nact-iio-provider.h"
+
+struct NactPivotPrivate {
+	gboolean  dispose_has_run;
+
+	/* list of interface providers
+	 * needs to be in the instance rather than in the class to be able
+	 * to pass NactPivot object to the IO provider, so that the later
+	 * is able to have access to the former (and its list of actions)
+	 */
+	GSList   *providers;
+
+	/* list of actions
+	 */
+	GSList   *actions;
+};
+
+struct NactPivotClassPrivate {
+};
+
+static GObjectClass   *st_parent_class = NULL;
+
+static GType   register_type( void );
+static void    class_init( NactPivotClass *klass );
+static void    instance_init( GTypeInstance *instance, gpointer klass );
+static GSList *register_interface_providers( const NactPivot *pivot );
+static void    instance_dispose( GObject *object );
+static void    instance_finalize( GObject *object );
+
+NactPivot *
+nact_pivot_new( void )
+{
+	return( g_object_new( NACT_PIVOT_TYPE, NULL ));
+}
+
+GType
+nact_pivot_get_type( void )
+{
+	static GType object_type = 0;
+
+	if( !object_type ){
+		object_type = register_type();
+	}
+
+	return( object_type );
+}
+
+static GType
+register_type( void )
+{
+	static GTypeInfo info = {
+		sizeof( NactPivotClass ),
+		( GBaseInitFunc ) NULL,
+		( GBaseFinalizeFunc ) NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( NactPivot ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	return( g_type_register_static( G_TYPE_OBJECT, "NactPivot", &info, 0 ));
+}
+
+static void
+class_init( NactPivotClass *klass )
+{
+	static const gchar *thisfn = "nact_pivot_class_init";
+	g_debug( "%s: klass=%p", thisfn, klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	GObjectClass *object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
+
+	klass->private = g_new0( NactPivotClassPrivate, 1 );
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+	static const gchar *thisfn = "nact_pivot_instance_init";
+	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );
+
+	g_assert( NACT_IS_PIVOT( instance ));
+	NactPivot* self = NACT_PIVOT( instance );
+
+	self->private = g_new0( NactPivotPrivate, 1 );
+	self->private->dispose_has_run = FALSE;
+	self->private->providers = register_interface_providers( self );
+	self->private->actions = nact_iio_provider_load_actions( G_OBJECT( self ));
+}
+
+static GSList *
+register_interface_providers( const NactPivot *pivot )
+{
+	static const gchar *thisfn = "nact_pivot_register_interface_providers";
+	g_debug( "%s", thisfn );
+
+	GSList *list = NULL;
+
+	list = g_slist_prepend( list, nact_gconf_new( G_OBJECT( pivot )));
+
+	return( list );
+}
+
+static void
+instance_dispose( GObject *object )
+{
+	static const gchar *thisfn = "nact_pivot_instance_dispose";
+	g_debug( "%s: object=%p", thisfn, object );
+
+	g_assert( NACT_IS_PIVOT( object ));
+	NactPivot *self = NACT_PIVOT( object );
+
+	if( !self->private->dispose_has_run ){
+
+		self->private->dispose_has_run = TRUE;
+
+		/* release list of actions */
+		GSList *ia;
+		for( ia = self->private->actions ; ia ; ia = ia->next ){
+			g_object_unref( G_OBJECT( ia->data ));
+		}
+		g_slist_free( self->private->actions );
+		self->private->actions = NULL;
+
+		/* chain up to the parent class */
+		G_OBJECT_CLASS( st_parent_class )->dispose( object );
+	}
+}
+
+static void
+instance_finalize( GObject *object )
+{
+	static const gchar *thisfn = "nact_pivot_instance_finalize";
+	g_debug( "%s: object=%p", thisfn, object );
+
+	g_assert( NACT_IS_PIVOT( object ));
+	NactPivot *self = ( NactPivot * ) object;
+
+	/* release the interface providers */
+	GSList *ip;
+	for( ip = self->private->providers ; ip ; ip = ip->next ){
+		g_object_unref( G_OBJECT( ip->data ));
+	}
+	g_slist_free( self->private->providers );
+	self->private->providers = NULL;
+
+	/* chain call to parent class */
+	if((( GObjectClass * ) st_parent_class )->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( object );
+	}
+}
+
+/**
+ * Returns the list of providers of the required interface.
+ */
+GSList *
+nact_pivot_get_providers( const NactPivot *pivot, GType type )
+{
+	static const gchar *thisfn = "nact_pivot_get_providers";
+	g_debug( "%s", thisfn );
+
+	g_assert( NACT_IS_PIVOT( pivot ));
+
+	GSList *list = NULL;
+	GSList *ip;
+	for( ip = pivot->private->providers ; ip ; ip = ip->next ){
+		if( G_TYPE_CHECK_INSTANCE_TYPE( G_OBJECT( ip->data ), type )){
+			list = g_slist_prepend( list, ip->data );
+		}
+	}
+
+	return( list );
+}
diff --git a/src/common/nact-pivot.h b/src/common/nact-pivot.h
new file mode 100644
index 0000000..1cb5abd
--- /dev/null
+++ b/src/common/nact-pivot.h
@@ -0,0 +1,78 @@
+/*
+ * Nautilus Pivots
+ * A Nautilus extension which offers configurable context menu pivots.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009 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 __NACT_PIVOT_H__
+#define __NACT_PIVOT_H__
+
+/*
+ * NactPivot class definition.
+ *
+ * A consuming program should allocate one new NactPivot object in its
+ * startup phase. The class takes care of declaring the I/O interface,
+ * while registering the known providers. The object will then load
+ * itself the existing list of actions.
+ */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NACT_PIVOT_TYPE					( nact_pivot_get_type())
+#define NACT_PIVOT( object )			( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_PIVOT_TYPE, NactPivot ))
+#define NACT_PIVOT_CLASS( klass )		( G_TYPE_CHECK_CLASS_CAST( klass, NACT_PIVOT_TYPE, NactPivotClass ))
+#define NACT_IS_PIVOT( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_PIVOT_TYPE ))
+#define NACT_IS_PIVOT_CLASS( klass )	( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_PIVOT_TYPE ))
+#define NACT_PIVOT_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_PIVOT_TYPE, NactPivotClass ))
+
+typedef struct NactPivotPrivate NactPivotPrivate;
+
+typedef struct {
+	GObject           parent;
+	NactPivotPrivate *private;
+}
+	NactPivot;
+
+typedef struct NactPivotClassPrivate NactPivotClassPrivate;
+
+typedef struct {
+	GObjectClass           parent;
+	NactPivotClassPrivate *private;
+}
+	NactPivotClass;
+
+GType      nact_pivot_get_type( void );
+
+NactPivot *nact_pivot_new( void );
+
+GSList    *nact_pivot_get_providers( const NactPivot *pivot, GType type );
+
+G_END_DECLS
+
+#endif /* __NACT_PIVOT_H__ */
diff --git a/src/common/nact-storage.c b/src/common/nact-storage.c
deleted file mode 100644
index fdb76b3..0000000
--- a/src/common/nact-storage.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * 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 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 "nact-gconf.h"
-#include "nact-storage.h"
-#include "uti-lists.h"
-
-static GObjectClass *st_parent_class = NULL;
-
-static GType   register_type( void );
-static void    class_init( NactStorageClass *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 void    do_dump( const NactStorage *object );
-
-struct NactStoragePrivate {
-	gboolean dispose_has_run;
-	int      io_origin;
-	gpointer io_subsystem;
-};
-
-struct NactStorageClassPrivate {
-};
-
-enum {
-	PROP_ORIGIN = 1,
-	PROP_SUBSYSTEM
-};
-
-GType
-nact_storage_get_type( void )
-{
-	static GType object_type = 0;
-
-	if( !object_type ){
-		object_type = register_type();
-	}
-
-	return( object_type );
-}
-
-static GType
-register_type( void )
-{
-	static GTypeInfo info = {
-		sizeof( NactStorageClass ),
-		( GBaseInitFunc ) NULL,
-		( GBaseFinalizeFunc ) NULL,
-		( GClassInitFunc ) class_init,
-		NULL,
-		NULL,
-		sizeof( NactStorage ),
-		0,
-		( GInstanceInitFunc ) instance_init
-	};
-
-	return( g_type_register_static( G_TYPE_OBJECT, "NactStorage", &info, 0 ));
-}
-
-static void
-class_init( NactStorageClass *klass )
-{
-	static const gchar *thisfn = "nact_storage_class_init";
-	g_debug( "%s: klass=%p", thisfn, klass );
-
-	st_parent_class = g_type_class_peek_parent( klass );
-
-	GObjectClass *object_class = G_OBJECT_CLASS( klass );
-	object_class->dispose = instance_dispose;
-	object_class->finalize = instance_finalize;
-	object_class->set_property = instance_set_property;
-	object_class->get_property = instance_get_property;
-
-	GParamSpec *spec;
-	spec = g_param_spec_int(
-			PROP_ORIGIN_STR,
-			PROP_ORIGIN_STR,
-			"Internal identifiant of the storage subsystem", 0, ORIGIN_LAST, 0,
-			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_ORIGIN, spec );
-
-	spec = g_param_spec_pointer(
-			PROP_SUBSYSTEM_STR,
-			PROP_SUBSYSTEM_STR,
-			"Pointer to a private are for the I/O subsystem",
-			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_SUBSYSTEM, spec );
-
-	klass->private = g_new0( NactStorageClassPrivate, 1 );
-
-	klass->do_dump = do_dump;
-}
-
-static void
-instance_init( GTypeInstance *instance, gpointer klass )
-{
-	/*static const gchar *thisfn = "nact_storage_instance_init";
-	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );*/
-
-	g_assert( NACT_IS_STORAGE( instance ));
-	NactStorage *self = NACT_STORAGE( instance );
-
-	self->private = g_new0( NactStoragePrivate, 1 );
-
-	self->private->dispose_has_run = FALSE;
-	self->private->io_origin = 0;
-	self->private->io_subsystem = NULL;
-}
-
-static void
-instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
-{
-	g_assert( NACT_IS_STORAGE( object ));
-	NactStorage *self = NACT_STORAGE( object );
-
-	switch( property_id ){
-		case PROP_ORIGIN:
-			g_value_set_int( value, self->private->io_origin );
-			break;
-
-		/* returns the initially provided gpointer
-		 * the caller must not try to free or unref it
-		 */
-		case PROP_SUBSYSTEM:
-			g_value_set_pointer( value, self->private->io_subsystem );
-			break;
-
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
-			break;
-	}
-}
-
-static void
-instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
-{
-	/*static const gchar *thisfn = "nact_storage_instance_set_property";*/
-
-	g_assert( NACT_IS_STORAGE( object ));
-	NactStorage *self = NACT_STORAGE( object );
-
-	switch( property_id ){
-		case PROP_ORIGIN:
-			self->private->io_origin = g_value_get_int( value );
-			/*g_debug( "%s: io_origin=%d", thisfn, self->private->io_origin );*/
-			break;
-
-		case PROP_SUBSYSTEM:
-			self->private->io_subsystem = g_value_get_pointer( value );
-			/*g_debug( "%s: io_subsystem=%p", thisfn, self->private->io_subsystem );*/
-			break;
-
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
-			break;
-	}
-}
-
-static void
-instance_dispose( GObject *object )
-{
-	g_assert( NACT_IS_STORAGE( object ));
-	NactStorage *self = NACT_STORAGE( object );
-
-	if( !self->private->dispose_has_run ){
-
-		self->private->dispose_has_run = TRUE;
-
-		/* chain up to the parent class */
-		G_OBJECT_CLASS( st_parent_class )->dispose( object );
-	}
-}
-
-static void
-instance_finalize( GObject *object )
-{
-	g_assert( NACT_IS_STORAGE( object ));
-	NactStorage *self = ( NactStorage * ) object;
-
-	gpointer io;
-	g_object_get( object, PROP_SUBSYSTEM_STR, &io, NULL );
-
-	switch( self->private->io_origin ){
-		case ORIGIN_GCONF:
-			nact_gconf_dispose( io );
-			break;
-		default:
-			break;
-	}
-
-	/* chain call to parent class */
-	if( st_parent_class->finalize ){
-		G_OBJECT_CLASS( st_parent_class )->finalize( object );
-	}
-}
-
-/**
- * Returns the id of the object as a newly allocated string.
- *
- * This is a virtual function, which may be implemented by the derived
- * class.
- *
- * This class defaults to ask to the storage subsystem for an i/o id.
- * Eventually returns an empty string.
- *
- * @object: object whose id is to be returned.
- *
- * The returned string has to be g_free by the caller.
- */
-gchar *
-nact_storage_get_id( const NactStorage *object )
-{
-	g_assert( NACT_IS_STORAGE( object ));
-	return( NACT_STORAGE_GET_CLASS( object )->get_id( object ));
-}
-
-static void
-do_dump( const NactStorage *object )
-{
-	static const char *thisfn = "nact_storage_do_dump";
-
-	g_assert( NACT_IS_STORAGE( object ));
-
-	g_debug( "%s: origin=%d", thisfn, object->private->io_origin );
-
-	switch( object->private->io_origin ){
-		case ORIGIN_GCONF:
-			nact_gconf_dump( object->private->io_subsystem );
-			break;
-		default:
-			g_assert_not_reached();
-			break;
-	}
-}
-
-/**
- * Dump the content of the object via g_debug output.
- *
- * This is a virtual function which may be implemented by the derived
- * class ; the derived class may also call its parent class to get a
- * dump of parent object.
- *
- * @object: object to be dumped.
- */
-void
-nact_storage_dump( const NactStorage *object )
-{
-	g_assert( NACT_IS_STORAGE( object ));
-
-	NACT_STORAGE_GET_CLASS( object )->do_dump( object );
-}
-
-/**
- * Load all defined actions.
- *
- * Ask to each registered storage subsystem for its list of actions,
- * then concatenates them in the returned list.
- *
- * @type: GObject type to allocate.
- *
- * The returned list is a GSList of NactStorage-derived GObjects.
- */
-GSList *
-nact_storage_load_actions( GType type )
-{
-	static const gchar *thisfn = "nact_storage_load_actions";
-	g_debug( "%s", thisfn );
-
-	GSList *actions = NULL;
-
-	/* GConf storage subsystem */
-	GSList *list_gconf = nact_gconf_load_actions( type );
-	actions = g_slist_concat( actions, list_gconf );
-
-	return( actions );
-}
-
-GSList *
-nact_storage_load_profiles( NactStorage *action, GType type )
-{
-	g_assert( NACT_IS_STORAGE( action ));
-	GSList *profiles = NULL;
-
-	switch( action->private->io_origin ){
-		case ORIGIN_GCONF:
-			profiles = nact_gconf_load_profiles( action, type );
-			break;
-		default:
-			g_assert_not_reached();
-			break;
-	}
-	return( profiles );
-}
diff --git a/src/common/nact-storage.h b/src/common/nact-storage.h
deleted file mode 100644
index a48c6f6..0000000
--- a/src/common/nact-storage.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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 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 __NACT_STORAGE_H__
-#define __NACT_STORAGE_H__
-
-/*
- * NactStorage class definition.
- *
- * This is the NactAction base class.
- *
- * It takes care of storage subsystems management.
- *
- * For now, Gconf storage subsystem is implemented by calling directly
- * ad-hoc functions of nact-gconf.c source.
- *
- * In a near or far future, storage subsystems may be extended by
- * creating extension libraries, this class loading the modules at
- * startup time (e.g. on the model of provider interfaces in Nautilus).
- */
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/* identifiers for various storage subsystems */
-enum {
-	ORIGIN_GCONF = 1,
-	ORIGIN_LAST
-};
-
-/* property names */
-#define PROP_ORIGIN_STR						"origin"
-#define PROP_SUBSYSTEM_STR					"subsystem"
-
-#define NACT_STORAGE_TYPE					( nact_storage_get_type())
-#define NACT_STORAGE( object )				( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_STORAGE_TYPE, NactStorage ))
-#define NACT_STORAGE_CLASS( klass )			( G_TYPE_CHECK_CLASS_CAST( klass, NACT_STORAGE_TYPE, NactStorageClass ))
-#define NACT_IS_STORAGE( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_STORAGE_TYPE ))
-#define NACT_IS_STORAGE_CLASS( klass )		( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_STORAGE_TYPE ))
-#define NACT_STORAGE_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_STORAGE_TYPE, NactStorageClass ))
-
-typedef struct NactStoragePrivate NactStoragePrivate;
-
-typedef struct {
-	GObject             parent;
-	NactStoragePrivate *private;
-}
-	NactStorage;
-
-typedef struct NactStorageClassPrivate NactStorageClassPrivate;
-
-typedef struct {
-	GObjectClass             parent;
-	NactStorageClassPrivate *private;
-
-	/* virtual public functions */
-	void    ( *do_dump )( const NactStorage *object );
-	gchar * ( *get_id )( const NactStorage *object );
-}
-	NactStorageClass;
-
-GType    nact_storage_get_type( void );
-
-gchar   *nact_storage_get_id( const NactStorage *object );
-
-void     nact_storage_dump( const NactStorage *object );
-
-GSList  *nact_storage_load_actions( GType type );
-
-GSList  *nact_storage_load_profiles( NactStorage *action, GType type );
-
-G_END_DECLS
-
-#endif /* __NACT_STORAGE_H__ */
diff --git a/src/plugin/nautilus-actions.c b/src/plugin/nautilus-actions.c
index 2e1da84..3876642 100644
--- a/src/plugin/nautilus-actions.c
+++ b/src/plugin/nautilus-actions.c
@@ -31,40 +31,33 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
 #include <string.h>
+
 #include <libgnomevfs/gnome-vfs.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
 #include <libgnomevfs/gnome-vfs-file-info.h>
 #include <libgnomevfs/gnome-vfs-ops.h>
+
 #include <libnautilus-extension/nautilus-extension-types.h>
 #include <libnautilus-extension/nautilus-file-info.h>
 #include <libnautilus-extension/nautilus-menu-provider.h>
+
 #include <common/nact-action.h>
+#include <common/nact-pivot.h>
 #include <common/nautilus-actions-config.h>
 #include <common/nautilus-actions-config-gconf-reader.h>
 #include "nautilus-actions.h"
 #include "nautilus-actions-test.h"
 #include "nautilus-actions-utils.h"
 
-static GObjectClass *st_parent_class = NULL;
-static GType         st_actions_type = 0;
-
-static void   class_init( NautilusActionsClass *klass );
-static void   menu_provider_iface_init( NautilusMenuProviderIface *iface );
-static void   instance_init( GTypeInstance *instance, gpointer klass );
-static void   instance_dispose( GObject *object );
-static void   instance_finalize( GObject *object );
-static GList *get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files );
-static GList *get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder );
-static void   execute_action( NautilusMenuItem *item, NautilusActionsConfigActionProfile *action_profile );
-static void   action_changed_handler( NautilusActionsConfig* config, NautilusActionsConfigAction* action, gpointer user_data );
+struct NautilusActionsPrivate {
+	gboolean   dispose_has_run;
 
-static const gchar      *get_verified_icon_name( const gchar* icon_name );
-static NautilusMenuItem *create_menu_item( NautilusActionsConfigAction *action, GList *files, NautilusActionsConfigActionProfile* action_profile );
+	/* from nact-pivot */
+	NactPivot *pivot;
 
-struct NautilusActionsPrivate {
-	gboolean  dispose_has_run;
-	GSList   *actions;
+	/* original */
 	NautilusActionsConfigGconfReader* configs;
 	GSList* config_list;
 };
@@ -72,6 +65,22 @@ struct NautilusActionsPrivate {
 struct NautilusActionsClassPrivate {
 };
 
+static GObjectClass *st_parent_class = NULL;
+static GType         st_actions_type = 0;
+
+static void class_init( NautilusActionsClass *klass );
+static void menu_provider_iface_init( NautilusMenuProviderIface *iface );
+static void instance_init( GTypeInstance *instance, gpointer klass );
+static void instance_dispose( GObject *object );
+static void instance_finalize( GObject *object );
+
+static void              action_changed_handler( NautilusActionsConfig* config, NautilusActionsConfigAction* action, gpointer user_data );
+static NautilusMenuItem *create_menu_item( NautilusActionsConfigAction *action, GList *files, NautilusActionsConfigActionProfile* action_profile );
+static void              execute_action( NautilusMenuItem *item, NautilusActionsConfigActionProfile *action_profile );
+static GList            *get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder );
+static GList            *get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files );
+static const gchar      *get_verified_icon_name( const gchar* icon_name );
+
 GType
 nautilus_actions_get_type( void )
 {
@@ -160,7 +169,9 @@ instance_init( GTypeInstance *instance, gpointer klass )
 
 	self->private = g_new0( NautilusActionsPrivate, 1 );
 
-	self->private->actions = nact_action_load_actions();
+	/* from nact-pivot */
+	self->private->pivot = nact_pivot_new();
+
 	self->private->configs = NULL;
 	self->private->configs = nautilus_actions_config_gconf_reader_get ();
 	self->private->config_list = NULL;
@@ -199,6 +210,7 @@ instance_dispose( GObject *object )
 	if( !self->private->dispose_has_run ){
 		self->private->dispose_has_run = TRUE;
 
+		g_object_unref( self->private->pivot );
 		g_object_unref( self->private->configs );
 
 		/* chain up to the parent class */
@@ -229,50 +241,24 @@ static void nautilus_menu_provider_emit_items_updated_signal (NautilusMenuProvid
 #endif
 
 static void
-execute_action( NautilusMenuItem *item, NautilusActionsConfigActionProfile *action_profile )
+action_changed_handler( NautilusActionsConfig* config,
+						NautilusActionsConfigAction* action,
+						gpointer user_data )
 {
-	static const gchar *thisfn = "nautilus_actions_execute_action";
+	static const gchar *thisfn = "nautilus_actions_action_changed_handler";
 	g_debug( "%s", thisfn );
 
-	GList *files;
-	GString *cmd;
-	gchar* param = NULL;
-
-	files = (GList*)g_object_get_data (G_OBJECT (item), "files");
-
-	cmd = g_string_new (action_profile->path);
+	NautilusActions* self = NAUTILUS_ACTIONS (user_data);
 
-	param = nautilus_actions_utils_parse_parameter (action_profile->parameters, files);
+	g_return_if_fail (NAUTILUS_IS_ACTIONS (self));
 
-	if (param != NULL)
+	if (!self->private->dispose_has_run)
 	{
-		g_string_append_printf (cmd, " %s", param);
-		g_free (param);
-	}
-
-	g_spawn_command_line_async (cmd->str, NULL);
-	g_debug( "%s: commande='%s'", thisfn, cmd->str );
-
-	g_string_free (cmd, TRUE);
-
-}
+		nautilus_menu_provider_emit_items_updated_signal(( NautilusMenuProvider * ) self );
 
-static const gchar *
-get_verified_icon_name( const gchar* icon_name )
-{
-	if (icon_name[0] == '/')
-	{
-		if (!g_file_test (icon_name, G_FILE_TEST_IS_REGULAR))
-		{
-			return NULL;
-		}
-	}
-	else if (strlen (icon_name) == 0)
-	{
-		return NULL;
+		nautilus_actions_config_free_actions_list (self->private->config_list);
+		self->private->config_list = nautilus_actions_config_get_actions (NAUTILUS_ACTIONS_CONFIG (self->private->configs));
 	}
-
-	return icon_name;
 }
 
 static NautilusMenuItem *
@@ -311,6 +297,53 @@ create_menu_item( NautilusActionsConfigAction *action, GList *files, NautilusAct
 	return item;
 }
 
+static void
+execute_action( NautilusMenuItem *item, NautilusActionsConfigActionProfile *action_profile )
+{
+	static const gchar *thisfn = "nautilus_actions_execute_action";
+	g_debug( "%s", thisfn );
+
+	GList *files;
+	GString *cmd;
+	gchar* param = NULL;
+
+	files = (GList*)g_object_get_data (G_OBJECT (item), "files");
+
+	cmd = g_string_new (action_profile->path);
+
+	param = nautilus_actions_utils_parse_parameter (action_profile->parameters, files);
+
+	if (param != NULL)
+	{
+		g_string_append_printf (cmd, " %s", param);
+		g_free (param);
+	}
+
+	g_spawn_command_line_async (cmd->str, NULL);
+	g_debug( "%s: commande='%s'", thisfn, cmd->str );
+
+	g_string_free (cmd, TRUE);
+
+}
+
+/*
+ * this function is called when nautilus has to paint a folder background
+ * one of the first calls is with current_folder = 'x-nautilus-desktop:///'
+ * we have nothing to do here ; the function is left as a placeholder
+ * (and as an historic remainder)
+ */
+static GList *
+get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder )
+{
+#ifdef NACT_MAINTAINER_MODE
+	static const gchar *thisfn = "nautilus_actions_get_background_items";
+	gchar *uri = nautilus_file_info_get_uri( current_folder );
+	g_debug( "%s: provider=%p, window=%p, current_folder=%p (%s)", thisfn, provider, window, current_folder, uri );
+	g_free( uri );
+#endif
+	return(( GList * ) NULL );
+}
+
 static GList *
 get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files )
 {
@@ -368,41 +401,20 @@ get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files
 	return items;
 }
 
-/*
- * this function is called when nautilus has to paint a folder background
- * one of the first calls is with current_folder = 'x-nautilus-desktop:///'
- * we have nothing to do here ; the function is left as a placeholder
- * (and as an historic remainder)
- */
-static GList *
-get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder )
-{
-#ifdef NACT_MAINTAINER_MODE
-	static const gchar *thisfn = "nautilus_actions_get_background_items";
-	gchar *uri = nautilus_file_info_get_uri( current_folder );
-	g_debug( "%s: provider=%p, window=%p, current_folder=%p (%s)", thisfn, provider, window, current_folder, uri );
-	g_free( uri );
-#endif
-	return(( GList * ) NULL );
-}
-
-static void
-action_changed_handler( NautilusActionsConfig* config,
-						NautilusActionsConfigAction* action,
-						gpointer user_data )
+static const gchar *
+get_verified_icon_name( const gchar* icon_name )
 {
-	static const gchar *thisfn = "nautilus_actions_action_changed_handler";
-	g_debug( "%s", thisfn );
-
-	NautilusActions* self = NAUTILUS_ACTIONS (user_data);
-
-	g_return_if_fail (NAUTILUS_IS_ACTIONS (self));
-
-	if (!self->private->dispose_has_run)
+	if (icon_name[0] == '/')
 	{
-		nautilus_menu_provider_emit_items_updated_signal(( NautilusMenuProvider * ) self );
-
-		nautilus_actions_config_free_actions_list (self->private->config_list);
-		self->private->config_list = nautilus_actions_config_get_actions (NAUTILUS_ACTIONS_CONFIG (self->private->configs));
+		if (!g_file_test (icon_name, G_FILE_TEST_IS_REGULAR))
+		{
+			return NULL;
+		}
 	}
+	else if (strlen (icon_name) == 0)
+	{
+		return NULL;
+	}
+
+	return icon_name;
 }
diff --git a/src/plugin/nautilus-module.c b/src/plugin/nautilus-module.c
index 6f10c5d..44671cf 100644
--- a/src/plugin/nautilus-module.c
+++ b/src/plugin/nautilus-module.c
@@ -31,8 +31,11 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
 #include <syslog.h>
+
 #include <libnautilus-extension/nautilus-extension-types.h>
+
 #include "nautilus-actions.h"
 
 static guint st_log_handler = 0;



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