[Xfce4-commits] <squeeze:peter/libsqueeze> Rewritten support api

Peter de Ridder noreply at xfce.org
Sun Feb 3 21:46:02 CET 2013


Updating branch refs/heads/peter/libsqueeze
         to c377a7b361708fc4e6ad4489dba4dc76e9a90025 (commit)
       from 9ad6e42724397a3cca72ecabe1bec4dfe717cd54 (commit)

commit c377a7b361708fc4e6ad4489dba4dc76e9a90025
Author: Peter de Ridder <peter at xfce.org>
Date:   Tue Mar 6 21:43:36 2012 +0100

    Rewritten support api
    
    - Reorderd libsqueeze header files
    - Provide execute context to user
    - New mime support api

 libsqueeze/Makefile.am                             |   33 +-
 libsqueeze/archive-command.c                       |  223 ---------
 libsqueeze/archive-command.h                       |   60 ---
 libsqueeze/archive-iter-pool.c                     |    7 +-
 libsqueeze/archive-iter-pool.h                     |    7 +-
 libsqueeze/archive-iter.c                          |   78 ++--
 libsqueeze/archive-iter.h                          |   41 +-
 libsqueeze/archive-tempfs.c                        |    6 +-
 libsqueeze/archive-tempfs.h                        |   10 +
 libsqueeze/archive.c                               |  237 +++++++---
 libsqueeze/archive.h                               |  108 +----
 libsqueeze/btree.c                                 |    5 +-
 libsqueeze/btree.h                                 |    6 +
 libsqueeze/command-option.c                        |    4 +
 libsqueeze/command-option.h                        |   85 +---
 libsqueeze/command-queue.c                         |  193 +++++----
 libsqueeze/command-queue.h                         |   30 +-
 libsqueeze/datetime.c                              |   11 +-
 libsqueeze/datetime.h                              |    2 +-
 libsqueeze/{libsqueeze-mime.h => error.c}          |   32 +-
 libsqueeze/execute-context.c                       |  308 ++++++++++++
 libsqueeze/execute-context.h                       |   65 +++
 libsqueeze/{libsqueeze-mime.h => internal-error.h} |   32 +-
 libsqueeze/{internals.h => internal-types.h}       |   40 +-
 libsqueeze/internals.c                             |   15 +-
 libsqueeze/internals.h                             |   20 +-
 libsqueeze/{archive.h => libsqueeze-archive.h}     |  135 ++----
 .../{support-reader.h => libsqueeze-error.h}       |   22 +-
 libsqueeze/libsqueeze-operate.h                    |  215 ++++++++
 libsqueeze/libsqueeze-support.h                    |  124 +++++
 libsqueeze/libsqueeze-types.h                      |   54 ++
 libsqueeze/libsqueeze-view.h                       |   45 +-
 libsqueeze/libsqueeze.c                            |  110 ++---
 libsqueeze/libsqueeze.h                            |   68 +---
 libsqueeze/parser-context.c                        |    4 +-
 libsqueeze/parser-context.h                        |   15 +-
 libsqueeze/parser.c                                |    3 +-
 libsqueeze/parser.h                                |   13 +-
 libsqueeze/pcre-parser.c                           |    3 +-
 libsqueeze/pcre-parser.h                           |    8 +-
 libsqueeze/scanf-parser.c                          |    9 +-
 libsqueeze/scanf-parser.h                          |    9 +-
 libsqueeze/support-app.c                           |  157 ++++++
 libsqueeze/support-app.h                           |   76 +++
 libsqueeze/support-factory.c                       |  102 ----
 libsqueeze/support-factory.h                       |   60 ---
 libsqueeze/{libsqueeze-mime.h => support-file.c}   |   36 ++-
 libsqueeze/{scanf-parser.h => support-file.h}      |   55 ++-
 libsqueeze/support-info.c                          |  165 +++++++
 libsqueeze/{support-reader.h => support-info.h}    |   21 +-
 libsqueeze/support-reader.c                        |  510 +++++++++++++-------
 libsqueeze/support-reader.h                        |   15 +-
 libsqueeze/support-template.c                      |   98 ----
 libsqueeze/support-template.h                      |   87 ----
 54 files changed, 2282 insertions(+), 1595 deletions(-)

diff --git a/libsqueeze/Makefile.am b/libsqueeze/Makefile.am
index 9d64775..a921542 100644
--- a/libsqueeze/Makefile.am
+++ b/libsqueeze/Makefile.am
@@ -1,34 +1,47 @@
 lib_LTLIBRARIES = libsqueeze-2.la
 
-libsqueeze_2_la_SOURCES =  \
+#pkginclude_HEADERS = \
+#	libsqueeze.h \
+#	libsqueeze-archive.h \
+#	libsqueeze-error.h \
+#	libsqueeze-operate.h \
+#	libsqueeze-support.h \
+#	libsqueeze-types.h \
+#	libsqueeze-view.h \
+#	datetime.h
+
+libsqueeze_2_la_SOURCES = \
 	archive.c archive.h \
 	archive-iter-pool.c archive-iter-pool.h \
 	archive-iter.c archive-iter.h \
 	archive-tempfs.c archive-tempfs.h \
 	btree.c btree.h \
 	command-queue.c command-queue.h \
+	error.c \
+	execute-context.c execute-context.h \
 	command-option.c command-option.h \
 	datetime.c datetime.h \
+	internal-error.h internal-types.h \
 	internals.c internals.h \
 	libsqueeze.c libsqueeze.h \
+	libsqueeze-archive.h \
+	libsqueeze-error.h \
+	libsqueeze-operate.h \
+	libsqueeze-support.h \
+	libsqueeze-types.h \
 	libsqueeze-view.h \
 	parser-context.c parser-context.h \
 	parser.c parser.h \
 	scanf-parser.c scanf-parser.h \
-	support-reader.c support-reader.h \
-	support-template.c support-template.h \
-	support-factory.c support-factory.h
+	support-app.c support-app.h \
+	support-info.c support-info.h \
+	support-file.c support-file.h \
+	support-reader.c support-reader.h
 
 if HAVE_PCRE
 libsqueeze_2_la_SOURCES += pcre-parser.c pcre-parser.h
 endif
 
-# archive-command.c archive-command.h
-# spawn-command.c spawn-command.h
-# macro-command.c macro-command.h
-# remove-command.c remove-command.h
-# xfce-launch-command.c xfce-launch-command.h
-
 libsqueeze_2_la_CFLAGS = \
 	-DDATADIR=\"$(datadir)\" \
 	$(GLIB_CFLAGS)  \
diff --git a/libsqueeze/archive-command.c b/libsqueeze/archive-command.c
deleted file mode 100644
index 230efb9..0000000
--- a/libsqueeze/archive-command.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* 
- *  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 Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-#include <string.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib-object.h> 
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <gio/gio.h>
-
-#include "libsqueeze-archive.h"
-#include "libsqueeze-command.h"
-#include "archive-iter.h"
-#include "archive-command.h"
-#include "command-builder.h"
-#include "archive.h"
-
-static void
-lsq_archive_command_class_init(LSQArchiveCommandClass *);
-static void
-lsq_archive_command_init(LSQArchiveCommand *archive);
-static void
-lsq_archive_command_dispose(GObject *object);
-static void
-lsq_archive_command_finalize(GObject *object);
-
-static GObjectClass *parent_class;
-
-enum
-{
-	LSQ_ARCHIVE_COMMAND_SIGNAL_TERMINATED = 0,
-	LSQ_ARCHIVE_COMMAND_SIGNAL_COUNT
-};
-
-static gint lsq_archive_command_signals[LSQ_ARCHIVE_COMMAND_SIGNAL_COUNT];
-
-GType
-lsq_archive_command_get_type (void)
-{
-	static GType lsq_archive_command_type = 0;
-
- 	if (!lsq_archive_command_type)
-	{
- 		static const GTypeInfo lsq_archive_command_info = 
-		{
-			sizeof (LSQArchiveCommandClass),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) lsq_archive_command_class_init,
-			(GClassFinalizeFunc) NULL,
-			NULL,
-			sizeof (LSQArchiveCommand),
-			0,
-			(GInstanceInitFunc) lsq_archive_command_init,
-			NULL
-		};
-
-		lsq_archive_command_type = g_type_register_static (G_TYPE_OBJECT, "LSQArchiveCommand", &lsq_archive_command_info, 0);
-	}
-	return lsq_archive_command_type;
-}
-
-static void
-lsq_archive_command_class_init(LSQArchiveCommandClass *archive_command_class)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS(archive_command_class);
-
-	object_class->dispose = lsq_archive_command_dispose;
-	object_class->finalize = lsq_archive_command_finalize;
-
-	parent_class = g_type_class_peek(G_TYPE_OBJECT); 
-
-	lsq_archive_command_signals[LSQ_ARCHIVE_COMMAND_SIGNAL_TERMINATED] = g_signal_new("terminated",
-			G_TYPE_FROM_CLASS(archive_command_class),
-			G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-			0,
-			NULL,
-			NULL,
-			g_cclosure_marshal_VOID__POINTER,
-			G_TYPE_NONE,
-			1,
-			G_TYPE_POINTER,
-			NULL);
-}
-
-static void
-lsq_archive_command_init(LSQArchiveCommand *archive_command)
-{
-	archive_command->domain = g_quark_from_string("Command");
-}
-
-/**
- * lsq_archive_command_dispose:
- *
- * @object: LSQArchiveCommand object
- *
- */
-static void
-lsq_archive_command_dispose(GObject *object)
-{
-	LSQArchiveCommand *command = LSQ_ARCHIVE_COMMAND(object);
-	g_signal_emit(object, lsq_archive_command_signals[LSQ_ARCHIVE_COMMAND_SIGNAL_TERMINATED], 0, command->error, NULL);
-	if ( NULL != command->archive )
-	{
-		g_object_unref(command->archive);
-		command->archive = NULL;
-	}
-	parent_class->dispose(object);
-}
-
-/**
- * lsq_archive_command_finalize:
- *
- * @object: LSQArchiveCommand object
- *
- */
-static void
-lsq_archive_command_finalize(GObject *object)
-{
-	LSQArchiveCommand *command = LSQ_ARCHIVE_COMMAND(object);
-	if ( NULL != command->error )
-	{
-		g_error_free(command->error);
-	}
-}
-
-
-/**
- * lsq_archive_command_executr:
- * @command: the archive_command to be executed
- *
- * Returns: true on success
- */
-gboolean
-lsq_archive_command_execute(LSQArchiveCommand *command)
-{
-#ifdef DEBUG
-	g_return_val_if_fail ( NULL != command->archive, FALSE );
-	g_return_val_if_fail ( LSQ_IS_ARCHIVE(command->archive), FALSE );
-#endif /* DEBUG */
-
-	return command->execute(command);
-}
-
-/**
- * lsq_archive_command_stop
- * @command:
- *
- * Returns: TRUE on success, FALSE if the command is not running
- */
-gboolean
-lsq_archive_command_stop(LSQArchiveCommand *command)
-{
-	return command->stop(command);
-}
-
-/**
- * lsq_archive_command_get_archive
- * @command:
- *
- * Returns: the associated archive
- */
-LSQArchive *
-lsq_archive_command_get_archive(LSQArchiveCommand *command)
-{
-	return command->archive;
-}
-
-
-
-/**
- * lsq_archive_command_get_comment
- * @command:
- *
- * Returns: the command comment describing what it is actually doing
- */
-const gchar *
-lsq_archive_command_get_comment(LSQArchiveCommand *archive_command)
-{
-	return archive_command->comment;
-}
-
-LSQArchiveCommand *
-lsq_archive_command_new(const gchar *comment,
-						LSQArchive *archive,
-						LSQCommandFunc exec_command)
-{
-	LSQArchiveCommand *archive_command;
-
-#ifdef DEBUG
-	g_return_val_if_fail ( NULL != archive, NULL );
-	g_return_val_if_fail ( LSQ_IS_ARCHIVE(archive), NULL );
-#endif
-
-	archive_command = g_object_new(LSQ_TYPE_ARCHIVE_COMMAND, NULL);
-
-	g_object_ref(G_OBJECT(archive));
-	archive_command->archive = archive;
-	if ( NULL != comment )
-	{
-		archive_command->comment = g_strdup(comment);
-	}
-
-	archive_command->execute = exec_command;
-
-	return archive_command;
-}
diff --git a/libsqueeze/archive-command.h b/libsqueeze/archive-command.h
deleted file mode 100644
index 572e7bd..0000000
--- a/libsqueeze/archive-command.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  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 Library General Public License for more details.
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software 
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
- */
-
-#ifndef __LIBSQUEEZE_ARCHIVE_COMMAND_H__
-#define __LIBSQUEEZE_ARCHIVE_COMMAND_H__ 
-
-typedef gboolean (*LSQCommandFunc)(LSQArchiveCommand *);
-
-G_BEGIN_DECLS
-
-struct _LSQArchiveCommand
-{
-	GObject		parent;
-	GQuark		 domain;
-	gchar		 *comment;
-	LSQArchive	*archive;
-	GError		*error;
-	gboolean	   running;
-	gboolean	   safe;
-	gpointer	   user_data;
-	LSQCommandFunc execute;
-	LSQCommandFunc stop;
-};
-
-struct _LSQArchiveCommandClass
-{
-	GObjectClass parent;
-}; 
-
-gboolean
-lsq_archive_command_stop(LSQArchiveCommand *command);
-gboolean
-lsq_archive_command_execute(LSQArchiveCommand *command);
-const gchar *
-lsq_archive_command_get_comment(LSQArchiveCommand *archive_command);
-
-LSQArchiveCommand *
-lsq_archive_command_new(const gchar *comment,
-						LSQArchive *archive,
-						LSQCommandFunc exec_command);
-
-LSQArchiveCommand *
-lsq_archive_command_new_remove(const gchar *comment,
-						LSQArchive *archive,
-						GSList *iters);
-
-G_END_DECLS
-#endif /* __LIBSQUEEZE_ARCHIVE_COMMAND_H__ */
diff --git a/libsqueeze/archive-iter-pool.c b/libsqueeze/archive-iter-pool.c
index 310efe8..dba91c2 100644
--- a/libsqueeze/archive-iter-pool.c
+++ b/libsqueeze/archive-iter-pool.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib-object.h> 
@@ -23,9 +25,8 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-#include "libsqueeze-view.h"
-
-
+#include "archive-iter.h"
+#include "archive-iter-pool.h"
 
 
 struct _LSQArchiveIterPool
diff --git a/libsqueeze/archive-iter-pool.h b/libsqueeze/archive-iter-pool.h
index 31315bb..c2b9e90 100644
--- a/libsqueeze/archive-iter-pool.h
+++ b/libsqueeze/archive-iter-pool.h
@@ -15,11 +15,10 @@
 
 #ifndef __ARCHIVE_ITER_POOL_H__
 #define __ARCHIVE_ITER_POOL_H__ 
-G_BEGIN_DECLS
 
-typedef struct _LSQArchiveIter LSQArchiveIter;
-typedef struct _LSQArchiveEntry LSQArchiveEntry;
-typedef struct _LSQArchiveIterPool LSQArchiveIterPool;
+#include "internal-types.h"
+
+G_BEGIN_DECLS
 
 LSQArchiveIterPool *
 lsq_archive_iter_pool_new ( void ) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
diff --git a/libsqueeze/archive-iter.c b/libsqueeze/archive-iter.c
index 3fc35a8..8224613 100644
--- a/libsqueeze/archive-iter.c
+++ b/libsqueeze/archive-iter.c
@@ -13,7 +13,10 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
+
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib-object.h> 
@@ -22,11 +25,10 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-#include "libsqueeze-view.h"
-#include "support-factory.h"
 #include "btree.h"
-
-#include "internals.h"
+#include "archive.h"
+#include "archive-iter-pool.h"
+#include "archive-iter.h"
 
 #ifndef LSQ_ENTRY_CHILD_BUFFER_SIZE
 #define LSQ_ENTRY_CHILD_BUFFER_SIZE 8000
@@ -56,7 +58,7 @@ lsq_archive_entry_save_free ( const LSQArchive *, LSQArchiveEntry * );
 inline static const gchar *
 lsq_archive_entry_get_filename ( const LSQArchiveEntry * );
 inline static const gchar *
-lsq_archive_entry_get_contenttype ( const LSQArchiveEntry * );
+lsq_archive_entry_get_content_type ( const LSQArchiveEntry * );
 
 inline static guint
 lsq_archive_entry_n_children ( const LSQArchiveEntry * );
@@ -290,28 +292,6 @@ lsq_archive_iter_free ( LSQArchiveIter *iter )
 #endif
 }
 
-#ifdef DEBUG
-void
-_lsq_archive_iter_unref ( LSQArchiveIter *iter, const gchar *loc )
-{
-    if ( ( NULL == iter ) || ( 0 == iter->ref_count ) )
-    {
-        g_debug( "unref: %p %s", iter, loc );
-    }
-
-    g_return_if_fail( NULL != iter );
-    g_return_if_fail( 0 != iter->ref_count );
-
-    --iter->ref_count;
-
-    /* free the iter if there are no ref's left */
-    if ( 0 == iter->ref_count )
-    {
-        lsq_archive_iter_free( iter );
-    }
-}
-#endif
-
 void
 lsq_archive_iter_unref ( LSQArchiveIter *iter )
 {
@@ -329,24 +309,6 @@ lsq_archive_iter_unref ( LSQArchiveIter *iter )
     }
 }
 
-#ifdef DEBUG
-LSQArchiveIter *
-_lsq_archive_iter_ref ( LSQArchiveIter *iter, const gchar *loc )
-{
-    if ( ( NULL == iter ) || ( 0 == iter->ref_count ) )
-    {
-        g_debug( "ref: %p %s", iter, loc );
-    }
-
-    g_return_val_if_fail( NULL != iter, NULL );
-    g_return_val_if_fail( 0 != iter->ref_count, NULL );
-
-    ++iter->ref_count;
-
-    return iter;
-}
-#endif
-
 LSQArchiveIter *
 lsq_archive_iter_ref ( LSQArchiveIter *iter )
 {
@@ -454,7 +416,7 @@ lsq_archive_iter_is_directory ( const LSQArchiveIter *iter )
     g_return_val_if_fail( NULL != iter, FALSE );
 #endif
 
-    contenttype = lsq_archive_entry_get_contenttype( iter->entry );
+    contenttype = lsq_archive_entry_get_content_type( iter->entry );
     if ( NULL == contenttype )
     {
         return FALSE;
@@ -678,12 +640,12 @@ lsq_archive_iter_get_filename ( const LSQArchiveIter *iter )
 }
 
 const gchar *
-lsq_archive_iter_get_contenttype ( const LSQArchiveIter *iter )
+lsq_archive_iter_get_content_type ( const LSQArchiveIter *iter )
 {
 #ifdef DEBUG
     g_return_val_if_fail( NULL != iter, FALSE );
 #endif
-    return lsq_archive_entry_get_contenttype( iter->entry );
+    return lsq_archive_entry_get_content_type( iter->entry );
 }
 
 gboolean
@@ -1230,7 +1192,7 @@ lsq_archive_entry_get_filename ( const LSQArchiveEntry *entry )
 }
 
 inline static const gchar *
-lsq_archive_entry_get_contenttype ( const LSQArchiveEntry *entry )
+lsq_archive_entry_get_content_type ( const LSQArchiveEntry *entry )
 {
 #ifdef DEBUG
     g_return_val_if_fail( NULL != entry, NULL );
@@ -1567,7 +1529,7 @@ lsq_archive_entry_get_prop_str ( const LSQArchive *archive, const LSQArchiveEntr
             break;
 
         case LSQ_ARCHIVE_PROP_MIME_TYPE:
-            retval = lsq_archive_entry_get_contenttype( entry );
+            retval = lsq_archive_entry_get_content_type( entry );
             break;
 
         default:
@@ -1921,6 +1883,7 @@ lsq_archive_entry_set_propsva ( const LSQArchive *archive, LSQArchiveEntry *entr
  * Other iter/entry functions *
  ******************************/
 
+#if 0
 static gchar *
 lsq_concat_child_filenames ( LSQArchiveIter *iter )
 {
@@ -1984,6 +1947,7 @@ lsq_concat_iter_filenames ( GSList *file_iters, gboolean recursive )
     }
     return concat_str;
 }
+#endif
 
 GSList *
 lsq_iter_slist_copy ( GSList *iters )
@@ -2010,3 +1974,17 @@ lsq_iter_slist_free ( GSList *iters )
     g_slist_free( iters );
 }
 
+void
+lsq_iter_slist_add_children ( GSList *files )
+{
+    GSList *iter;
+    for ( iter = files; NULL != iter; iter = iter->next )
+    {
+        unsigned int i, size = lsq_archive_iter_n_children( iter->data );
+        for ( i = 0; i < size; ++i )
+        {
+            files = g_slist_append( iter, lsq_archive_iter_nth_child( iter->data, i ) );
+        }
+    }
+}
+
diff --git a/libsqueeze/archive-iter.h b/libsqueeze/archive-iter.h
index 49eaa1a..fb0c490 100644
--- a/libsqueeze/archive-iter.h
+++ b/libsqueeze/archive-iter.h
@@ -14,10 +14,12 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_ARCHIVE_ITER_H__
-#define __LIBSQUEEZE_ARCHIVE_ITER_H__ 
-G_BEGIN_DECLS
+#ifndef __ARCHIVE_ITER_H__
+#define __ARCHIVE_ITER_H__ 
+
+#include "internal-types.h"
 
+G_BEGIN_DECLS
 
 struct _LSQArchiveIter
 {
@@ -39,28 +41,6 @@ lsq_archive_iter_remove (
         gboolean
     );
 
-#ifdef DEBUG
-LSQArchiveIter *
-_lsq_archive_iter_ref (
-        LSQArchiveIter *iter,
-        const gchar *
-    );
-void
-_lsq_archive_iter_unref (
-        LSQArchiveIter *iter,
-        const gchar *
-    );
-/*
-#define lsq_archive_iter_ref(iter) _lsq_archive_iter_ref(iter, G_STRLOC)
-#define lsq_archive_iter_unref(iter) _lsq_archive_iter_unref(iter, G_STRLOC)
-*/
-#endif
-
-LSQArchiveIter *
-lsq_archive_iter_ref ( LSQArchiveIter *iter );
-void
-lsq_archive_iter_unref ( LSQArchiveIter *iter );
-
 LSQArchiveIter *
 lsq_archive_add_file (
         LSQArchive *archive,
@@ -73,6 +53,15 @@ lsq_archive_iter_add_file (
         const gchar *filename
     ) G_GNUC_WARN_UNUSED_RESULT;
 
+guint
+lsq_archive_get_entry_property_offset (
+        const LSQArchive *archive,
+        guint n
+    ) G_GNUC_PURE;
+
+guint
+lsq_archive_entry_properties_size ( const LSQArchive *archive ) G_GNUC_PURE;
+
 void
 lsq_archive_iter_set_prop_value (
         LSQArchiveIter *iter,
@@ -98,4 +87,4 @@ lsq_archive_iter_set_propsv (
 
 G_END_DECLS
 
-#endif /* __LIBSQUEEZE_ARCHIVE_ITER_H__ */
+#endif /* __ARCHIVE_ITER_H__ */
diff --git a/libsqueeze/archive-tempfs.c b/libsqueeze/archive-tempfs.c
index 8d8155b..a10acad 100644
--- a/libsqueeze/archive-tempfs.c
+++ b/libsqueeze/archive-tempfs.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -29,13 +31,9 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-#include "archive-iter.h"
-#include "support-factory.h"
 #include "archive.h"
 #include "archive-tempfs.h"
 
-#include "internals.h"
-
 static guint suffix = 0;
 
 static void
diff --git a/libsqueeze/archive-tempfs.h b/libsqueeze/archive-tempfs.h
index e7676e5..319e0d2 100644
--- a/libsqueeze/archive-tempfs.h
+++ b/libsqueeze/archive-tempfs.h
@@ -14,6 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifndef __ARCHIVE_TEMPFS_H__
+#define __ARCHIVE_TEMPFS_H__
+
 /*
  * temp extract
  * get mime type
@@ -22,6 +25,10 @@
  * check modify
  */
 
+#include "libsqueeze-types.h"
+
+G_BEGIN_DECLS
+
 void
 lsq_tempfs_clean_root_dir ( LSQArchive *archive );
 
@@ -63,3 +70,6 @@ lsq_archive_request_temp_file (
         const gchar *suffix
     ) G_GNUC_WARN_UNUSED_RESULT;
 
+G_END_DECLS
+
+#endif /* __ARCHIVE_TEMPFS_H__ */
diff --git a/libsqueeze/archive.c b/libsqueeze/archive.c
index b899d8e..3e343d3 100644
--- a/libsqueeze/archive.c
+++ b/libsqueeze/archive.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -27,15 +29,33 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-#include "libsqueeze-view.h"
-#include "support-template.h"
-#include "support-factory.h"
-
-#include "btree.h"
+#include "archive-iter.h"
 #include "archive-tempfs.h"
+#include "internals.h"
 #include "command-queue.h"
+#include "command-option.h"
+#include "support-app.h"
+#include "support-file.h"
+#include "archive.h"
+
+
+struct _LSQArchiveClass
+{
+    GObjectClass parent;
+};
+
+struct _LSQArchivePrivate
+{
+    GFile *file;
+    gchar *content_type;
+
+    const LSQSupportInfo *s_info;
+    const LSQSupportApp *refresh_app;
+
+    LSQArchiveState state;
+    const gchar *state_msg;
+};
 
-#include "internals.h"
 
 static void
 lsq_archive_finalize ( GObject *object );
@@ -121,12 +141,15 @@ lsq_archive_finalize ( GObject *object )
  *
  */
 LSQArchive *
-lsq_archive_new ( GFile *file )
+lsq_archive_new (
+        GFile *file,
+        const gchar *mime_type,
+        GError **error
+    )
 {
     LSQArchive *archive;
     GFileInfo *file_info;
     const gchar *content_type;
-    GSList *iter;
     gchar *_basename;
 
     /* We don't support no file. We can't get a content type of a NULL pointer */
@@ -144,6 +167,10 @@ lsq_archive_new ( GFile *file )
         archive->priv->content_type = g_strdup( content_type ); 
         g_object_unref( file_info );
     }
+    else if ( NULL != mime_type )
+    {
+        archive->priv->content_type = g_strdup( mime_type );
+    }
     else
     {
         /* The file might not exist yet. Get the content type from the file name */
@@ -154,36 +181,33 @@ lsq_archive_new ( GFile *file )
         }
         g_free( _basename );
     }
-#ifdef DEBUG
-    g_debug( "mime: %s\n", archive->priv->content_type );
-#endif
+    DBG( "mime: %s\n", archive->priv->content_type );
     if ( NULL == archive->priv->content_type )
     {
+        g_set_error_literal(
+                error,
+                LSQ_ARCHIVE_ERROR,
+                LSQ_ARCHIVE_ERROR_DETECT,
+                _("Content-Type could not be detected")
+            );
         /* Setting the content_type later on is not supported */
-#ifdef DEBUG
-        g_debug( "not supported" );
-#endif
+        DBG( "not supported" );
         g_object_unref( archive );
         return NULL;
     }
 
-    for ( iter = lsq_mime_support_list; NULL != iter; iter = iter->next )
-    {
-        if ( 0 == strcmp( ((LSQSupportTemplate *)iter->data)->content_type, archive->priv->content_type ) )
-        {
-#ifdef DEBUG
-            g_debug( "found template" );
-#endif
-            archive->priv->s_template = iter->data;
-            break;
-        }
-    }
+    archive->priv->s_info = lsq_support_info_get( archive->priv->content_type );
 
-    if ( NULL == archive->priv->s_template )
+    if ( NULL == archive->priv->s_info )
     {
-#ifdef DEBUG
-        g_debug( "not supported" );
-#endif
+        g_set_error(
+                error,
+                LSQ_ARCHIVE_ERROR,
+                LSQ_ARCHIVE_ERROR_CONTENT_TYPE,
+                _("Content-Type '%s' is not supported"),
+                archive->priv->content_type
+            );
+        DBG( "not supported" );
         g_object_unref( archive );
         archive = NULL;
     }
@@ -202,8 +226,9 @@ lsq_archive_n_entry_properties ( const LSQArchive *archive )
 {
 #ifdef DEBUG
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), 0 );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( archive->priv->refresh_app ), 0 );
 #endif
-    return lsq_support_template_get_n_properties( archive->priv->s_template ) + LSQ_ARCHIVE_PROP_USER;
+    return lsq_support_app_get_n_properties( archive->priv->refresh_app ) + LSQ_ARCHIVE_PROP_USER;
 }
 
 /*
@@ -217,6 +242,7 @@ lsq_archive_get_entry_property_type ( const LSQArchive *archive, guint n )
 {
 #ifdef DEBUG
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), G_TYPE_NONE );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( archive->priv->refresh_app ), 0 );
     g_return_val_if_fail( lsq_archive_n_entry_properties( archive ) > n , G_TYPE_NONE );
 #endif
     switch ( n )
@@ -226,7 +252,7 @@ lsq_archive_get_entry_property_type ( const LSQArchive *archive, guint n )
             return G_TYPE_STRING;
 
         default:
-            return lsq_support_template_get_property_type( archive->priv->s_template, n - LSQ_ARCHIVE_PROP_USER );
+            return lsq_support_app_get_property_type( archive->priv->refresh_app, n - LSQ_ARCHIVE_PROP_USER );
     }
 }
 
@@ -235,6 +261,7 @@ lsq_archive_get_entry_property_offset ( const LSQArchive *archive, guint n )
 {
 #ifdef DEBUG
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), 0 );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( archive->priv->refresh_app ), 0 );
     g_return_val_if_fail( lsq_archive_n_entry_properties( archive ) > n , 0 );
 #endif
     switch ( n )
@@ -244,7 +271,7 @@ lsq_archive_get_entry_property_offset ( const LSQArchive *archive, guint n )
             g_return_val_if_reached( 0 );
 
         default:
-            return lsq_support_template_get_property_offset( archive->priv->s_template, n - LSQ_ARCHIVE_PROP_USER );
+            return lsq_support_app_get_property_offset( archive->priv->refresh_app, n - LSQ_ARCHIVE_PROP_USER );
     }
 }
 
@@ -258,6 +285,7 @@ const gchar *
 lsq_archive_get_entry_property_name ( const LSQArchive *archive, guint n )
 {
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), NULL );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( archive->priv->refresh_app ), 0 );
     g_return_val_if_fail( lsq_archive_n_entry_properties( archive ) > n , NULL );
 
     switch( n )
@@ -269,7 +297,7 @@ lsq_archive_get_entry_property_name ( const LSQArchive *archive, guint n )
             return _("Mime type");
 
         default:
-            return lsq_support_template_get_property_name( archive->priv->s_template, n - LSQ_ARCHIVE_PROP_USER );
+            return lsq_support_app_get_property_name( archive->priv->refresh_app, n - LSQ_ARCHIVE_PROP_USER );
     }
 }
 
@@ -278,8 +306,9 @@ lsq_archive_entry_properties_size ( const LSQArchive *archive )
 {
 #ifdef DEBUG
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), 0 );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( archive->priv->refresh_app ), 0 );
 #endif
-    return lsq_support_template_get_properties_size( archive->priv->s_template );
+    return lsq_support_app_get_properties_size( archive->priv->refresh_app );
 }
 
 /*
@@ -326,19 +355,6 @@ lsq_archive_refreshed ( const LSQArchive *archive )
     g_signal_emit( G_OBJECT( archive ), lsq_archive_signals[LSQ_ARCHIVE_SIGNAL_REFRESHED], 0, NULL );
 }
 
-void lsq_archive_add_children ( GSList *files )
-{
-    GSList *iter;
-    for ( iter = files; NULL != iter; iter = iter->next )
-    {
-        unsigned int i, size = lsq_archive_iter_n_children( iter->data );
-        for ( i = 0; i < size; ++i )
-        {
-            files = g_slist_append( iter, lsq_archive_iter_nth_child( iter->data, i ) );
-        }
-    }
-}
-
 void
 lsq_archive_state_changed ( const LSQArchive *archive )
 {
@@ -378,7 +394,7 @@ lsq_archive_can_stop ( const LSQArchive *archive )
 }
 
 gboolean
-lsq_archive_stop ( const LSQArchive *archive )
+lsq_archive_stop ( LSQArchive *archive )
 {
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), FALSE );
 
@@ -401,12 +417,34 @@ lsq_archive_get_state ( const LSQArchive *archive )
     return archive->priv->state;
 }
 
+/*
 LSQSupportType
 lsq_archive_get_support_mask ( const LSQArchive *archive )
 {
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), 0 );
 
-    return archive->priv->s_template->support_mask;
+    return archive->priv->s_info->support_mask;
+}
+*/
+
+void
+lsq_archive_set_refresh_app (
+        LSQArchive *archive,
+        const LSQSupportApp *app
+    )
+{
+    g_return_if_fail( LSQ_IS_ARCHIVE( archive ) );
+    g_return_if_fail( NULL == app || LSQ_IS_SUPPORT_APP( app ) );
+
+    if ( NULL == app )
+    {
+         app = archive->priv->refresh_app;
+         if ( NULL == app )
+         {
+             /* Find the first refresh supporting app */
+         }
+    }
+    archive->priv->refresh_app = app;
 }
 
 /**
@@ -416,73 +454,132 @@ lsq_archive_get_support_mask ( const LSQArchive *archive )
  *
  * Return value: TRUE on success
  */
-gboolean
-lsq_archive_operate ( LSQArchive *archive, LSQCommandType type, gchar **files, const gchar *directory )
+LSQExecuteContext *
+lsq_archive_operate (
+        LSQArchive *archive,
+        LSQCommandType type,
+        gchar **files,
+        const gchar *directory,
+	const LSQSupportApp *app,
+        GError **error
+    )
 {
-    LSQSupportTemplate *s_template;
-    LSQExecuteContext *leaked = NULL; /* FIXME */
+    //const LSQSupportInfo *s_info;
+    LSQExecuteContext *ctx = NULL;
 
-    g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), FALSE );
+    g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), NULL );
+    g_return_val_if_fail( NULL == app || LSQ_IS_SUPPORT_APP( app ), NULL );
 
-    s_template = archive->priv->s_template;
+    //s_info = archive->priv->s_info;
 
     switch ( type )
     {
         case LSQ_COMMAND_TYPE_ADD:
-            g_return_val_if_fail( files, FALSE );
-            leaked = lsq_command_queue_execute( s_template->add_cmd_queue, archive, files, NULL, NULL );
+            g_return_val_if_fail( files, NULL );
+	    /*
+            if ( NULL != s_info->add_cmd_queue )
+            {
+                ctx = lsq_command_queue_execute( s_info->add_cmd_queue, archive, files, NULL, NULL, error );
+            }
+	    */
             break;
 
         case LSQ_COMMAND_TYPE_REMOVE:
-            g_return_val_if_fail( files, FALSE );
-            leaked = lsq_command_queue_execute( s_template->remove_cmd_queue, archive, files, NULL, NULL );
+            g_return_val_if_fail( files, NULL );
+	    /*
+            if ( NULL != s_info->remove_cmd_queue )
+            {
+                ctx = lsq_command_queue_execute( s_info->remove_cmd_queue, archive, files, NULL, NULL, error );
+            }
+	    */
             break;
 
         case LSQ_COMMAND_TYPE_EXTRACT:
-            g_return_val_if_fail( directory, FALSE );
-            leaked = lsq_command_queue_execute( s_template->extract_cmd_queue, archive, files, directory, NULL );
+            g_return_val_if_fail( directory, NULL );
+	    /*
+            if ( NULL != s_info->extract_cmd_queue )
+            {
+                ctx = lsq_command_queue_execute( s_info->extract_cmd_queue, archive, files, directory, NULL, error );
+            }
+	    */
             break;
 
         case LSQ_COMMAND_TYPE_REFRESH:
-            leaked = lsq_command_queue_execute( s_template->refresh_cmd_queue, archive, NULL, NULL, s_template->parser );
+	    lsq_archive_set_refresh_app( archive, app );
+	    app = archive->priv->refresh_app;
+            if ( NULL != app->refresh_cmd_queue )
+            {
+                ctx = lsq_command_queue_execute( app->refresh_cmd_queue, archive, NULL, NULL, app->file->parser, error );
+            }
             break;
 
         default:
-            g_return_val_if_reached( FALSE );
+	    DBG( "Unknown command type" );
+            break;
+    }
+
+    /* if cts == NULL and there is no error set, the operation isn't supported */
+    if ( NULL == ctx && NULL != error && NULL == *error )
+    {
+        g_set_error_literal(
+                error,
+                LSQ_ARCHIVE_ERROR,
+                LSQ_ARCHIVE_ERROR_OPERATION,
+                _("Operation not supported")
+            );
+        DBG( "Unsupported operation" );
+    }
+
+    return ctx;
+}
+
+/* this function returns a new reference which should be released by the user */
+LSQExecuteContext *
+lsq_archive_current_operation ( const LSQArchive *archive )
+{
+    LSQExecuteContext *ctx;
+
+    g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), NULL );
+
+    if ( NULL == archive->operation_queue )
+    {
+        return NULL;
     }
 
-    (void)leaked;
+    ctx = LSQ_EXECUTE_CONTEXT( archive->operation_queue->data );
 
-    return TRUE;
+    return g_object_ref( ctx );
 }
 
 LSQCommandOptionPair **
 lsq_archive_get_command_options ( LSQArchive *archive, LSQCommandType type )
 {
     LSQCommandOptionPair **option_list = NULL;
-    LSQSupportTemplate *s_template;
+    //const LSQSupportInfo *s_info;
 
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), NULL );
 
-    s_template = archive->priv->s_template;
+    //s_info = archive->priv->s_info;
 
+    /*
     switch ( type )
     {
         case LSQ_COMMAND_TYPE_ADD:
-            option_list = lsq_command_option_create_pair( s_template->add_options );
+            option_list = lsq_command_option_create_pair( s_info->add_options );
             break;
 
         case LSQ_COMMAND_TYPE_REMOVE:
-            option_list = lsq_command_option_create_pair( s_template->remove_options );
+            option_list = lsq_command_option_create_pair( s_info->remove_options );
             break;
 
         case LSQ_COMMAND_TYPE_EXTRACT:
-            option_list = lsq_command_option_create_pair( s_template->extract_options );
+            option_list = lsq_command_option_create_pair( s_info->extract_options );
             break;
 
         default:
             break;
     }
+    */
 
     return option_list;
 }
diff --git a/libsqueeze/archive.h b/libsqueeze/archive.h
index 2c2f4f5..4b05dc0 100644
--- a/libsqueeze/archive.h
+++ b/libsqueeze/archive.h
@@ -13,58 +13,15 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __ARCHIVE_H__
-#define __ARCHIVE_H__ 
-G_BEGIN_DECLS
-
-#define LSQ_TYPE_ARCHIVE lsq_archive_get_type()
-
-#define LSQ_ARCHIVE(obj) ( \
-        G_TYPE_CHECK_INSTANCE_CAST ((obj), \
-            LSQ_TYPE_ARCHIVE, \
-            LSQArchive))
-
-#define LSQ_IS_ARCHIVE(obj) ( \
-        G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
-            LSQ_TYPE_ARCHIVE))
-
-#define LSQ_ARCHIVE_CLASS(klass) ( \
-        G_TYPE_CHECK_CLASS_CAST ((klass), \
-            LSQ_TYPE_ARCHIVE, \
-            LSQArchiveClass))
+#ifndef __ARCHIVE_INTERNAL_H__
+#define __ARCHIVE_INTERNAL_H__ 
 
-#define LSQ_IS_ARCHIVE_CLASS(klass) ( \
-        G_TYPE_CHECK_CLASS_TYPE ((klass), \
-            LSQ_TYPE_ARCHIVE))
+#include "internal-types.h"
 
-enum
-{
-    LSQ_ARCHIVE_PROP_FILENAME = 0,
-    LSQ_ARCHIVE_PROP_MIME_TYPE,
-    LSQ_ARCHIVE_PROP_USER
-};
-
-typedef enum
-{
-    LSQ_ARCHIVE_STATE_IDLE,
-    LSQ_ARCHIVE_STATE_BUSY
-} LSQArchiveState;
+G_BEGIN_DECLS
 
 typedef struct _LSQArchivePrivate LSQArchivePrivate;
 
-struct _LSQArchivePrivate
-{
-    GFile *file;
-    gchar *content_type;
-
-    LSQSupportTemplate *s_template;
-
-    LSQArchiveState state;
-    const gchar *state_msg;
-};
-
-
-typedef struct _LSQArchive LSQArchive;
 
 struct _LSQArchive
 {
@@ -80,71 +37,28 @@ struct _LSQArchive
         guint64 n_files;
         guint64 n_directories;
     } props;
+    GSList *operation_queue;
 };
 
 
-typedef struct _LSQArchiveClass LSQArchiveClass;
-
-struct _LSQArchiveClass
-{
-    GObjectClass parent;
-};
-
-
-GType
-lsq_archive_get_type ( void ) G_GNUC_CONST;
-
-gchar *
-lsq_archive_get_filename ( const LSQArchive *archive ) G_GNUC_WARN_UNUSED_RESULT;
-gchar *
-lsq_archive_get_path ( const LSQArchive *archive ) G_GNUC_WARN_UNUSED_RESULT;
-const gchar *
-lsq_archive_get_mimetype ( const LSQArchive *archive );
-gboolean
-lsq_archive_exists ( const LSQArchive *archive );
-LSQSupportType
-lsq_archive_get_support_mask ( const LSQArchive *archive );
-
-
 LSQArchive *
-lsq_archive_new ( GFile * ) G_GNUC_WARN_UNUSED_RESULT;
+lsq_archive_new (
+        GFile *,
+        const gchar *mime_type,
+        GError **error
+    ) G_GNUC_WARN_UNUSED_RESULT;
 void
 lsq_archive_state_changed ( const LSQArchive *archive );
-void
-lsq_archive_add_children ( GSList *files );
 gboolean
 lsq_archive_remove_file (
         LSQArchive *,
         const gchar *
     );
 
-GFile *
-lsq_archive_get_file ( const LSQArchive * );
-
-gboolean
-lsq_archive_operate (
-        LSQArchive *archive,
-        LSQCommandType type,
-        gchar **,
-        const gchar *
-    );
-
-LSQCommandOptionPair **
-lsq_archive_get_command_options (
-        LSQArchive *archive,
-        LSQCommandType type
-    ) G_GNUC_WARN_UNUSED_RESULT;
-
-const gchar *
-lsq_archive_get_state_msg ( const LSQArchive *archive );
-
-LSQArchiveState
-lsq_archive_get_state ( const LSQArchive *archive );
-
 void
 lsq_archive_refreshed ( const LSQArchive *archive );
 
 
 G_END_DECLS
 
-#endif /* __ARCHIVE_H__ */
+#endif /* __ARCHIVE_INTERNAL_H__ */
diff --git a/libsqueeze/btree.c b/libsqueeze/btree.c
index 1ac87b8..92fc6ce 100644
--- a/libsqueeze/btree.c
+++ b/libsqueeze/btree.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib-object.h>
@@ -22,9 +24,6 @@
 
 #include <libxfce4util/libxfce4util.h>
 
-#include "libsqueeze.h"
-#include "support-factory.h"
-#include "internals.h"
 #include "btree.h"
 
 #ifndef LSQ_BTREE_MAX_DEPTH
diff --git a/libsqueeze/btree.h b/libsqueeze/btree.h
index d9abb01..7382c54 100644
--- a/libsqueeze/btree.h
+++ b/libsqueeze/btree.h
@@ -17,6 +17,10 @@
 #ifndef __LSQ_BTREE_H__
 #define __LSQ_BTREE_H__
 
+#include "internal-types.h"
+
+G_BEGIN_DECLS
+
 typedef struct _LSQBTree LSQBTree;
 
 struct _LSQBTree {
@@ -51,4 +55,6 @@ lsq_btree_free ( LSQBTree *list ) G_GNUC_INTERNAL;
 LSQBTree *
 lsq_btree_flatten ( LSQBTree *list ) G_GNUC_WARN_UNUSED_RESULT G_GNUC_INTERNAL;
 
+G_END_DECLS
+
 #endif /* __LSQ_BTREE_H__ */
diff --git a/libsqueeze/command-option.c b/libsqueeze/command-option.c
index 8983d95..ab8d1ac 100644
--- a/libsqueeze/command-option.c
+++ b/libsqueeze/command-option.c
@@ -14,12 +14,16 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib-object.h> 
+#include <gio/gio.h> 
 #include <libxfce4util/libxfce4util.h>
 
+#include "libsqueeze.h"
 #include "command-option.h"
 
 #define LSQ_COMMAND_OPTION_GET_CLASS(obj) ( \
diff --git a/libsqueeze/command-option.h b/libsqueeze/command-option.h
index e04389a..8872acb 100644
--- a/libsqueeze/command-option.h
+++ b/libsqueeze/command-option.h
@@ -14,39 +14,12 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef __LSQ_COMMAND_OPTION_H__
-#define __LSQ_COMMAND_OPTION_H__
+#ifndef __COMMAND_OPTION_INTERNAL_H__
+#define __COMMAND_OPTION_INTERNAL_H__
 
-#define LSQ_TYPE_COMMAND_OPTION           lsq_command_option_get_type(0)
-#define LSQ_COMMAND_OPTION(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION,LSQCommandOption))
-#define LSQ_IS_COMMAND_OPTION(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION))
+#include "libsqueeze-types.h"
 
-#define LSQ_TYPE_COMMAND_OPTION_BOOL      lsq_command_option_get_type(1)
-#define LSQ_COMMAND_OPTION_BOOL(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION_BOOL,LSQCommandOptionBool))
-#define LSQ_IS_COMMAND_OPTION_BOOL(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION_BOOL))
-
-#define LSQ_TYPE_COMMAND_OPTION_STRING    lsq_command_option_get_type(2)
-#define LSQ_COMMAND_OPTION_STRING(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION_STRING,LSQCommandOptionString))
-#define LSQ_IS_COMMAND_OPTION_STRING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION_STRING))
-
-#define LSQ_TYPE_COMMAND_OPTION_INT       lsq_command_option_get_type(3)
-#define LSQ_COMMAND_OPTION_INT(obj)       (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION_INT,LSQCommandOptionInt))
-#define LSQ_IS_COMMAND_OPTION_INT(obj)    (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION_INT))
-
-#define LSQ_TYPE_COMMAND_OPTION_UINT      lsq_command_option_get_type(4)
-#define LSQ_COMMAND_OPTION_UINT(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION_UINT,LSQCommandOptionUint))
-#define LSQ_IS_COMMAND_OPTION_UINT(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION_UINT))
-
-typedef struct _LSQCommandOptionPair    LSQCommandOptionPair;
-
-typedef struct _LSQCommandOption        LSQCommandOption;
-typedef struct _LSQCommandOptionString  LSQCommandOptionString;
-typedef struct _LSQCommandOptionBool    LSQCommandOptionBool;
-typedef struct _LSQCommandOptionInt     LSQCommandOptionInt;
-typedef struct _LSQCommandOptionUint    LSQCommandOptionUint;
-
-GType
-lsq_command_option_get_type ( guint ) G_GNUC_CONST;
+G_BEGIN_DECLS
 
 LSQCommandOptionPair **
 lsq_command_option_create_pair ( LSQCommandOption **option_list ) G_GNUC_WARN_UNUSED_RESULT;
@@ -73,52 +46,6 @@ lsq_command_option_get_args (
         gchar **argv
     );
 
-struct _LSQCommandOptionPair
-{
-    GValue value;
-    const LSQCommandOption *option;
-};
-
-struct _LSQCommandOption
-{
-    GTypeInstance parent;
-    const gchar *name;
-    const gchar *flag;
-    const gchar *blurb;
-    GType value_type;
-};
-
-struct _LSQCommandOptionString
-{
-    LSQCommandOption parent;
-
-    const gchar *default_value;
-    const gchar *filter;
-};
-
-struct _LSQCommandOptionBool
-{
-    LSQCommandOption parent;
-
-    gboolean default_value;
-};
-
-struct _LSQCommandOptionInt
-{
-    LSQCommandOption parent;
-
-    gint default_value;
-    gint min_value;
-    gint max_value;
-};
-
-struct _LSQCommandOptionUint
-{
-    LSQCommandOption parent;
-
-    guint default_value;
-    guint min_value;
-    guint max_value;
-};
+G_END_DECLS
 
-#endif /* __LSQ_COMMAND_OPTION_H__ */
+#endif /* __COMMAND_OPTION_INTERNAL_H__ */
diff --git a/libsqueeze/command-queue.c b/libsqueeze/command-queue.c
index 5a4cccc..12e042e 100644
--- a/libsqueeze/command-queue.c
+++ b/libsqueeze/command-queue.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <glib.h>
 #include <glib-object.h> 
 #include <signal.h>
@@ -25,14 +27,12 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-#include "archive-tempfs.h"
-#include "parser-context.h"
+#include "execute-context.h"
 #include "parser.h"
-
+#include "parser-context.h"
+#include "archive.h"
 #include "command-queue.h"
 
-typedef struct _LSQCommandEntry LSQCommandEntry;
-
 struct _LSQCommandEntry
 {
     LSQCommandEntry *next;
@@ -46,6 +46,8 @@ struct _LSQCommandQueue
 {
     GObject parent;
 
+    LSQCommandType type;
+
     LSQCommandEntry *queue;
 };
 
@@ -54,24 +56,6 @@ struct _LSQCommandQueueClass
     GObjectClass parent;
 };
 
-struct _LSQExecuteContext
-{
-    LSQCommandEntry *queue;
-    LSQParser *parser;
-    LSQArchive *archive;
-    gchar **files;
-    gchar *directory;
-    gchar *tempfile;
-    LSQParserContext *ctx;
-    GIOChannel *redir_out;
-    enum {
-        LSQ_EXEC_CTX_STATE_RUNNING = 1<<0,
-        LSQ_EXEC_CTX_STATE_PARSING = 1<<1
-    } state;
-};
-
-static void
-lsq_command_entry_start ( LSQCommandEntry *entry, LSQExecuteContext *ctx );
 static void
 lsq_command_entry_free ( LSQCommandEntry *entry );
 
@@ -112,7 +96,10 @@ lsq_command_queue_finalize ( GObject *object )
 }
 
 LSQCommandQueue *
-lsq_command_queue_new ( const gchar *command_string )
+lsq_command_queue_new (
+        const gchar *command_string,
+        LSQCommandType cmd_type
+    )
 {
     LSQCommandQueue *queue;
 
@@ -120,6 +107,8 @@ lsq_command_queue_new ( const gchar *command_string )
 
     queue = g_object_new( LSQ_TYPE_COMMAND_QUEUE, NULL );
 
+    queue->type = cmd_type;
+
     if ( FALSE == build_queue( queue, command_string ) )
     {
         g_object_unref( queue );
@@ -129,19 +118,6 @@ lsq_command_queue_new ( const gchar *command_string )
     return LSQ_COMMAND_QUEUE( queue );
 }
 
-static const gchar *
-lsq_execute_context_get_temp_file ( LSQExecuteContext *ctx )
-{
-    g_return_val_if_fail( NULL != ctx, NULL );
-
-    if ( NULL == ctx->tempfile )
-    {
-        ctx->tempfile = lsq_archive_request_temp_file( ctx->archive, NULL );
-    }
-
-    return ctx->tempfile;
-}
-
 static gboolean
 validate_format ( const gchar *format )
 {
@@ -258,8 +234,8 @@ static void
 child_exit ( GPid pid, gint status, LSQExecuteContext *ctx )
 {
     g_spawn_close_pid( pid );
-    ctx->state &= ~LSQ_EXEC_CTX_STATE_RUNNING;
-    if ( 0 == ctx->state )
+    ctx->exec_state &= ~LSQ_EXEC_CTX_STATE_RUNNING;
+    if ( 0 == ctx->exec_state )
     {
         ctx->queue = ctx->queue->next;
         if ( NULL != ctx->queue )
@@ -271,10 +247,7 @@ child_exit ( GPid pid, gint status, LSQExecuteContext *ctx )
             //...ERROR | DONE//
         }
     }
-    else
-    {
-        //...ERROR | DONE//
-    }
+    g_object_unref( ctx );
 }
 
 static void
@@ -324,17 +297,20 @@ out_channel ( GIOChannel *source, GIOCondition condition, LSQExecuteContext *ctx
         g_io_channel_flush( dest, NULL );
         g_io_channel_unref( dest );
         ctx->redir_out = NULL;
-        ctx->state &= ~LSQ_EXEC_CTX_STATE_PARSING;
-        if ( 0 == ctx->state )
+        ctx->exec_state &= ~LSQ_EXEC_CTX_STATE_PARSING;
+        if ( 0 == ctx->exec_state )
         {
             ctx->queue = ctx->queue->next;
             if ( NULL != ctx->queue )
             {
                 lsq_command_entry_start( ctx->queue, ctx );
             }
-            //else
-            //...//done
+            else
+            {
+                //...//done
+            }
         }
+        g_object_unref( ctx );
     }
 }
 
@@ -354,17 +330,20 @@ parse_channel ( GIOChannel *source, GIOCondition condition, LSQExecuteContext *c
     {
         lsq_parser_context_set_channel( ctx->ctx, NULL );
         g_io_channel_unref( source );
-        ctx->state &= ~LSQ_EXEC_CTX_STATE_PARSING;
-        if ( 0 == ctx->state )
+        ctx->exec_state &= ~LSQ_EXEC_CTX_STATE_PARSING;
+        if ( 0 == ctx->exec_state )
         {
             ctx->queue = ctx->queue->next;
             if ( NULL != ctx->queue )
             {
                 lsq_command_entry_start( ctx->queue, ctx );
             }
-            //else
-            //...//done
+            else
+            {
+                //...//done
+            }
         }
+        g_object_unref( ctx );
         //FIXME: this is not entirely the correct place, or is it?
         lsq_archive_refreshed( ctx->archive );
         return FALSE;
@@ -372,10 +351,12 @@ parse_channel ( GIOChannel *source, GIOCondition condition, LSQExecuteContext *c
     return TRUE;
 }
 
-static void
-lsq_command_entry_start ( LSQCommandEntry *entry, LSQExecuteContext *ctx )
+gboolean
+lsq_command_entry_start (
+        LSQCommandEntry *entry,
+        LSQExecuteContext *ctx
+    )
 {
-    GError *error = NULL;
     gint fd_in = FALSE;
     gint fd_out = TRUE;
     GIOChannel *redir_in = NULL;
@@ -386,15 +367,15 @@ lsq_command_entry_start ( LSQCommandEntry *entry, LSQExecuteContext *ctx )
     GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL;
     gchar **argvi;
 
-    g_return_if_fail( NULL != entry );
-    g_return_if_fail( NULL != ctx );
+    g_return_val_if_fail( NULL != entry, FALSE );
+    g_return_val_if_fail( NULL != ctx, FALSE );
 
     if ( NULL != entry->redirect_out )
     {
         gchar *file = format_get_filename( entry->redirect_out, ctx );
         ctx->redir_out = g_io_channel_new_file( file, "w", NULL );
         g_free( file );
-        g_return_if_fail( NULL != ctx->redir_out );
+        g_return_val_if_fail( NULL != ctx->redir_out, FALSE );
     }
     else if ( NULL == ctx->ctx )
     {
@@ -406,7 +387,7 @@ lsq_command_entry_start ( LSQCommandEntry *entry, LSQExecuteContext *ctx )
         gchar *file = format_get_filename( entry->redirect_in, ctx );
         redir_in = g_io_channel_new_file( file, "r", NULL );
         g_free( file );
-        g_return_if_fail( NULL != redir_in );
+        g_return_val_if_fail( NULL != redir_in, FALSE );
         fd_in = TRUE;
     }
 
@@ -423,59 +404,91 @@ lsq_command_entry_start ( LSQCommandEntry *entry, LSQExecuteContext *ctx )
     }
 #endif
 
-    if ( FALSE == g_spawn_async_with_pipes( NULL, argv, NULL, flags, NULL, NULL, &pid, ( TRUE == fd_in ) ? &fd_in : NULL, ( TRUE == fd_out ) ? &fd_out : NULL , NULL, &error ) )
+    if ( FALSE == g_spawn_async_with_pipes( NULL, argv, NULL, flags, NULL, NULL, &pid, ( TRUE == fd_in ) ? &fd_in : NULL, ( TRUE == fd_out ) ? &fd_out : NULL , NULL, &ctx->error ) )
     {
-        g_debug( "spawn failed: %s", error->message );
-        g_error_free( error );
-        return;
+        return FALSE;
     }
 
     g_strfreev( argv );
 
-    g_child_watch_add( pid, (GChildWatchFunc)child_exit, ctx );
-    ctx->state |= LSQ_EXEC_CTX_STATE_RUNNING;
+    g_child_watch_add(
+            pid,
+            (GChildWatchFunc)child_exit,
+            g_object_ref( ctx )
+         );
+    ctx->exec_state |= LSQ_EXEC_CTX_STATE_RUNNING;
 
     if ( NULL != entry->redirect_in )
     {
         chan_in = g_io_channel_unix_new( fd_in );
-        g_return_if_fail( NULL != chan_in );
-        g_io_add_watch( redir_in, G_IO_IN|G_IO_HUP, (GIOFunc)in_channel, chan_in );
+        g_return_val_if_fail( NULL != chan_in, FALSE );
+        g_io_add_watch(
+                redir_in,
+                G_IO_IN|G_IO_HUP,
+                (GIOFunc)in_channel,
+                chan_in
+            );
     }
     if ( NULL != entry->redirect_out )
     {
         chan_out = g_io_channel_unix_new( fd_out );
-        g_return_if_fail( NULL != chan_out );
-        g_io_add_watch( chan_out, G_IO_IN|G_IO_HUP, (GIOFunc)out_channel, ctx );
-        ctx->state |= LSQ_EXEC_CTX_STATE_PARSING;
+        g_return_val_if_fail( NULL != chan_out, FALSE );
+        g_io_add_watch(
+                chan_out,
+                G_IO_IN|G_IO_HUP,
+                (GIOFunc)out_channel,
+                g_object_ref( ctx )
+            );
+        ctx->exec_state |= LSQ_EXEC_CTX_STATE_PARSING;
     }
     else if ( NULL != ctx->ctx )
     {
         chan_out = g_io_channel_unix_new( fd_out );
-        g_return_if_fail( NULL != chan_out );
+        g_return_val_if_fail( NULL != chan_out, FALSE );
         lsq_parser_context_set_channel( ctx->ctx, chan_out );
-        g_io_add_watch( chan_out, G_IO_IN|G_IO_HUP, (GIOFunc)parse_channel, ctx );
-        ctx->state |= LSQ_EXEC_CTX_STATE_PARSING;
+        g_io_add_watch(
+                chan_out,
+                G_IO_IN|G_IO_HUP,
+                (GIOFunc)parse_channel,
+                g_object_ref( ctx )
+            );
+        ctx->exec_state |= LSQ_EXEC_CTX_STATE_PARSING;
     }
+
+    return TRUE;
 }
 
 LSQExecuteContext *
-lsq_command_queue_execute ( LSQCommandQueue *queue, LSQArchive *archive, gchar **files, const gchar *directory, LSQParser *parser )
+lsq_command_queue_execute (
+        LSQCommandQueue *queue,
+        LSQArchive *archive,
+        gchar **files,
+        const gchar *directory,
+        LSQParser *parser,
+        GError **error
+    )
 {
     LSQExecuteContext *ctx;
 
     g_return_val_if_fail( LSQ_IS_COMMAND_QUEUE( queue ), NULL );
     g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), NULL );
 
-    ctx = g_new0( LSQExecuteContext, 1 );
-
-    ctx->queue = queue->queue;
-    ctx->archive = archive;
-    ctx->files = g_strdupv( files );
-    ctx->directory = g_strdup( directory );
-    ctx->parser = parser;
-    ctx->ctx = ( NULL != parser ) ? lsq_parser_get_context( parser, archive ) : NULL;
-
-    lsq_command_entry_start( ctx->queue, ctx );
+    ctx = lsq_execute_context_new(
+            queue->queue,
+            archive,
+            files,
+            directory,
+            parser,
+            queue->type
+        );
+       
+    lsq_execute_context_start( ctx );
+
+    if ( TRUE == lsq_operation_get_error( ctx, error ) )
+    {
+        g_object_unref( ctx );
+        return NULL;
+    }
 
     return ctx;
 }
@@ -751,3 +764,17 @@ lsq_command_entry_free ( LSQCommandEntry *entry )
     g_free( entry );
 }
 
+guint
+lsq_command_entry_queue_size ( LSQCommandEntry *queue )
+{
+    LSQCommandEntry *iter;
+    guint size = 0;
+
+    for ( iter = queue; NULL != iter; iter = iter->next )
+    {
+        ++size;
+    }
+
+    return size;
+}
+
diff --git a/libsqueeze/command-queue.h b/libsqueeze/command-queue.h
index 03f8e1c..4371a6f 100644
--- a/libsqueeze/command-queue.h
+++ b/libsqueeze/command-queue.h
@@ -13,8 +13,10 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_COMMAND_QUEUE_H__
-#define __LIBSQUEEZE_COMMAND_QUEUE_H__ 
+#ifndef __COMMAND_QUEUE_H__
+#define __COMMAND_QUEUE_H__ 
+
+#include "internal-types.h"
 
 G_BEGIN_DECLS
 
@@ -43,20 +45,18 @@ G_BEGIN_DECLS
             LSQ_TYPE_COMMAND_QUEUE, \
             LSQCommandQueueClass))
 
-#if 0
-typedef struct _LSQCommandQueue LSQCommandQueue;
-#endif
 
 typedef struct _LSQCommandQueueClass LSQCommandQueueClass;
 
-typedef struct _LSQExecuteContext LSQExecuteContext;
-
 
 GType
 lsq_command_queue_get_type ( void ) G_GNUC_CONST;
 
 LSQCommandQueue *
-lsq_command_queue_new ( const gchar *command_string ) G_GNUC_WARN_UNUSED_RESULT;
+lsq_command_queue_new (
+        const gchar *command_string,
+        LSQCommandType
+    ) G_GNUC_WARN_UNUSED_RESULT;
 
 LSQExecuteContext *
 lsq_command_queue_execute (
@@ -64,11 +64,19 @@ lsq_command_queue_execute (
         LSQArchive *archive,
         gchar **files,
         const gchar *direcotry,
-        LSQParser *parser
+        LSQParser *parser,
+        GError **error
     ) G_GNUC_WARN_UNUSED_RESULT;
 
+guint
+lsq_command_entry_queue_size ( LSQCommandEntry *queue );
 
-G_END_DECLS
+gboolean
+lsq_command_entry_start (
+        LSQCommandEntry *entry,
+        LSQExecuteContext *ctx
+    );
 
-#endif /* __LIBSQUEEZE_COMMAND_QUEUE_H__ */
+G_END_DECLS
 
+#endif /* __COMMAND_QUEUE_H__ */
diff --git a/libsqueeze/datetime.c b/libsqueeze/datetime.c
index 644b899..c26403d 100644
--- a/libsqueeze/datetime.c
+++ b/libsqueeze/datetime.c
@@ -13,7 +13,10 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
+
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #define _XOPEN_SOURCE
 #include <time.h>
 #include <string.h>
@@ -24,13 +27,7 @@
 
 #include <libxfce4util/libxfce4util.h>
 
-#include "libsqueeze.h"
-#include "support-factory.h"
-#include "support-reader.h"
-#include "archive-iter.h"
-#include "archive.h"
-
-#include "internals.h"
+#include "datetime.h"
 
 #define TM_SEC_SIZE     (6)
 #define TM_MIN_SIZE     (6)
diff --git a/libsqueeze/datetime.h b/libsqueeze/datetime.h
index 4d42c86..05e1000 100644
--- a/libsqueeze/datetime.h
+++ b/libsqueeze/datetime.h
@@ -16,8 +16,8 @@
 
 #ifndef __LIBSQUEEZE_DATETIME_H__
 #define __LIBSQUEEZE_DATETIME_H__ 
-G_BEGIN_DECLS
 
+G_BEGIN_DECLS
 
 #define LSQ_TYPE_DATETIME lsq_datetime_get_type()
 #define LSQ_DATETIME(v) ((LSQDateTime)(v))
diff --git a/libsqueeze/libsqueeze-mime.h b/libsqueeze/error.c
similarity index 58%
copy from libsqueeze/libsqueeze-mime.h
copy to libsqueeze/error.c
index c963178..dda579e 100644
--- a/libsqueeze/libsqueeze-mime.h
+++ b/libsqueeze/error.c
@@ -14,15 +14,31 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef __LIBSQUEEZE_MIME_SUPPORT_H__
-#define __LIBSQUEEZE_MIME_SUPPORT_H__
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-object.h> 
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <gio/gio.h>
 
-typedef struct _LSQMimeSupport LSQMimeSupport;
+#include <libxfce4util/libxfce4util.h>
 
-const gchar *
-lsq_mime_support_get_comment ( LSQMimeSupport * );
+#include "libsqueeze.h"
+#include "internal-error.h"
 
-const gchar *
-lsq_mime_support_get_name ( LSQMimeSupport * );
+GQuark
+lsq_archive_error_quark ( void )
+{
+    return g_quark_from_static_string( "lsq-archive-error-quark" );
+}
 
-#endif /* __LIBSQUEEZE_MIME_SUPPORT_H__ */
+GQuark
+lsq_support_error_quark ( void )
+{
+    return g_quark_from_static_string( "lsq-support-error-quark" );
+}
diff --git a/libsqueeze/execute-context.c b/libsqueeze/execute-context.c
new file mode 100644
index 0000000..a13a5ec
--- /dev/null
+++ b/libsqueeze/execute-context.c
@@ -0,0 +1,308 @@
+/*
+ *  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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <glib.h>
+#include <glib-object.h> 
+#include <signal.h>
+
+#include <gio/gio.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "libsqueeze.h"
+#include "archive.h"
+#include "parser.h"
+#include "archive-tempfs.h"
+#include "command-queue.h"
+#include "execute-context.h"
+
+
+struct _LSQExecuteContextClass
+{
+    GObjectClass parent;
+};
+
+enum {
+    LSQ_EXECUTE_CONTEXT_PROPERTY_ARCHIVE = 1,
+};
+
+static void
+lsq_execute_context_set_property (
+        GObject *,
+        guint,
+        const GValue *,
+        GParamSpec *
+    );
+
+static void
+lsq_execute_context_get_property (
+        GObject *,
+        guint,
+        GValue *,
+        GParamSpec *
+    );
+
+G_DEFINE_TYPE ( LSQExecuteContext, lsq_execute_context, G_TYPE_OBJECT );
+
+static void
+lsq_execute_context_init ( LSQExecuteContext *self )
+{
+}
+
+static void
+lsq_execute_context_finalize ( GObject *self )
+{
+    LSQExecuteContext *ctx = LSQ_EXECUTE_CONTEXT( self );
+
+    g_return_if_fail( LSQ_IS_ARCHIVE( ctx->archive ) );
+
+    ctx->archive->operation_queue = g_slist_remove(
+            ctx->archive->operation_queue,
+            ctx
+        );
+
+    g_strfreev( ctx->files );
+    g_free( ctx->directory );
+    g_object_unref( ctx->ctx );
+}
+
+static void
+lsq_execute_context_class_init ( LSQExecuteContextClass *klass )
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+    GParamSpec *pspec;
+
+    object_class->finalize = lsq_execute_context_finalize;
+
+    object_class->set_property = lsq_execute_context_set_property;
+    object_class->get_property = lsq_execute_context_get_property;
+
+    pspec = g_param_spec_object( "archive", NULL, NULL, LSQ_TYPE_ARCHIVE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY );
+    g_object_class_install_property( object_class, LSQ_EXECUTE_CONTEXT_PROPERTY_ARCHIVE, pspec );
+}
+
+static void
+lsq_execute_context_set_property (
+        GObject *object,
+        guint property_id,  
+        const GValue *value,
+        GParamSpec *pspec
+    )
+{
+    switch ( property_id )
+    {
+        case LSQ_EXECUTE_CONTEXT_PROPERTY_ARCHIVE:
+            LSQ_EXECUTE_CONTEXT ( object )->archive = g_value_get_object( value );
+            break;
+    }
+}
+
+static void
+lsq_execute_context_get_property (
+        GObject *object,
+        guint property_id,
+        GValue *value,
+        GParamSpec *pspec
+    )
+{
+    switch ( property_id )
+    {
+        case LSQ_EXECUTE_CONTEXT_PROPERTY_ARCHIVE:
+            g_value_set_object( value, LSQ_EXECUTE_CONTEXT ( object )->archive );
+            break;
+    }
+}
+
+LSQExecuteContext *
+lsq_execute_context_new (
+        LSQCommandEntry *queue,
+        LSQArchive *archive,
+        gchar **files,
+        const gchar *directory,
+        LSQParser *parser,
+        LSQCommandType cmd_type
+    )
+{
+    LSQExecuteContext *ctx;
+
+    g_return_val_if_fail( LSQ_IS_ARCHIVE( archive ), NULL );
+
+    ctx = g_object_new(
+            LSQ_TYPE_EXECUTE_CONTEXT,
+            "archive",
+            archive,
+            NULL
+        );
+
+    ctx->queue = queue;
+    ctx->files = g_strdupv( files );
+    ctx->directory = g_strdup( directory );
+    ctx->parser = parser;
+    if ( NULL != parser)
+    {
+        ctx->ctx = lsq_parser_get_context( parser, archive );
+    }
+    ctx->type = cmd_type;
+
+    ctx->queue_size = lsq_command_entry_queue_size( queue );
+
+    archive->operation_queue = g_slist_append(
+            archive->operation_queue,
+            ctx
+        );
+
+    return ctx;
+}
+
+const gchar *
+lsq_execute_context_get_temp_file ( LSQExecuteContext *ctx )
+{
+    g_return_val_if_fail( NULL != ctx, NULL );
+
+    if ( NULL == ctx->tempfile )
+    {
+        ctx->tempfile = lsq_archive_request_temp_file( ctx->archive, NULL );
+    }
+
+    return ctx->tempfile;
+}
+
+gboolean
+lsq_execute_context_start ( LSQExecuteContext *ctx )
+{
+    g_return_val_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ), FALSE );
+    g_return_val_if_fail( LSQ_IS_ARCHIVE( ctx->archive ), FALSE );
+    g_return_val_if_fail( NULL != ctx->archive->operation_queue, FALSE );
+
+    /* Only execute when we are the first in the queue
+     * Should the be considered a programming error?
+     */
+    if ( ctx != ctx->archive->operation_queue->data )
+    {
+        return FALSE;
+    }
+
+    return lsq_command_entry_start( ctx->queue, ctx );
+}
+
+guint
+lsq_operation_step_count ( const LSQExecuteContext *ctx )
+{
+    g_return_val_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ), 0 );
+
+    return ctx->queue_size;
+}
+
+guint
+lsq_operation_current_step ( const LSQExecuteContext *ctx )
+{
+    guint count;
+
+    g_return_val_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ), 0 );
+
+    count = lsq_command_entry_queue_size( ctx->queue );
+
+    g_return_val_if_fail( count > ctx->queue_size, 0 );
+
+    return ctx->queue_size - count;
+}
+
+gboolean
+lsq_operation_is_finished (
+        const LSQExecuteContext *ctx,
+        GError **error
+    )
+{
+    g_return_val_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ), FALSE );
+    g_return_val_if_fail( NULL == error || NULL == *error, FALSE );
+
+    switch ( ctx->oper_state )
+    {
+        case LSQ_OPERATION_STATE_ERROR:
+            if ( error )
+            {
+                *error = g_error_copy( ctx->error );
+            }
+        case LSQ_OPERATION_STATE_SUCCES:
+            return TRUE;
+
+        case LSQ_OPERATION_STATE_RUNNING:
+        case LSQ_OPERATION_STATE_PENDING:
+            break;
+    }
+
+    return FALSE;
+}
+
+gboolean
+lsq_operation_get_error (
+        const LSQExecuteContext *ctx,
+        GError **error
+    )
+{
+    g_return_val_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ), FALSE );
+    g_return_val_if_fail( NULL == error || NULL == *error, FALSE );
+
+    switch ( ctx->oper_state )
+    {
+        case LSQ_OPERATION_STATE_ERROR:
+            if ( error )
+            {
+                *error = g_error_copy( ctx->error );
+            }
+            return TRUE;
+
+        case LSQ_OPERATION_STATE_SUCCES:
+        case LSQ_OPERATION_STATE_RUNNING:
+        case LSQ_OPERATION_STATE_PENDING:
+            break;
+    }
+
+    return FALSE;
+}
+
+LSQCommandType
+lsq_operation_get_type ( const LSQExecuteContext *ctx )
+{
+    g_return_val_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ), 0 );
+
+    return ctx->type;
+}
+
+void
+lsq_operation_stop ( LSQExecuteContext *ctx )
+{
+    g_return_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ) );
+}
+
+LSQOperationState
+lsq_operation_get_state ( const LSQExecuteContext *ctx )
+{
+    g_return_val_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ), 0 );
+
+    return ctx->oper_state;
+}
+
+const gchar *
+lsq_operation_get_msg ( const LSQExecuteContext *ctx )
+{
+    g_return_val_if_fail( LSQ_IS_EXECUTE_CONTEXT( ctx ), NULL );
+
+    return NULL;
+}
diff --git a/libsqueeze/execute-context.h b/libsqueeze/execute-context.h
new file mode 100644
index 0000000..e588cfa
--- /dev/null
+++ b/libsqueeze/execute-context.h
@@ -0,0 +1,65 @@
+/*
+ *  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 Library General Public License for more details.
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software 
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+ */
+
+#ifndef __EXECUTE_CONTEXT_H__
+#define __EXECUTE_CONTEXT_H__ 
+
+#include "internal-types.h"
+
+G_BEGIN_DECLS
+
+
+struct _LSQExecuteContext
+{
+    GObject parent;
+
+    LSQCommandEntry *queue;
+    LSQParser *parser;
+    LSQArchive *archive;
+    gchar **files;
+    gchar *directory;
+    LSQCommandType type;
+    guint queue_size;
+    gchar *tempfile;
+    LSQParserContext *ctx;
+    GIOChannel *redir_out;
+    enum {
+        LSQ_EXEC_CTX_STATE_RUNNING = 1<<0,
+        LSQ_EXEC_CTX_STATE_PARSING = 1<<1
+    } exec_state;
+    LSQOperationState oper_state;
+    GError *error;
+};
+
+
+LSQExecuteContext *
+lsq_execute_context_new (
+        LSQCommandEntry *queue,
+        LSQArchive *archive,
+        gchar **files,
+        const gchar *directory,
+        LSQParser *parser,
+        LSQCommandType
+    ) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+const gchar *
+lsq_execute_context_get_temp_file ( LSQExecuteContext *ctx );
+
+gboolean
+lsq_execute_context_start ( LSQExecuteContext *ctx );
+
+G_END_DECLS
+
+#endif /* __EXECUTE_CONTEXT_H__ */
diff --git a/libsqueeze/libsqueeze-mime.h b/libsqueeze/internal-error.h
similarity index 62%
copy from libsqueeze/libsqueeze-mime.h
copy to libsqueeze/internal-error.h
index c963178..6c6eb49 100644
--- a/libsqueeze/libsqueeze-mime.h
+++ b/libsqueeze/internal-error.h
@@ -1,28 +1,34 @@
-/* 
+/*
  *  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 
+ *  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 Library General Public License for more details.
- *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *  along with this program; if not, write to the Free Software 
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_MIME_SUPPORT_H__
-#define __LIBSQUEEZE_MIME_SUPPORT_H__
+#ifndef __INTERNAL_ERROR_H__
+#define __INTERNAL_ERROR_H__ 
+
+G_BEGIN_DECLS
+
+
+#define LSQ_SUPPORT_ERROR lsq_support_error_quark()
+
+typedef enum {
+    LSQ_SUPPORT_ERROR_FAILED
+} LSQSupportError;
 
-typedef struct _LSQMimeSupport LSQMimeSupport;
+GQuark
+lsq_support_error_quark ( void ) G_GNUC_CONST;
 
-const gchar *
-lsq_mime_support_get_comment ( LSQMimeSupport * );
 
-const gchar *
-lsq_mime_support_get_name ( LSQMimeSupport * );
+G_END_DECLS
 
-#endif /* __LIBSQUEEZE_MIME_SUPPORT_H__ */
+#endif /* __INTERNAL_ERROR_H__ */
diff --git a/libsqueeze/internals.h b/libsqueeze/internal-types.h
similarity index 57%
copy from libsqueeze/internals.h
copy to libsqueeze/internal-types.h
index 25cfa2a..a8fe7c9 100644
--- a/libsqueeze/internals.h
+++ b/libsqueeze/internal-types.h
@@ -14,19 +14,27 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-GSList *support_factory_list;
-GSList *lsq_mime_support_list;
-GSList *lsq_opened_archive_list;
-gchar  *lsq_relative_base_uri;
-
-gchar *
-lsq_concat_filenames ( GSList *filenames ) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-
-gchar *
-lsq_concat_iter_filenames (
-        GSList *file_iters,
-        gboolean
-    ) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-
-LSQArchive *
-lsq_opened_archive_get_archive ( gchar *path ) G_GNUC_WARN_UNUSED_RESULT;
+#ifndef __INTERNAL_TYPES_H__
+#define __INTERNAL_TYPES_H__
+
+#include "libsqueeze-types.h"
+
+G_BEGIN_DECLS
+
+typedef struct _LSQParser LSQParser;
+typedef struct _LSQParserContext LSQParserContext;
+
+typedef struct _LSQSupportFactory LSQSupportFactory;
+
+typedef struct _LSQArchiveIterPool LSQArchiveIterPool;
+
+typedef struct _LSQArchiveEntry LSQArchiveEntry;
+
+typedef struct _LSQCommandQueue LSQCommandQueue;
+typedef struct _LSQCommandEntry LSQCommandEntry;
+
+typedef struct _LSQSupportFile LSQSupportFile;
+
+G_END_DECLS
+
+#endif /* __INTERNAL_TYPES_H__ */
diff --git a/libsqueeze/internals.c b/libsqueeze/internals.c
index e3cb072..baa7dbb 100644
--- a/libsqueeze/internals.c
+++ b/libsqueeze/internals.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <stdlib.h>
 #include <glib.h>
 #include <glib-object.h>
@@ -23,20 +25,9 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-#include "support-template.h"
-#include "archive.h"
-#include "archive-iter.h"
-#include "support-factory.h"
-
-#include "libsqueeze-view.h"
-
 #include "internals.h"
 
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
+GSList *lsq_opened_archive_list = NULL;
 
 static gint
 lsq_opened_archives_lookup_archive (
diff --git a/libsqueeze/internals.h b/libsqueeze/internals.h
index 25cfa2a..318a2b8 100644
--- a/libsqueeze/internals.h
+++ b/libsqueeze/internals.h
@@ -14,19 +14,31 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-GSList *support_factory_list;
-GSList *lsq_mime_support_list;
-GSList *lsq_opened_archive_list;
-gchar  *lsq_relative_base_uri;
+#ifndef __INTERNALS_H__
+#define __INTERNALS_H__
+
+#include "libsqueeze-types.h"
+
+G_BEGIN_DECLS
+
+extern GHashTable *lsq_support_info_table;
+extern GHashTable *lsq_support_file_table;
+extern GSList *lsq_opened_archive_list;
 
 gchar *
 lsq_concat_filenames ( GSList *filenames ) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
+#if 0
 gchar *
 lsq_concat_iter_filenames (
         GSList *file_iters,
         gboolean
     ) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+#endif
 
 LSQArchive *
 lsq_opened_archive_get_archive ( gchar *path ) G_GNUC_WARN_UNUSED_RESULT;
+
+G_END_DECLS
+
+#endif /* __INTERNALS_H__ */
diff --git a/libsqueeze/archive.h b/libsqueeze/libsqueeze-archive.h
similarity index 54%
copy from libsqueeze/archive.h
copy to libsqueeze/libsqueeze-archive.h
index 2c2f4f5..a862a49 100644
--- a/libsqueeze/archive.h
+++ b/libsqueeze/libsqueeze-archive.h
@@ -13,8 +13,15 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __ARCHIVE_H__
-#define __ARCHIVE_H__ 
+#ifndef __LIBSQUEEZE_ARCHIVE_H__
+#define __LIBSQUEEZE_ARCHIVE_H__ 
+
+#ifndef __LIBSQUEEZE_H__
+#error This file cannot be included directly. Include <libsqueeze.h> instead.
+#endif
+
+#include "libsqueeze-types.h"
+
 G_BEGIN_DECLS
 
 #define LSQ_TYPE_ARCHIVE lsq_archive_get_type()
@@ -37,59 +44,14 @@ G_BEGIN_DECLS
         G_TYPE_CHECK_CLASS_TYPE ((klass), \
             LSQ_TYPE_ARCHIVE))
 
-enum
-{
-    LSQ_ARCHIVE_PROP_FILENAME = 0,
-    LSQ_ARCHIVE_PROP_MIME_TYPE,
-    LSQ_ARCHIVE_PROP_USER
-};
-
-typedef enum
-{
-    LSQ_ARCHIVE_STATE_IDLE,
-    LSQ_ARCHIVE_STATE_BUSY
-} LSQArchiveState;
-
-typedef struct _LSQArchivePrivate LSQArchivePrivate;
-
-struct _LSQArchivePrivate
-{
-    GFile *file;
-    gchar *content_type;
-
-    LSQSupportTemplate *s_template;
-
-    LSQArchiveState state;
-    const gchar *state_msg;
-};
-
-
-typedef struct _LSQArchive LSQArchive;
-
-struct _LSQArchive
-{
-    GObject parent;
-    LSQArchivePrivate  *priv;
-    LSQArchiveEntry *root_entry;
-    LSQArchiveIterPool *pool;
-    gchar *temp_dir;
-    GSList *monitor_list;
-    struct {
-        guint64 archive_size;
-        guint64 content_size;
-        guint64 n_files;
-        guint64 n_directories;
-    } props;
-};
+#define LSQ_ARCHIVE_GET_CLASS(obj) ( \
+        G_TYPE_INSTANCE_GET_CLASS ((obj), \
+            LSQ_TYPE_ARCHIVE, \
+            LSQArchiveClass)
 
 
 typedef struct _LSQArchiveClass LSQArchiveClass;
 
-struct _LSQArchiveClass
-{
-    GObjectClass parent;
-};
-
 
 GType
 lsq_archive_get_type ( void ) G_GNUC_CONST;
@@ -105,46 +67,49 @@ lsq_archive_exists ( const LSQArchive *archive );
 LSQSupportType
 lsq_archive_get_support_mask ( const LSQArchive *archive );
 
-
-LSQArchive *
-lsq_archive_new ( GFile * ) G_GNUC_WARN_UNUSED_RESULT;
-void
-lsq_archive_state_changed ( const LSQArchive *archive );
-void
-lsq_archive_add_children ( GSList *files );
-gboolean
-lsq_archive_remove_file (
-        LSQArchive *,
-        const gchar *
-    );
-
 GFile *
 lsq_archive_get_file ( const LSQArchive * );
 
-gboolean
-lsq_archive_operate (
-        LSQArchive *archive,
-        LSQCommandType type,
-        gchar **,
-        const gchar *
-    );
-
-LSQCommandOptionPair **
-lsq_archive_get_command_options (
-        LSQArchive *archive,
-        LSQCommandType type
+/*
+ * gint
+ * lsq_new_archive(gchar *path,
+ *				 LSQArchiveType type,
+ *				 gboolean overwrite,
+ *				 LSQArchive &&lp_archive)
+ *
+ * returns:
+ * 0 -- success
+ */
+LSQArchive *
+lsq_new_archive (
+        GFile *,
+	const gchar *mime_type,
+        gboolean overwrite,
+        GError **error
     ) G_GNUC_WARN_UNUSED_RESULT;
 
-const gchar *
-lsq_archive_get_state_msg ( const LSQArchive *archive );
-
-LSQArchiveState
-lsq_archive_get_state ( const LSQArchive *archive );
-
-void
-lsq_archive_refreshed ( const LSQArchive *archive );
+/*
+ * gint 
+ * lsq_open_archive(gchar *path,
+ *				  LSQArchive **lp_archive)
+ *
+ * returns:
+ * 0 -- success
+ */
+LSQArchive *
+lsq_open_archive (
+        GFile *, 
+        GError **error
+    ) G_GNUC_WARN_UNUSED_RESULT;
 
+/*
+ * void 
+ * lsq_close_archive( LSQArchive **lp_archive )
+ *
+ */
+void 
+lsq_close_archive ( LSQArchive *archive );
 
 G_END_DECLS
 
-#endif /* __ARCHIVE_H__ */
+#endif /* __LIBSQUEEZE_ARCHIVE_H__ */
diff --git a/libsqueeze/support-reader.h b/libsqueeze/libsqueeze-error.h
similarity index 63%
copy from libsqueeze/support-reader.h
copy to libsqueeze/libsqueeze-error.h
index 8990494..6524588 100644
--- a/libsqueeze/support-reader.h
+++ b/libsqueeze/libsqueeze-error.h
@@ -13,16 +13,28 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_SUPPORT_READER_H__
-#define __LIBSQUEEZE_SUPPORT_READER_H__ 
+#ifndef __LIBSQUEEZE_ERROR_H__
+#define __LIBSQUEEZE_ERROR_H__ 
+
+#ifndef __LIBSQUEEZE_H__
+#error This file cannot be included directly. Include <libsqueeze.h> instead.
+#endif
 
 G_BEGIN_DECLS
 
 
-LSQSupportFactory *
-lsq_support_reader_parse_file ( const gchar *filename ) G_GNUC_WARN_UNUSED_RESULT;
+#define LSQ_ARCHIVE_ERROR lsq_archive_error_quark()
+
+typedef enum {
+    LSQ_ARCHIVE_ERROR_DETECT,
+    LSQ_ARCHIVE_ERROR_CONTENT_TYPE,
+    LSQ_ARCHIVE_ERROR_OPERATION
+} LSQArchiveError;
+
+GQuark
+lsq_archive_error_quark ( void ) G_GNUC_CONST;
 
 
 G_END_DECLS
-#endif /* __LIBSQUEEZE_SUPPORT_READER_H__ */
 
+#endif /* __LIBSQUEEZE_ERROR_H__ */
diff --git a/libsqueeze/libsqueeze-operate.h b/libsqueeze/libsqueeze-operate.h
new file mode 100644
index 0000000..53d2a58
--- /dev/null
+++ b/libsqueeze/libsqueeze-operate.h
@@ -0,0 +1,215 @@
+/*
+ *  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 Library General Public License for more details.
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software 
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+ */
+
+#ifndef __LIBSQUEEZE_OPERATE_H__
+#define __LIBSQUEEZE_OPERATE_H__ 
+
+#ifndef __LIBSQUEEZE_H__
+#error This file cannot be included directly. Include <libsqueeze.h> instead.
+#endif
+
+#include "libsqueeze-types.h"
+
+G_BEGIN_DECLS
+
+#define LSQ_TYPE_EXECUTE_CONTEXT lsq_execute_context_get_type()
+
+#define LSQ_EXECUTE_CONTEXT(obj) ( \
+        G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+            LSQ_TYPE_EXECUTE_CONTEXT, \
+            LSQExecuteContext))
+
+#define LSQ_IS_EXECUTE_CONTEXT(obj) ( \
+        G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+            LSQ_TYPE_EXECUTE_CONTEXT))
+
+#define LSQ_EXECUTE_CONTEXT_CLASS(klass) ( \
+        G_TYPE_CHECK_CLASS_CAST ((klass), \
+            LSQ_TYPE_EXECUTE_CONTEXT, \
+            LSQExecuteContextClass))
+
+#define LSQ_IS_EXECUTE_CONTEXT_CLASS(klass) ( \
+        G_TYPE_CHECK_CLASS_TYPE ((klass), \
+            LSQ_TYPE_EXECUTE_CONTEXT))
+
+#define LSQ_EXECUTE_CONTEXT_GET_CLASS(obj) ( \
+        G_TYPE_INSTANCE_GET_CLASS ((obj), \
+            LSQ_TYPE_EXECUTE_CONTEXT, \
+            LSQExecuteContextClass)
+
+typedef struct _LSQExecuteContextClass LSQExecuteContextClass;
+
+GType
+lsq_execute_context_get_type ( void ) G_GNUC_CONST;
+
+#define LSQ_TYPE_COMMAND_OPTION           lsq_command_option_get_type(0)
+#define LSQ_COMMAND_OPTION(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION,LSQCommandOption))
+#define LSQ_IS_COMMAND_OPTION(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION))
+
+#define LSQ_TYPE_COMMAND_OPTION_BOOL      lsq_command_option_get_type(1)
+#define LSQ_COMMAND_OPTION_BOOL(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION_BOOL,LSQCommandOptionBool))
+#define LSQ_IS_COMMAND_OPTION_BOOL(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION_BOOL))
+
+#define LSQ_TYPE_COMMAND_OPTION_STRING    lsq_command_option_get_type(2)
+#define LSQ_COMMAND_OPTION_STRING(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION_STRING,LSQCommandOptionString))
+#define LSQ_IS_COMMAND_OPTION_STRING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION_STRING))
+
+#define LSQ_TYPE_COMMAND_OPTION_INT       lsq_command_option_get_type(3)
+#define LSQ_COMMAND_OPTION_INT(obj)       (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION_INT,LSQCommandOptionInt))
+#define LSQ_IS_COMMAND_OPTION_INT(obj)    (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION_INT))
+
+#define LSQ_TYPE_COMMAND_OPTION_UINT      lsq_command_option_get_type(4)
+#define LSQ_COMMAND_OPTION_UINT(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),LSQ_TYPE_COMMAND_OPTION_UINT,LSQCommandOptionUint))
+#define LSQ_IS_COMMAND_OPTION_UINT(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj),LSQ_TYPE_COMMAND_OPTION_UINT))
+
+typedef struct _LSQCommandOptionString  LSQCommandOptionString;
+typedef struct _LSQCommandOptionBool    LSQCommandOptionBool;
+typedef struct _LSQCommandOptionInt     LSQCommandOptionInt;
+typedef struct _LSQCommandOptionUint    LSQCommandOptionUint;
+
+GType
+lsq_command_option_get_type ( guint ) G_GNUC_CONST;
+
+struct _LSQCommandOptionPair
+{
+    GValue value;
+    const LSQCommandOption *option;
+};
+
+struct _LSQCommandOption
+{
+    GTypeInstance parent;
+    const gchar *name;
+    const gchar *flag;
+    const gchar *blurb;
+    GType value_type;
+};
+
+struct _LSQCommandOptionString
+{
+    LSQCommandOption parent;
+
+    const gchar *default_value;
+    const gchar *filter;
+};
+
+struct _LSQCommandOptionBool
+{
+    LSQCommandOption parent;
+
+    gboolean default_value;
+};
+
+struct _LSQCommandOptionInt
+{
+    LSQCommandOption parent;
+
+    gint default_value;
+    gint min_value;
+    gint max_value;
+};
+
+struct _LSQCommandOptionUint
+{
+    LSQCommandOption parent;
+
+    guint default_value;
+    guint min_value;
+    guint max_value;
+};
+
+typedef enum
+{
+    LSQ_ARCHIVE_STATE_IDLE,
+    LSQ_ARCHIVE_STATE_BUSY
+} LSQArchiveState;
+
+typedef enum
+{
+    LSQ_OPERATION_STATE_RUNNING,
+    LSQ_OPERATION_STATE_PENDING,
+    LSQ_OPERATION_STATE_SUCCES,
+    LSQ_OPERATION_STATE_ERROR
+} LSQOperationState;
+
+guint
+lsq_operation_step_count ( const LSQExecuteContext * ) G_GNUC_PURE;
+guint
+lsq_operation_current_step ( const LSQExecuteContext * );
+gboolean
+lsq_operation_is_finished (
+        const LSQExecuteContext *,
+        GError **
+    );
+gboolean
+lsq_operation_get_error (
+        const LSQExecuteContext *,
+        GError **
+    );
+LSQCommandType
+lsq_operation_get_type ( const LSQExecuteContext * ) G_GNUC_PURE;
+void
+lsq_operation_stop ( LSQExecuteContext * );
+LSQOperationState
+lsq_operation_get_state ( const LSQExecuteContext * );
+const gchar *
+lsq_operation_get_msg ( const LSQExecuteContext * );
+
+LSQExecuteContext *
+lsq_archive_operate (
+        LSQArchive *,
+        LSQCommandType,
+        gchar **files,
+        const gchar *directory,
+        const LSQSupportApp *app,
+        GError **
+    ) G_GNUC_WARN_UNUSED_RESULT;
+
+LSQCommandOptionPair **
+lsq_archive_get_command_options (
+        LSQArchive *archive,
+        LSQCommandType type
+    ) G_GNUC_WARN_UNUSED_RESULT;
+
+const gchar *
+lsq_archive_get_state_msg ( const LSQArchive *archive );
+
+LSQArchiveState
+lsq_archive_get_state ( const LSQArchive *archive );
+
+gboolean
+lsq_archive_can_stop ( const LSQArchive *archive );
+
+gboolean
+lsq_archive_stop ( LSQArchive *archive );
+
+LSQExecuteContext *
+lsq_archive_current_operation ( const LSQArchive *archive );
+
+GSList *
+lsq_iter_slist_copy ( GSList * ) G_GNUC_WARN_UNUSED_RESULT;
+
+void
+lsq_iter_slist_free ( GSList * );
+
+void
+lsq_iter_slist_add_children ( GSList *files );
+
+gchar **
+lsq_iter_slist_to_strv ( GSList *list ) G_GNUC_WARN_UNUSED_RESULT;
+
+G_END_DECLS
+
+#endif /* __LIBSQUEEZE_OPERATE_H__ */
diff --git a/libsqueeze/libsqueeze-support.h b/libsqueeze/libsqueeze-support.h
new file mode 100644
index 0000000..dedc7d4
--- /dev/null
+++ b/libsqueeze/libsqueeze-support.h
@@ -0,0 +1,124 @@
+/*
+ *  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 Library General Public License for more details.
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software 
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+ */
+
+#ifndef __LIBSQUEEZE_SUPPORT_H__
+#define __LIBSQUEEZE_SUPPORT_H__
+
+#include "internal-types.h"
+
+G_BEGIN_DECLS
+
+
+#define LSQ_TYPE_SUPPORT_INFO lsq_support_info_get_type()
+
+#define LSQ_SUPPORT_INFO(obj) ( \
+        G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+            LSQ_TYPE_SUPPORT_INFO, \
+            LSQSupportInfo))
+
+#define LSQ_IS_SUPPORT_INFO(obj) ( \
+        G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+            LSQ_TYPE_SUPPORT_INFO))
+
+#define LSQ_SUPPORT_INFO_CLASS(klass) ( \
+        G_TYPE_CHECK_CLASS_CAST ((klass), \
+            LSQ_TYPE_SUPPORT_INFO, \
+            LSQSupportInfoClass))
+
+#define LSQ_IS_SUPPORT_INFO_CLASS(klass) ( \
+        G_TYPE_CHECK_CLASS_TYPE ((klass), \
+            LSQ_TYPE_SUPPORT_INFO))
+
+#define LSQ_SUPPORT_INFO_GET_CLASS(obj) ( \
+        G_TYPE_INSTANCE_GET_CLASS ((obj), \
+            LSQ_TYPE_SUPPORT_INFO, \
+            LSQSupportInfoClass))
+
+
+#define LSQ_TYPE_SUPPORT_APP lsq_support_app_get_type()
+
+#define LSQ_SUPPORT_APP(obj) ( \
+        G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+            LSQ_TYPE_SUPPORT_APP, \
+            LSQSupportApp))
+
+#define LSQ_IS_SUPPORT_APP(obj) ( \
+        G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+            LSQ_TYPE_SUPPORT_APP))
+
+#define LSQ_SUPPORT_APP_CLASS(klass) ( \
+        G_TYPE_CHECK_CLASS_CAST ((klass), \
+            LSQ_TYPE_SUPPORT_APP, \
+            LSQSupportAppClass))
+
+#define LSQ_IS_SUPPORT_APP_CLASS(klass) ( \
+        G_TYPE_CHECK_CLASS_TYPE ((klass), \
+            LSQ_TYPE_SUPPORT_APP))
+
+#define LSQ_SUPPORT_APP_GET_CLASS(obj) ( \
+        G_TYPE_INSTANCE_GET_CLASS ((obj), \
+            LSQ_TYPE_SUPPORT_APP, \
+            LSQSupportAppClass))
+
+
+GType
+lsq_support_info_get_type ( void ) G_GNUC_CONST;
+
+GType
+lsq_support_app_get_type ( void ) G_GNUC_CONST;
+
+
+const LSQSupportInfo *
+lsq_support_info_get ( const gchar *mime_type );
+
+const gchar *
+lsq_support_info_get_contentype ( const LSQSupportInfo *info );
+
+GSList *
+lsq_support_info_get_apps ( const LSQSupportInfo *info ) G_GNUC_WARN_UNUSED_RESULT;
+
+const LSQSupportApp *
+lsq_support_info_get_app_by_id (
+        const LSQSupportInfo *info,
+        const gchar *id
+    );
+
+const gchar *
+lsq_support_app_get_id ( const LSQSupportApp *app );
+
+
+GList *
+lsq_support_info_get_all ( void ) G_GNUC_WARN_UNUSED_RESULT;
+
+GList *
+lsq_support_info_get_all_mime_types ( void ) G_GNUC_WARN_UNUSED_RESULT;
+
+
+const gchar *
+lsq_archive_iter_get_content_type ( const LSQArchiveIter * ) G_GNUC_PURE;
+
+const LSQSupportInfo *
+lsq_archive_get_support_info ( const LSQArchive *archive ) G_GNUC_PURE;
+
+void
+lsq_archive_set_refresh_app (
+        LSQArchive *archive,
+        const LSQSupportApp *app
+    );
+
+
+G_END_DECLS
+
+#endif /* __LIBSQUEEZE_SUPPORT_H__ */
diff --git a/libsqueeze/libsqueeze-types.h b/libsqueeze/libsqueeze-types.h
new file mode 100644
index 0000000..27de943
--- /dev/null
+++ b/libsqueeze/libsqueeze-types.h
@@ -0,0 +1,54 @@
+/*
+ *  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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __LIBSQUEEZE_TYPES_H__
+#define __LIBSQUEEZE_TYPES_H__
+
+G_BEGIN_DECLS
+
+typedef struct _LSQArchive LSQArchive;
+
+typedef struct _LSQArchiveIter LSQArchiveIter;
+
+typedef struct _LSQCommandOptionPair    LSQCommandOptionPair;
+typedef struct _LSQCommandOption        LSQCommandOption;
+
+typedef struct _LSQExecuteContext LSQExecuteContext;
+
+typedef struct _LSQSupportInfo LSQSupportInfo;
+typedef struct _LSQSupportApp LSQSupportApp;
+
+typedef enum
+{
+    LSQ_SUPPORT_FILES    = 1 << 0x0,
+    LSQ_SUPPORT_FOLDERS  = 1 << 0x1,
+    LSQ_SUPPORT_MANY     = 1 << 0x2
+} LSQSupportType;
+
+typedef enum
+{
+    LSQ_COMMAND_TYPE_REFRESH,
+    LSQ_COMMAND_TYPE_EXTRACT,
+    LSQ_COMMAND_TYPE_NEW,
+    LSQ_COMMAND_TYPE_ADD,
+    LSQ_COMMAND_TYPE_REMOVE,
+    LSQ_COMMAND_TYPE_OPEN,
+    LSQ_COMMAND_TYPE_TEST
+} LSQCommandType;
+
+G_END_DECLS
+
+#endif /* __LIBSQUEEZE_TYPES_H__ */
diff --git a/libsqueeze/libsqueeze-view.h b/libsqueeze/libsqueeze-view.h
index fe41776..4812d81 100644
--- a/libsqueeze/libsqueeze-view.h
+++ b/libsqueeze/libsqueeze-view.h
@@ -15,8 +15,27 @@
 
 #ifndef __LIBSQUEEZE_VIEW_H__
 #define __LIBSQUEEZE_VIEW_H__ 
+
+#ifndef __LIBSQUEEZE_H__
+#error This file cannot be included directly. Include <libsqueeze.h> instead.
+#endif
+
+#include "libsqueeze-types.h"
+
 G_BEGIN_DECLS
 
+enum
+{
+    LSQ_ARCHIVE_PROP_FILENAME = 0,
+    LSQ_ARCHIVE_PROP_MIME_TYPE,
+    LSQ_ARCHIVE_PROP_USER
+};
+
+LSQArchiveIter *
+lsq_archive_iter_ref ( LSQArchiveIter *iter );
+void
+lsq_archive_iter_unref ( LSQArchiveIter *iter );
+
 gboolean
 lsq_archive_iter_is_real ( const LSQArchiveIter * ) G_GNUC_PURE;
 
@@ -59,9 +78,6 @@ lsq_archive_iter_get_prop_value (
 const gchar *
 lsq_archive_iter_get_filename ( const LSQArchiveIter * ) G_GNUC_PURE;
 
-const gchar *
-lsq_archive_iter_get_contenttype ( const LSQArchiveIter * ) G_GNUC_PURE;
-
 gchar *
 lsq_archive_iter_get_path ( const LSQArchiveIter *archive ) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
@@ -76,11 +92,6 @@ lsq_archive_get_entry_property_type (
         const LSQArchive *archive,
         guint n
     ) G_GNUC_PURE;
-guint
-lsq_archive_get_entry_property_offset (
-        const LSQArchive *archive,
-        guint n
-    ) G_GNUC_PURE;
 
 const gchar *
 lsq_archive_get_entry_property_name (
@@ -91,24 +102,6 @@ lsq_archive_get_entry_property_name (
 guint
 lsq_archive_n_entry_properties ( const LSQArchive *archive ) G_GNUC_PURE;
 
-guint
-lsq_archive_entry_properties_size ( const LSQArchive *archive ) G_GNUC_PURE;
-
-gboolean
-lsq_archive_can_stop ( const LSQArchive *archive );
-
-gboolean
-lsq_archive_stop ( const LSQArchive *archive );
-
-const gchar *
-lsq_archive_get_status ( const LSQArchive *archive );
-
-GSList *
-lsq_iter_slist_copy ( GSList * ) G_GNUC_WARN_UNUSED_RESULT;
-
-void
-lsq_iter_slist_free ( GSList * );
-
 G_END_DECLS
 
 #endif /* __LIBSQUEEZE_VIEW_H__ */
diff --git a/libsqueeze/libsqueeze.c b/libsqueeze/libsqueeze.c
index 4f54c29..1c8316b 100644
--- a/libsqueeze/libsqueeze.c
+++ b/libsqueeze/libsqueeze.c
@@ -14,8 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -24,13 +25,13 @@
 
 #include <libxfce4util/libxfce4util.h>
 
-#include "libsqueeze.h"
-#include "support-factory.h"
+#include "internals.h"
 #include "support-reader.h"
-#include "archive-iter.h"
+#include "support-file.h"
 #include "archive.h"
+#include "libsqueeze.h"
 
-#include "internals.h"
+GHashTable *lsq_support_file_table;
 
 static void
 lsq_read_squeeze_dir ( const gchar *dir )
@@ -49,21 +50,25 @@ lsq_read_squeeze_dir ( const gchar *dir )
         {
             if ( g_str_has_suffix( filename, ".squeeze" ) )
             {
-                /* see if a file with this name was already loaded.
-                 * skip this file. configuration was overruled
-                 */
-                if ( NULL == g_slist_find_custom( support_factory_list, filename, (GCompareFunc)lsq_suport_factory_compare_filename ) )
+                LSQSupportFile *file;
+                /* see if a file with this name was already loaded. */
+                file = g_hash_table_lookup( lsq_support_file_table, filename );
+                /* skip this file. configuration was overruled. */
+                if ( NULL == file )
                 {
-                    /**
-                     * FIXME: factories should be per-mime-type, not per-template
-                     */
+                    GError *error = NULL;
                     gchar *path = g_build_filename( dir, filename, NULL );
-                    LSQSupportFactory *factory = lsq_support_reader_parse_file( path );
-                    if ( NULL != factory )
+                    file = lsq_support_reader_parse_file( path, &error );
+                    g_free( path );
+                    if ( NULL != file )
+		    {
+                        g_hash_table_insert( lsq_support_file_table, file->filename, file );
+		    }
+		    else
                     {
-                        support_factory_list = g_slist_append( support_factory_list, factory );
+                        g_warning( "%s", error->message );
+                        g_error_free( error );
                     }
-                    g_free( path );
                 }
             }
             filename = g_dir_read_name( data_dir );
@@ -77,50 +82,58 @@ void
 lsq_init ( void )
 {
     gchar *data_squeeze;
+#ifndef NO_XDG_DATA_DIRS
     const gchar * const *system_dirs = g_get_system_data_dirs();
     const gchar *user_dir = g_get_user_data_dir();
+#endif
 
     lsq_datetime_register_type();
 
-    support_factory_list = NULL;
-
     lsq_opened_archive_list = NULL;
 
+    lsq_support_file_table = g_hash_table_new( g_str_hash, g_str_equal );
+
+#ifndef NO_XDG_DATA_DIRS
     data_squeeze = g_build_filename( user_dir, "squeeze", NULL );
     lsq_read_squeeze_dir( data_squeeze );
     g_free( data_squeeze );
+#endif
 
     data_squeeze = g_build_filename( DATADIR, "squeeze", NULL );
     lsq_read_squeeze_dir( data_squeeze );
     g_free( data_squeeze );
 
+#ifndef NO_XDG_DATA_DIRS
     for ( ; NULL != *system_dirs; ++system_dirs )
     {
         data_squeeze = g_build_filename( *system_dirs, "squeeze", NULL );
         lsq_read_squeeze_dir( data_squeeze );
         g_free( data_squeeze );
     }
+#endif
 }
 
 void
 lsq_shutdown ( void )
 {
     g_slist_foreach( lsq_opened_archive_list, (GFunc)lsq_close_archive, NULL );
-    g_slist_foreach( support_factory_list, (GFunc)g_object_unref, NULL );
-    g_slist_free( support_factory_list );
 }
 
 /*
  * XAArchive* lsq_new_archive(gchar *path, LSQArchiveType type, gboolean overwrite)
  *
  */
-gint
-lsq_new_archive ( GFile *file, gboolean overwrite, LSQArchive **lp_archive )
+LSQArchive *
+lsq_new_archive (
+        GFile *file,
+        const gchar *mime_type,
+        gboolean overwrite,
+        GError **error
+    )
 {
     LSQArchive *archive;
 
-    g_return_val_if_fail( G_IS_FILE( file ), 1 );
-    g_return_val_if_fail( NULL != lp_archive, 1 );
+    g_return_val_if_fail( G_IS_FILE( file ), NULL );
 
     if ( TRUE == overwrite )
     {
@@ -129,17 +142,12 @@ lsq_new_archive ( GFile *file, gboolean overwrite, LSQArchive **lp_archive )
 
     if ( TRUE == g_file_query_exists( file, NULL ) )
     {
-        (*lp_archive) = NULL;
-        return 1;
+        return NULL;
     }
 
-    archive = lsq_archive_new( file );
-    (*lp_archive) = archive;
-    if( NULL == archive )
-    {
-        return 1;
-    }
-    return 0;
+    archive = lsq_archive_new( file, mime_type, error );
+
+    return archive;
 }
 
 /*
@@ -147,51 +155,36 @@ lsq_new_archive ( GFile *file, gboolean overwrite, LSQArchive **lp_archive )
  * XAArchive* lsq_open_archive(gchar *path)
  *
  */
-gint
-lsq_open_archive ( GFile *file, LSQArchive **lp_archive )
+LSQArchive *
+lsq_open_archive (
+        GFile *file,
+        GError **error
+    )
 {
     LSQArchive *archive = NULL; /*lsq_opened_archive_get_archive(path); */
 
-    g_return_val_if_fail( G_IS_FILE( file ), 1 );
-    g_return_val_if_fail( NULL != lp_archive, 1 );
+    g_return_val_if_fail( G_IS_FILE( file ), NULL );
 
     if ( FALSE == g_file_query_exists( file, NULL ) )
     {
-        (*lp_archive) = NULL;
-        return 1;
+        return NULL;
     }
 
     if ( NULL == archive )
     {
-        archive = lsq_archive_new( file );
+        archive = lsq_archive_new( file, NULL, error );
         if ( NULL != archive )
         {
             /* FIXME: Shouldn't this be part of lsq_archive_new? */
             lsq_opened_archive_list = g_slist_prepend( lsq_opened_archive_list, archive );
         }
     }
-    (*lp_archive) = archive;
-    if( NULL == archive )
-    {
-        return 1;
-    }
-    return 0;
-}
 
-gboolean
-lsq_is_supported ( const gchar *filename )
-{
-    return FALSE;
-}
-
-GSList *
-lsq_get_supported_mime_types ( LSQCommandType type )
-{
-    return NULL;
+    return archive;
 }
 
 gchar **
-lsq_iter_list_to_strv ( GSList *list )
+lsq_iter_slist_to_strv ( GSList *list )
 {
     GSList *iter;
     guint i;
@@ -214,4 +207,3 @@ lsq_iter_list_to_strv ( GSList *list )
 
     return strv;
 }
-
diff --git a/libsqueeze/libsqueeze.h b/libsqueeze/libsqueeze.h
index 287c729..3a60efb 100644
--- a/libsqueeze/libsqueeze.h
+++ b/libsqueeze/libsqueeze.h
@@ -17,16 +17,18 @@
 #ifndef __LIBSQUEEZE_H__
 #define __LIBSQUEEZE_H__
 
-#include <libxfce4util/libxfce4util.h>
-
-#include <libsqueeze/command-option.h>
-#include <libsqueeze/support-template.h>
-#include <libsqueeze/archive-iter-pool.h>
-#include <libsqueeze/archive.h>
-#include <libsqueeze/archive-iter.h>
-#include <libsqueeze/datetime.h>
+/*
+ * This is the only file which should be included by an application.
+ * All requered header files should be includeed into this file.
+ */
 
-#include <libsqueeze/libsqueeze-view.h>
+#include "libsqueeze-types.h"
+#include "libsqueeze-error.h"
+#include "libsqueeze-archive.h"
+#include "libsqueeze-operate.h"
+#include "libsqueeze-view.h"
+#include "libsqueeze-support.h"
+#include "datetime.h"
 
 G_BEGIN_DECLS
 
@@ -42,54 +44,6 @@ void lsq_init ( void );
  */
 void lsq_shutdown ( void );
 
-/*
- * gint
- * lsq_new_archive(gchar *path,
- *				 LSQArchiveType type,
- *				 gboolean overwrite,
- *				 LSQArchive &&lp_archive)
- *
- * returns:
- * 0 -- success
- */
-gint
-lsq_new_archive (
-        GFile *,
-        gboolean overwrite,
-        LSQArchive **lp_archive
-    );
-
-/*
- * gint 
- * lsq_open_archive(gchar *path,
- *				  LSQArchive **lp_archive)
- *
- * returns:
- * 0 -- success
- */
-gint
-lsq_open_archive (
-        GFile *, 
-        LSQArchive **lp_archive
-    );
-
-/*
- * void 
- * lsq_close_archive( LSQArchive **lp_archive )
- *
- */
-void 
-lsq_close_archive ( LSQArchive *archive );
-
-GSList *
-lsq_get_supported_mime_types ( LSQCommandType type );
-
-gboolean
-lsq_is_supported ( const gchar *filename );
-
-gchar **
-lsq_iter_list_to_strv ( GSList *list ) G_GNUC_WARN_UNUSED_RESULT;
-
 G_END_DECLS
 
 #endif /* __LIBSQUEEZE_H__ */
diff --git a/libsqueeze/parser-context.c b/libsqueeze/parser-context.c
index 9e38b44..488e6a5 100644
--- a/libsqueeze/parser-context.c
+++ b/libsqueeze/parser-context.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <glib.h>
 #include <glib-object.h> 
 #include <signal.h>
@@ -24,8 +26,6 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-
-#include "archive.h"
 #include "parser-context.h"
 
 enum {
diff --git a/libsqueeze/parser-context.h b/libsqueeze/parser-context.h
index 96a7e4b..5057094 100644
--- a/libsqueeze/parser-context.h
+++ b/libsqueeze/parser-context.h
@@ -13,8 +13,10 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_PARSER_CONTEXT_H__
-#define __LIBSQUEEZE_PARSER_CONTEXT_H__ 
+#ifndef __PARSER_CONTEXT_H__
+#define __PARSER_CONTEXT_H__ 
+
+#include "internal-types.h"
 
 G_BEGIN_DECLS
 
@@ -38,7 +40,10 @@ G_BEGIN_DECLS
         G_TYPE_CHECK_CLASS_TYPE ((klass), \
             LSQ_TYPE_PARSER_CONTEXT))
 
-typedef struct _LSQParserContext LSQParserContext;
+#define LSQ_PARSER_CONTEXT_GET_CLASS(obj) ( \
+        G_TYPE_INSTANCE_GET_CLASS ((obj), \
+            LSQ_TYPE_PARSER_CONTEXT, \
+            LSQParserContextClass)
 
 struct _LSQParserContext
 {
@@ -74,7 +79,7 @@ gboolean
 lsq_parser_context_is_good ( LSQParserContext * ) G_GNUC_PURE;
 
 gboolean
-lsq_parser_context_read_again ( LSQParserContext *) G_GNUC_PURE;
+lsq_parser_context_read_again ( LSQParserContext * ) G_GNUC_PURE;
 
 void
 lsq_parser_context_set_channel (
@@ -84,4 +89,4 @@ lsq_parser_context_set_channel (
 
 G_END_DECLS
 
-#endif /* __LIBSQUEEZE_PARSER_CONTEXT_H__ */
+#endif /* __PARSER_CONTEXT_H__ */
diff --git a/libsqueeze/parser.c b/libsqueeze/parser.c
index e670ab6..b689409 100644
--- a/libsqueeze/parser.c
+++ b/libsqueeze/parser.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <glib.h>
 #include <glib-object.h> 
 #include <signal.h>
@@ -24,7 +26,6 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-
 #include "parser-context.h"
 #include "parser.h"
 
diff --git a/libsqueeze/parser.h b/libsqueeze/parser.h
index 2797a71..27ef080 100644
--- a/libsqueeze/parser.h
+++ b/libsqueeze/parser.h
@@ -13,8 +13,10 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_PARSER_H__
-#define __LIBSQUEEZE_PARSER_H__ 
+#ifndef __PARSER_H__
+#define __PARSER_H__ 
+
+#include "internal-types.h"
 
 G_BEGIN_DECLS
 
@@ -44,10 +46,6 @@ G_BEGIN_DECLS
             LSQParserClass))
 
 
-#if 0
-typedef struct _LSQParser LSQParser;
-#endif
-
 struct _LSQParser
 {
     GObject parent;
@@ -127,5 +125,4 @@ lsq_parser_set_datetime_format (
 
 G_END_DECLS
 
-#endif /* __LIBSQUEEZE_PARSER_H__ */
-
+#endif /* __PARSER_H__ */
diff --git a/libsqueeze/pcre-parser.c b/libsqueeze/pcre-parser.c
index 72151f1..9415246 100644
--- a/libsqueeze/pcre-parser.c
+++ b/libsqueeze/pcre-parser.c
@@ -26,11 +26,10 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-#include "archive-iter.h"
 #include "parser-context.h"
 #include "parser.h"
+#include "archive-iter.h"
 #include "pcre-parser.h"
-#include "archive.h"
 
 typedef struct _type_parser type_parser;
 typedef struct _LSQPcreParserContext LSQPcreParserContext;
diff --git a/libsqueeze/pcre-parser.h b/libsqueeze/pcre-parser.h
index 3be7dee..6410de9 100644
--- a/libsqueeze/pcre-parser.h
+++ b/libsqueeze/pcre-parser.h
@@ -13,8 +13,10 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_PCRE_PARSER_H__
-#define __LIBSQUEEZE_PCRE_PARSER_H__ 
+#ifndef __PCRE_PARSER_H__
+#define __PCRE_PARSER_H__ 
+
+#include "internal-types.h"
 
 G_BEGIN_DECLS
 
@@ -59,4 +61,4 @@ lsq_pcre_parser_new (
 
 G_END_DECLS
 
-#endif /* __LIBSQUEEZE_PCRE_PARSER_H__ */
+#endif /* __PCRE_PARSER_H__ */
diff --git a/libsqueeze/scanf-parser.c b/libsqueeze/scanf-parser.c
index a700eb5..d2c2db6 100644
--- a/libsqueeze/scanf-parser.c
+++ b/libsqueeze/scanf-parser.c
@@ -14,7 +14,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -25,11 +27,10 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "libsqueeze.h"
-#include "archive-iter.h"
 #include "parser-context.h"
 #include "parser.h"
+#include "archive-iter.h"
 #include "scanf-parser.h"
-#include "archive.h"
 
 typedef struct _parse_part parse_part;
 typedef struct _LSQScanfParserContext LSQScanfParserContext;
@@ -543,7 +544,7 @@ skip_datetime (
         return 0;
     }
 
-    if ( ( ptr - str ) > lng )
+    if ( (guint)( ptr - str ) > lng )
     {
         return 0;
     }
@@ -922,7 +923,7 @@ parse_datetime (
         return 0;
     }
 
-    if ( ( ptr - str ) > lng )
+    if ( (guint)( ptr - str ) > lng )
     {
         return 0;
     }
diff --git a/libsqueeze/scanf-parser.h b/libsqueeze/scanf-parser.h
index 3e19a7c..09f3176 100644
--- a/libsqueeze/scanf-parser.h
+++ b/libsqueeze/scanf-parser.h
@@ -13,8 +13,10 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_SCANF_PARSER_H__
-#define __LIBSQUEEZE_SCANF_PARSER_H__ 
+#ifndef __SCANF_PARSER_H__
+#define __SCANF_PARSER_H__ 
+
+#include "internal-types.h"
 
 G_BEGIN_DECLS
 
@@ -56,5 +58,4 @@ lsq_scanf_parser_new ( const gchar * ) G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS
 
-#endif /* __LIBSQUEEZE_SCANF_PARSER_H__ */
-
+#endif /* __SCANF_PARSER_H__ */
diff --git a/libsqueeze/support-app.c b/libsqueeze/support-app.c
new file mode 100644
index 0000000..d40e082
--- /dev/null
+++ b/libsqueeze/support-app.c
@@ -0,0 +1,157 @@
+/* 
+ *  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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-object.h> 
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <gio/gio.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "libsqueeze.h"
+#include "support-file.h"
+#include "parser.h"
+#include "support-app.h"
+
+struct _LSQSupportAppClass
+{
+    GObjectClass parent;
+};
+
+G_DEFINE_TYPE ( LSQSupportApp, lsq_support_app, G_TYPE_OBJECT );
+
+static void
+lsq_support_app_class_init ( LSQSupportAppClass *klass )
+{
+}
+
+static void
+lsq_support_app_init ( LSQSupportApp *self )
+{
+}
+
+
+LSQSupportApp *
+lsq_support_app_new ( LSQSupportFile *file )
+{
+    LSQSupportApp *app;
+
+    g_return_val_if_fail( LSQ_IS_SUPPORT_FILE( file ), NULL );
+
+    app = g_object_new( LSQ_TYPE_SUPPORT_APP, NULL );
+
+    app->file = file;
+    app->id = file->filename;
+
+    return app;
+}
+
+const gchar *
+lsq_support_app_get_id ( const LSQSupportApp *app )
+{
+    return app->id;
+}
+
+gint
+lsq_support_app_compare_id (
+        const LSQSupportApp *app,
+        const gchar *id
+    )
+{
+    return strcmp( app->id, id );
+}
+
+
+GType
+lsq_support_app_get_property_type (
+        const LSQSupportApp *app,
+        guint nr
+    )
+{
+#ifdef DEBUG
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( app ), G_TYPE_NONE );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_FILE( app->file ), G_TYPE_NONE );
+    g_return_val_if_fail( app->file->n_properties > nr, G_TYPE_NONE );
+    g_return_val_if_fail( LSQ_IS_PARSER( app->file->parser ), G_TYPE_NONE);
+#endif
+    return lsq_parser_get_property_type( app->file->parser, nr );
+}
+
+guint
+lsq_support_app_get_property_offset (
+        const LSQSupportApp *app,
+        guint nr
+    )
+{
+#ifdef DEBUG
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( app ), 0 );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_FILE( app->file ), 0 );
+    g_return_val_if_fail( app->file->n_properties > nr, 0 );
+    g_return_val_if_fail( LSQ_IS_PARSER( app->file->parser ), 0 );
+#endif
+    return lsq_parser_get_property_offset( app->file->parser, nr );
+}
+
+const gchar *
+lsq_support_app_get_property_name (
+        const LSQSupportApp *app,
+        guint nr
+    )
+{
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( app ), NULL );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_FILE( app->file ), NULL );
+    g_return_val_if_fail( app->file->n_properties > nr, NULL );
+
+    return app->file->property_names[nr];
+}
+
+guint
+lsq_support_app_get_n_properties ( const LSQSupportApp *app )
+{
+    guint n_props;
+
+#ifdef DEBUG
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( app ), 0 );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_FILE( app->file ), 0 );
+    g_return_val_if_fail( LSQ_IS_PARSER( app->file->parser ), 0 );
+#endif
+
+    n_props = lsq_parser_n_properties( app->file->parser );
+
+    if ( app->file->n_properties > n_props )
+    {
+        n_props = app->file->n_properties;
+    }
+    return n_props;
+}
+
+guint
+lsq_support_app_get_properties_size ( const LSQSupportApp *app )
+{
+#ifdef DEBUG
+    g_return_val_if_fail( LSQ_IS_SUPPORT_APP( app ), 0 );
+    g_return_val_if_fail( LSQ_IS_SUPPORT_FILE( app->file ), 0 );
+    g_return_val_if_fail( LSQ_IS_PARSER( app->file->parser ), 0 );
+#endif
+    return lsq_parser_get_properties_size( app->file->parser );
+}
diff --git a/libsqueeze/support-app.h b/libsqueeze/support-app.h
new file mode 100644
index 0000000..1687f04
--- /dev/null
+++ b/libsqueeze/support-app.h
@@ -0,0 +1,76 @@
+/*
+ *  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 Library General Public License for more details.
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software 
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+ */
+
+#ifndef __SUPPORT_APP_H__
+#define __SUPPORT_APP_H__
+
+#include "internal-types.h"
+
+G_BEGIN_DECLS
+
+
+struct _LSQSupportApp
+{
+    GObject parent;
+
+    const gchar *id;
+
+    LSQSupportFile *file;
+    LSQSupportInfo *support_info;
+
+    LSQCommandQueue    *new_cmd_queue;
+    LSQCommandQueue    *add_cmd_queue;
+    LSQCommandQueue    *remove_cmd_queue;
+    LSQCommandQueue    *extract_cmd_queue;
+    LSQCommandQueue    *refresh_cmd_queue;
+};
+
+typedef struct _LSQSupportAppClass LSQSupportAppClass;
+
+
+LSQSupportApp *
+lsq_support_app_new ( LSQSupportFile *file );
+
+gint
+lsq_support_app_compare_id (
+        const LSQSupportApp *app,
+        const gchar *id
+    );
+
+
+GType
+lsq_support_app_get_property_type (
+        const LSQSupportApp *app,
+        guint n
+    ) G_GNUC_PURE;
+guint
+lsq_support_app_get_property_offset (
+        const LSQSupportApp *app,
+        guint n
+    ) G_GNUC_PURE;
+const gchar *
+lsq_support_app_get_property_name (
+        const LSQSupportApp *app,
+        guint n
+    ) G_GNUC_PURE;
+guint
+lsq_support_app_get_n_properties ( const LSQSupportApp *app) G_GNUC_PURE;
+guint
+lsq_support_app_get_properties_size ( const LSQSupportApp *app ) G_GNUC_PURE;
+
+
+G_END_DECLS
+
+#endif /* __SUPPORT_APP_H__ */
diff --git a/libsqueeze/support-factory.c b/libsqueeze/support-factory.c
deleted file mode 100644
index 1ae93b5..0000000
--- a/libsqueeze/support-factory.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* 
- *  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 Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-#include <string.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib-object.h> 
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <gio/gio.h>
-
-#include <libxfce4util/libxfce4util.h>
-
-#include "libsqueeze.h"
-#include "archive-iter.h"
-#include "archive-tempfs.h"
-#include "support-factory.h"
-#include "archive.h"
-#include "internals.h"
-
-static void
-lsq_support_factory_finalize ( GObject *object );
-
-G_DEFINE_TYPE ( LSQSupportFactory, lsq_support_factory, G_TYPE_OBJECT );
-
-static void
-lsq_support_factory_class_init ( LSQSupportFactoryClass *support_factory_class )
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(support_factory_class);
-
-    object_class->finalize = lsq_support_factory_finalize;
-}
-
-static void
-lsq_support_factory_init ( LSQSupportFactory *support_factory )
-{
-}
-
-/**
- * lsq_support_factory_finalize:
- *
- * @object: LSQSupportFactory object
- *
- */
-static void
-lsq_support_factory_finalize ( GObject *object )
-{
-    LSQSupportFactory *factory = LSQ_SUPPORT_FACTORY(object);
-
-    g_free( factory->filename );
-    g_free( factory->id );
-    g_slist_free( factory->mime_support );
-
-    G_OBJECT_CLASS(lsq_support_factory_parent_class)->finalize( object );
-}
-
-static gint
-lsq_lookup_mime_support ( gconstpointer a, gconstpointer b )
-{
-    return 1;
-}
-
-void
-lsq_support_factory_add_template ( LSQSupportFactory *factory, LSQSupportTemplate *s_template )
-{
-    GSList *result;
-   
-    g_return_if_fail( LSQ_IS_SUPPORT_FACTORY( factory ) );
-    g_return_if_fail( NULL != s_template );
-
-    result = g_slist_find_custom( lsq_mime_support_list, s_template, lsq_lookup_mime_support );
-    if ( NULL == result )
-    {
-        factory->mime_support = g_slist_prepend( factory->mime_support, s_template );
-        lsq_mime_support_list = g_slist_prepend( lsq_mime_support_list, s_template );
-    }
-}
-
-gint
-lsq_suport_factory_compare_filename ( const LSQSupportFactory *factory, const gchar *filename )
-{
-    g_return_val_if_fail( LSQ_IS_SUPPORT_FACTORY( factory ), 1 );
-    g_return_val_if_fail( NULL != filename, 1 );
-
-    return strcmp( factory->filename, filename );
-}
-
diff --git a/libsqueeze/support-factory.h b/libsqueeze/support-factory.h
deleted file mode 100644
index 63fc87c..0000000
--- a/libsqueeze/support-factory.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __LIBSQUEEZE_SUPPORT_FACTORY_H__
-#define __LIBSQUEEZE_SUPPORT_FACTORY_H__
-
-#define LSQ_TYPE_SUPPORT_FACTORY lsq_support_factory_get_type()
-
-#define LSQ_SUPPORT_FACTORY(obj) ( \
-        G_TYPE_CHECK_INSTANCE_CAST ((obj), \
-            LSQ_TYPE_SUPPORT_FACTORY, \
-            LSQSupportFactory))
-
-#define LSQ_IS_SUPPORT_FACTORY(obj) ( \
-        G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
-            LSQ_TYPE_SUPPORT_FACTORY))
-
-#define LSQ_SUPPORT_FACTORY_CLASS(klass) ( \
-        G_TYPE_CHECK_CLASS_CAST ((klass), \
-            LSQ_TYPE_SUPPORT_FACTORY, \
-            LSQSupportFactoryClass))
-
-#define LSQ_IS_SUPPORT_FACTORY_CLASS(klass) ( \
-        G_TYPE_CHECK_CLASS_TYPE ((klass), \
-            LSQ_TYPE_SUPPORT_FACTORY))
-
-
-typedef struct _LSQSupportFactory LSQSupportFactory;
-
-struct _LSQSupportFactory
-{
-    GObject parent;
-    gchar *filename;
-    gchar *id;
-    GSList *mime_support;
-};
-
-typedef struct _LSQSupportFactoryClass LSQSupportFactoryClass;
-
-struct _LSQSupportFactoryClass
-{
-    GObjectClass parent;
-};
-
-GType
-lsq_support_factory_get_type ( void ) G_GNUC_CONST;
-void
-lsq_support_factory_init_archive (
-        LSQSupportFactory *builder,
-        LSQArchive *archive
-    );
-void
-lsq_support_factory_add_template (
-        LSQSupportFactory *factory,
-        LSQSupportTemplate *s_template
-    );
-gint
-lsq_suport_factory_compare_filename (
-        const LSQSupportFactory *factory,
-        const gchar *filename
-    ) G_GNUC_PURE;
-
-#endif /* __LIBSQUEEZE_SUPPORT_FACTORY_H__ */
diff --git a/libsqueeze/libsqueeze-mime.h b/libsqueeze/support-file.c
similarity index 57%
rename from libsqueeze/libsqueeze-mime.h
rename to libsqueeze/support-file.c
index c963178..afc3d1d 100644
--- a/libsqueeze/libsqueeze-mime.h
+++ b/libsqueeze/support-file.c
@@ -14,15 +14,35 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef __LIBSQUEEZE_MIME_SUPPORT_H__
-#define __LIBSQUEEZE_MIME_SUPPORT_H__
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-object.h> 
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <gio/gio.h>
 
-typedef struct _LSQMimeSupport LSQMimeSupport;
+#include <libxfce4util/libxfce4util.h>
 
-const gchar *
-lsq_mime_support_get_comment ( LSQMimeSupport * );
+#include "support-file.h"
 
-const gchar *
-lsq_mime_support_get_name ( LSQMimeSupport * );
+struct _LSQSupportFileClass
+{
+    GObjectClass parent;
+};
 
-#endif /* __LIBSQUEEZE_MIME_SUPPORT_H__ */
+G_DEFINE_TYPE ( LSQSupportFile, lsq_support_file, G_TYPE_OBJECT );
+
+static void
+lsq_support_file_class_init ( LSQSupportFileClass *klass )
+{
+}
+
+static void
+lsq_support_file_init ( LSQSupportFile *self )
+{
+}
diff --git a/libsqueeze/scanf-parser.h b/libsqueeze/support-file.h
similarity index 51%
copy from libsqueeze/scanf-parser.h
copy to libsqueeze/support-file.h
index 3e19a7c..13c111d 100644
--- a/libsqueeze/scanf-parser.h
+++ b/libsqueeze/support-file.h
@@ -13,48 +13,57 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_SCANF_PARSER_H__
-#define __LIBSQUEEZE_SCANF_PARSER_H__ 
+#ifndef __SUPPORT_FILE_H__
+#define __SUPPORT_FILE_H__
+
+#include "internal-types.h"
 
 G_BEGIN_DECLS
 
-#define LSQ_TYPE_SCANF_PARSER lsq_scanf_parser_get_type()
 
-#define LSQ_SCANF_PARSER(obj) ( \
+#define LSQ_TYPE_SUPPORT_FILE lsq_support_file_get_type()
+
+#define LSQ_SUPPORT_FILE(obj) ( \
         G_TYPE_CHECK_INSTANCE_CAST ((obj), \
-            LSQ_TYPE_SCANF_PARSER, \
-            LSQScanfParser))
+            LSQ_TYPE_SUPPORT_FILE, \
+            LSQSupportFile))
 
-#define LSQ_IS_SCANF_PARSER(obj) ( \
+#define LSQ_IS_SUPPORT_FILE(obj) ( \
         G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
-            LSQ_TYPE_SCANF_PARSER))
+            LSQ_TYPE_SUPPORT_FILE))
 
-#define LSQ_SCANF_PARSER_CLASS(klass) ( \
+#define LSQ_SUPPORT_FILE_CLASS(klass) ( \
         G_TYPE_CHECK_CLASS_CAST ((klass), \
-            LSQ_TYPE_SCANF_PARSER, \
-            LSQScanfParserClass))
+            LSQ_TYPE_SUPPORT_FILE, \
+            LSQSupportFileClass))
 
-#define LSQ_IS_SCANF_PARSER_CLASS(klass) ( \
+#define LSQ_IS_SUPPORT_FILE_CLASS(klass) ( \
         G_TYPE_CHECK_CLASS_TYPE ((klass), \
-            LSQ_TYPE_SCANF_PARSER))
+            LSQ_TYPE_SUPPORT_FILE))
 
-#define LSQ_SCANF_PARSER_GET_CLASS(obj) ( \
+#define LSQ_SUPPORT_FILE_GET_CLASS(obj) ( \
         G_TYPE_INSTANCE_GET_CLASS ((obj), \
-            LSQ_TYPE_SCANF_PARSER, \
-            LSQScanfParserClass))
+            LSQ_TYPE_SUPPORT_FILE, \
+            LSQSupportFileClass))
 
+struct _LSQSupportFile
+{
+    GObject parent;
 
-typedef struct _LSQScanfParser LSQScanfParser;
+    gchar *filename;
+    gchar *display_name;
 
-typedef struct _LSQScanfParserClass LSQScanfParserClass;
+    guint       n_properties;
+    gchar     **property_names;
+    LSQParser  *parser;
+};
+
+typedef struct _LSQSupportFileClass LSQSupportFileClass;
 
 GType
-lsq_scanf_parser_get_type ( void ) G_GNUC_CONST;
+lsq_support_file_get_type ( void ) G_GNUC_CONST;
 
-LSQParser *
-lsq_scanf_parser_new ( const gchar * ) G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS
 
-#endif /* __LIBSQUEEZE_SCANF_PARSER_H__ */
-
+#endif /* __SUPPORT_FILE_H__ */
diff --git a/libsqueeze/support-info.c b/libsqueeze/support-info.c
new file mode 100644
index 0000000..50fc63c
--- /dev/null
+++ b/libsqueeze/support-info.c
@@ -0,0 +1,165 @@
+/* 
+ *  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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-object.h> 
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <gio/gio.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "libsqueeze.h"
+#include "internals.h"
+#include "support-app.h"
+#include "support-info.h"
+
+struct _LSQSupportInfo
+{
+    GObject parent;
+
+    gchar *contenttype;
+    GSList *apps;
+};
+
+struct _LSQSupportInfoClass
+{
+    GObjectClass parent;
+};
+
+G_DEFINE_TYPE ( LSQSupportInfo, lsq_support_info, G_TYPE_OBJECT );
+
+GHashTable *lsq_support_info_table;
+
+static void
+lsq_support_info_class_init ( LSQSupportInfoClass *klass )
+{
+    lsq_support_info_table = g_hash_table_new( g_str_hash, g_str_equal );
+}
+
+static void
+lsq_support_info_init ( LSQSupportInfo *self )
+{
+}
+
+
+LSQSupportInfo *
+lsq_support_info_new ( const gchar *contenttype )
+{
+    LSQSupportInfo *info;
+
+    g_return_val_if_fail( NULL != contenttype, NULL );
+
+    info = g_hash_table_lookup( lsq_support_info_table, contenttype );
+
+    if ( NULL == info )
+    {
+        info = g_object_new( LSQ_TYPE_SUPPORT_INFO, NULL );
+
+        info->contenttype = g_strdup( contenttype );
+
+        g_hash_table_insert( lsq_support_info_table, info->contenttype, info );
+    }
+
+    return info;
+}
+
+const LSQSupportInfo *
+lsq_support_info_get ( const gchar *contenttype )
+{
+    gpointer info;
+
+    g_return_val_if_fail( NULL != contenttype, NULL );
+
+    info = g_hash_table_lookup( lsq_support_info_table, contenttype );
+
+    if ( NULL != info )
+    {
+        return LSQ_SUPPORT_INFO( info );
+    }
+
+    return NULL;
+}
+
+const gchar *
+lsq_support_info_get_contentype ( const LSQSupportInfo *info )
+{
+    return info->contenttype;
+}
+
+GSList *
+lsq_support_info_get_apps ( const LSQSupportInfo *info )
+{
+    return g_slist_copy( info->apps );
+}
+
+static gint
+compare_id ( gconstpointer a, gconstpointer b )
+{
+    return lsq_support_app_compare_id ( a, b );
+}
+
+const LSQSupportApp *
+lsq_support_info_get_app_by_id (
+        const LSQSupportInfo *info,
+        const gchar *id
+    )
+{
+    GSList *element;
+
+    g_return_val_if_fail( LSQ_IS_SUPPORT_INFO( info ), NULL );
+
+    element = g_slist_find_custom( info->apps, id, compare_id );
+
+    if ( NULL != element )
+    {
+        return LSQ_SUPPORT_APP( element->data );
+    }
+
+    return NULL;
+}
+
+void
+lsq_support_info_add_app (
+        LSQSupportInfo *info,
+        LSQSupportApp *app
+    )
+{
+    g_return_if_fail( LSQ_IS_SUPPORT_INFO( info ) );
+    g_return_if_fail( LSQ_IS_SUPPORT_APP( app ) );
+
+    /* shouldn't this append? That way the use directory is added first and will be preferred */
+    info->apps = g_slist_prepend( info->apps, app );
+}
+
+
+GList *
+lsq_support_info_get_all ( void )
+{
+    return g_hash_table_get_values( lsq_support_info_table );
+}
+
+GList *
+lsq_support_info_get_all_mime_types ( void )
+{
+    return g_hash_table_get_values( lsq_support_info_table );
+}
diff --git a/libsqueeze/support-reader.h b/libsqueeze/support-info.h
similarity index 69%
copy from libsqueeze/support-reader.h
copy to libsqueeze/support-info.h
index 8990494..ac8a25a 100644
--- a/libsqueeze/support-reader.h
+++ b/libsqueeze/support-info.h
@@ -13,16 +13,27 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_SUPPORT_READER_H__
-#define __LIBSQUEEZE_SUPPORT_READER_H__ 
+#ifndef __SUPPORT_INFO_H__
+#define __SUPPORT_INFO_H__
+
+#include "libsqueeze-types.h"
 
 G_BEGIN_DECLS
 
 
-LSQSupportFactory *
-lsq_support_reader_parse_file ( const gchar *filename ) G_GNUC_WARN_UNUSED_RESULT;
+typedef struct _LSQSupportInfoClass LSQSupportInfoClass;
+
+
+LSQSupportInfo *
+lsq_support_info_new ( const gchar *contentype );
+
+void
+lsq_support_info_add_app (
+        LSQSupportInfo *info,
+        LSQSupportApp *app
+    );
 
 
 G_END_DECLS
-#endif /* __LIBSQUEEZE_SUPPORT_READER_H__ */
 
+#endif /* __SUPPORT_INFO_H__ */
diff --git a/libsqueeze/support-reader.c b/libsqueeze/support-reader.c
index 7d40535..13adf99 100644
--- a/libsqueeze/support-reader.c
+++ b/libsqueeze/support-reader.c
@@ -14,7 +14,9 @@
  *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -25,11 +27,11 @@
 #include <gio/gio.h>
 #include <libxfce4util/libxfce4util.h>
 
-#include "libsqueeze.h"
-#include "support-factory.h"
-#include "archive-iter.h"
-#include "archive.h"
-#include "parser-context.h"
+#include "internal-error.h"
+#include "support-file.h"
+#include "support-app.h"
+#include "support-info.h"
+#include "command-option.h"
 #include "parser.h"
 #include "scanf-parser.h"
 #ifdef HAVE_PCRE
@@ -38,32 +40,28 @@
 #include "command-queue.h"
 #include "support-reader.h"
 
-#include "internals.h"
-
 /**
  * lsq_support_reader_parse_file:
  *
  * @filename: The filename that should be parsed.
- *
- * Returns: a new LSQSupportFactory object.
  */
-LSQSupportFactory *
-lsq_support_reader_parse_file ( const gchar *filename )
+LSQSupportFile *
+lsq_support_reader_parse_file (
+        const gchar *filename,
+        GError **error
+    )
 {
-    gint i = 0;
-    LSQSupportFactory *factory;
-    const gchar *type, *name;
+    LSQSupportFile *support_file;
+    const gchar *name;
     gchar **mime_types;
-    LSQCommandOption **add_options = NULL;
-    LSQCommandOption **remove_options = NULL;
-    LSQCommandOption **extract_options = NULL;
-    gchar **option_names;
+    gchar **mime_type;
+    gchar **actions;
+    gchar **action;
+    gboolean can_refresh;
     gchar **column_names;
-    LSQParser *parser = NULL;
+    const gchar *parser_type;
     const gchar *parser_string;
-    const gchar *parser_regex;
     const gchar *parser_datetime;
-    gchar **_mime_types;
 #ifdef HAVE_PCRE
     gchar **regex_types;
 #endif
@@ -74,154 +72,297 @@ lsq_support_reader_parse_file ( const gchar *filename )
     rc = xfce_rc_simple_open( filename, TRUE );
     if ( NULL == rc )
     {
-        g_warning( "Unable to open %s", filename );
+        g_set_error(
+                error,
+                LSQ_SUPPORT_ERROR,
+                LSQ_SUPPORT_ERROR_FAILED,
+                "Unable to open %s",
+                filename
+            );
         return NULL;
     }
 
-    factory = g_object_new( LSQ_TYPE_SUPPORT_FACTORY, NULL );
+    support_file = g_object_new( LSQ_TYPE_SUPPORT_FILE, NULL );
 
-    factory->filename = g_path_get_basename( filename );
+    support_file->filename = g_path_get_basename( filename );
 
-    xfce_rc_set_group( rc, "Desktop Entry" );
-
-    type = xfce_rc_read_entry( rc, "Type", "" );
-    if ( 0 != strcmp( type, "X-Squeeze-Archiver" ) )
-    {
-        g_warning( "%s is not a Squeeze support file", filename );
-        g_object_unref( factory );
-        return NULL;
-    }
+    xfce_rc_set_group( rc, "Squeeze Entry" );
 
     name = xfce_rc_read_entry( rc, "Name", NULL );
     if ( NULL != name )
     {
-        factory->id = g_strdup( name );
+        support_file->display_name = g_strdup( name );
     }
     else
     {
-        g_warning( "Missing %s in %s", "Name", filename );
-        g_object_unref( factory );
+        xfce_rc_close( rc );
+        g_object_unref( support_file );
+        g_set_error(
+                error,
+                LSQ_SUPPORT_ERROR,
+                LSQ_SUPPORT_ERROR_FAILED,
+                "Missing %s in %s",
+                "Name",
+                filename
+            );
         return NULL;
     }
 
     mime_types = xfce_rc_read_list_entry( rc, "MimeType", ";" );
     if ( NULL == mime_types )
     {
-        g_warning( "Missing %s in %s", "MimeType", filename );
-        g_object_unref( factory );
+        xfce_rc_close( rc );
+        g_object_unref( support_file );
+        g_set_error(
+                error,
+                LSQ_SUPPORT_ERROR,
+                LSQ_SUPPORT_ERROR_FAILED,
+                "Missing %s in %s",
+                "MimeType",
+                filename
+            );
         return NULL;
     }
 
-    xfce_rc_set_group( rc, "Squeeze-Add" );
-
-    option_names = xfce_rc_read_list_entry( rc, "X-Squeeze-Options", ";" );
-
-    if ( NULL != option_names )
+    actions = xfce_rc_read_list_entry( rc, "Actions", ";" );
+    /* Assume default actions, when none are listed */
+    if ( NULL == actions )
     {
-        add_options = lsq_command_option_create_list( rc, option_names );
-        g_strfreev( option_names );
+        actions = g_strsplit( "New;Add;Remove;Extract;Refresh", ";", 0 );
     }
 
-    xfce_rc_set_group( rc, "Squeeze-Remove" );
-
-    option_names = xfce_rc_read_list_entry( rc, "X-Squeeze-Options", ";" );
-
-    if ( NULL != option_names )
+    can_refresh = FALSE;
+    for ( action = actions; NULL != *action; ++action )
     {
-        remove_options = lsq_command_option_create_list (rc, option_names );
-        g_strfreev( option_names );
+        if ( 0 == strcmp( "Refresh", *action ) )
+        {
+            can_refresh = TRUE;
+            break;
+        }
     }
-
-    xfce_rc_set_group( rc, "Squeeze-Extract" );
-
-    option_names = xfce_rc_read_list_entry( rc, "X-Squeeze-Options", ";" );
-    if ( NULL != option_names )
+    /* Refresh has special keys */
+    if ( TRUE == can_refresh )
     {
-        extract_options = lsq_command_option_create_list( rc, option_names );
-        g_strfreev( option_names );
-    }
+        xfce_rc_set_group( rc, "Refresh" );
 
-    xfce_rc_set_group( rc, "Squeeze-Refresh" );
-    column_names = xfce_rc_read_list_entry( rc, "X-Squeeze-Headers", ";" );
+        column_names = xfce_rc_read_list_entry( rc, "Headers", ";" );
+        if ( NULL == column_names )
+        {
+            xfce_rc_close( rc );
+            g_strfreev( mime_types );
+            g_object_unref( support_file );
+            g_set_error(
+                    error,
+                    LSQ_SUPPORT_ERROR,
+                    LSQ_SUPPORT_ERROR_FAILED,
+                    "Missing %s in %s",
+                    "Headers",
+                    filename
+                );
+            return NULL;
+        }
 
-    if ( NULL == column_names )
-    {
-        g_warning( "Missing %s in %s", "X-Squeeze-Headers", filename );
-        g_object_unref( factory );
-        return NULL;
-    }
+        support_file->n_properties = g_strv_length(column_names);
+        support_file->property_names = column_names;
 
-    parser_string = xfce_rc_read_entry( rc, "X-Squeeze-Parse", NULL );
-    parser_regex = xfce_rc_read_entry( rc, "X-Squeeze-Parse-Regex", NULL );
-    parser_datetime = xfce_rc_read_entry( rc, "X-Squeeze-Parse-DateTime", NULL );
+        parser_type = xfce_rc_read_entry( rc, "Parser", NULL );
 
-    if ( NULL != parser_string )
-    {
-        parser = lsq_scanf_parser_new( parser_string );
-        if ( NULL == parser )
+        /* Read common parser keys */
+        parser_string = xfce_rc_read_entry( rc, "Parse", NULL );
+
+        if ( NULL == parser_type )
         {
-            g_warning( "Unable to parse %s in %s", "X-Squeeze-Parse", filename );
-            g_object_unref( factory );
+            xfce_rc_close( rc );
+            g_strfreev( mime_types );
+            g_object_unref( support_file );
+            g_set_error(
+                    error,
+                    LSQ_SUPPORT_ERROR,
+                    LSQ_SUPPORT_ERROR_FAILED,
+                    "Missing %s in %s",
+                    "Parser",
+                    filename
+                );
             return NULL;
         }
-    }
+        else if ( 0 == strcmp( "scanf", parser_type ) )
+        {
+            if ( NULL == parser_string )
+            {
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Missing %s in %s",
+                        "Parse",
+                        filename
+                    );
+                return NULL;
+            }
+            support_file->parser = lsq_scanf_parser_new( parser_string );
+            if ( NULL == support_file->parser )
+            {
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Unable to parse %s in %s",
+                        "Parse",
+                        filename
+                    );
+                return NULL;
+            }
+        }
 #ifdef HAVE_PCRE
-    else if ( NULL != parser_regex )
-    {
-        regex_types = xfce_rc_read_list_entry( rc, "X-Squeeze-Types", ";" );
-        if ( NULL == regex_types )
+        else if ( 0 == strcmp( "pcre", parser_type ) )
         {
-            g_warning( "Missing %s in %s", "X-Squeeze-Types", filename );
-            g_object_unref( factory );
+            if ( NULL == parser_string )
+            {
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Missing %s in %s",
+                        "Parse",
+                        filename
+                    );
+                return NULL;
+            }
+            regex_types = xfce_rc_read_list_entry( rc, "Types", ";" );
+            if ( NULL == regex_types )
+            {
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Missing %s in %s",
+                        "Types",
+                        filename
+                    );
+                return NULL;
+            }
+            support_file->parser = lsq_pcre_parser_new( parser_string, regex_types );
+            g_strfreev( regex_types );
+            if ( NULL == support_file->parser )
+            {
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Unable to parse %s in %s",
+                        "Parse",
+                        filename
+                    );
+                return NULL;
+            }
+        }
+#endif
+        else
+        {
+            xfce_rc_close( rc );
+            g_strfreev( mime_types );
+            g_object_unref( support_file );
+            g_set_error(
+                    error,
+                    LSQ_SUPPORT_ERROR,
+                    LSQ_SUPPORT_ERROR_FAILED,
+                    "Unknown parser '%s' in %s",
+                    parser_type,
+                    filename
+                );
             return NULL;
         }
-        parser = lsq_pcre_parser_new( parser_regex, regex_types );
-        g_strfreev( regex_types );
-        if ( NULL == parser )
+
+        if ( lsq_parser_n_properties( support_file->parser ) != g_strv_length( column_names ) )
         {
-            g_warning( "Unable to parse %s in %s", "X-Squeeze-Parse-Regex", filename );
-            g_object_unref( factory );
+            xfce_rc_close( rc );
+            g_strfreev( mime_types );
+            g_object_unref( support_file );
+            g_set_error(
+                    error,
+                    LSQ_SUPPORT_ERROR,
+                    LSQ_SUPPORT_ERROR_FAILED,
+                    "Parser expression and %s mismatch in %s",
+                    "Headers",
+                    filename
+                );
             return NULL;
         }
+
+        parser_datetime = xfce_rc_read_entry( rc, "Parse-DateTime", NULL );
+        if ( NULL != parser_datetime )
+        {
+            lsq_parser_set_datetime_format( support_file->parser, parser_datetime );
+        }
     }
-#endif
-    else
+
+    /*
+    xfce_rc_set_group( rc, "Add" );
+
+    option_names = xfce_rc_read_list_entry( rc, "Options", ";" );
+
+    if ( NULL != option_names )
     {
-        g_warning( "Missing %s in %s", "X-Squeeze-Parse", filename );
-        g_object_unref( factory );
-        return NULL;
+        add_options = lsq_command_option_create_list( rc, option_names );
+        g_strfreev( option_names );
     }
 
-    if ( NULL != parser_datetime )
+    xfce_rc_set_group( rc, "Remove" );
+
+    option_names = xfce_rc_read_list_entry( rc, "Options", ";" );
+
+    if ( NULL != option_names )
     {
-        lsq_parser_set_datetime_format( parser, parser_datetime );
+        remove_options = lsq_command_option_create_list (rc, option_names );
+        g_strfreev( option_names );
     }
 
-    if ( lsq_parser_n_properties( parser ) != g_strv_length( column_names ) )
+    xfce_rc_set_group( rc, "Extract" );
+
+    option_names = xfce_rc_read_list_entry( rc, "Options", ";" );
+    if ( NULL != option_names )
     {
-        g_warning( "Parser expression and %s mismatch in %s", "X-Squeeze-Headers", filename );
-        g_object_unref( factory );
-        return NULL;
+        extract_options = lsq_command_option_create_list( rc, option_names );
+        g_strfreev( option_names );
     }
+    */
 
-    _mime_types = mime_types;
-    for ( i = 0; NULL != _mime_types[i]; ++i )
+    for ( mime_type = mime_types; NULL != *mime_type; ++mime_type )
     {
-        LSQSupportTemplate *s_template = g_new( LSQSupportTemplate, 1 );
+        LSQSupportInfo *info;
+        LSQSupportApp *app;
+        gchar **required_apps;
+        gboolean required_found;
         const gchar *new_str_queue;
         const gchar *add_str_queue;
         const gchar *remove_str_queue;
         const gchar *extract_str_queue;
         const gchar *refresh_str_queue;
 
-        xfce_rc_set_group( rc, _mime_types[i] );
+        xfce_rc_set_group( rc, *mime_type );
+
         /* only add to builder->mime_types if all req. apps are found */
-        s_template->required_apps = xfce_rc_read_list_entry( rc, "X-Squeeze-Requires", ";" );
-        if ( NULL != s_template->required_apps )
+        required_apps = xfce_rc_read_list_entry( rc, "Requires", ";" );
+        if ( NULL != required_apps )
         {
             gchar **_iter;
-            s_template->supported = TRUE;
-            for ( _iter = s_template->required_apps; NULL != *_iter; ++_iter )
+            required_found = TRUE;
+            for ( _iter = required_apps; NULL != *_iter; ++_iter )
             {
                 gchar *path = g_find_program_in_path( *_iter );
                 if ( NULL != path )
@@ -230,33 +371,58 @@ lsq_support_reader_parse_file ( const gchar *filename )
                 }
                 else
                 {
-                    s_template->supported = FALSE;
+                    required_found = FALSE;
                     break;
                 }
             }
         }
         else
         {
-            s_template->supported = FALSE;
+            xfce_rc_close( rc );
+            g_strfreev( mime_types );
+            g_object_unref( support_file );
+            g_set_error(
+                    error,
+                    LSQ_SUPPORT_ERROR,
+                    LSQ_SUPPORT_ERROR_FAILED,
+                    "Missing %s in %s",
+                    "Requires",
+                    filename
+                );
+            return NULL;
+        }
+
+        /* Skip this mime type if the requirements are not met */
+        if ( FALSE == required_found )
+        {
+            continue;
         }
 
-        s_template->content_type = g_strdup( _mime_types[i] );
-        s_template->id = (const gchar *)factory->id;
+        app = lsq_support_app_new( support_file );
 
-        new_str_queue = xfce_rc_read_entry( rc, "X-Squeeze-New", NULL );
-        add_str_queue = xfce_rc_read_entry( rc, "X-Squeeze-Add", NULL );
-        remove_str_queue = xfce_rc_read_entry( rc, "X-Squeeze-Remove", NULL );
-        extract_str_queue = xfce_rc_read_entry( rc, "X-Squeeze-Extract", NULL );
-        refresh_str_queue = xfce_rc_read_entry( rc, "X-Squeeze-Refresh", NULL );
+        new_str_queue = xfce_rc_read_entry( rc, "New", NULL );
+        add_str_queue = xfce_rc_read_entry( rc, "Add", NULL );
+        remove_str_queue = xfce_rc_read_entry( rc, "Remove", NULL );
+        extract_str_queue = xfce_rc_read_entry( rc, "Extract", NULL );
+        refresh_str_queue = xfce_rc_read_entry( rc, "Refresh", NULL );
 
         /* Read the 'new-archive' command-queue from file */	
         if ( NULL != new_str_queue )
         {
-            s_template->new_cmd_queue = lsq_command_queue_new( new_str_queue );
-            if ( NULL == s_template->new_cmd_queue )
+            app->new_cmd_queue = lsq_command_queue_new( new_str_queue, LSQ_COMMAND_TYPE_NEW );
+            if ( NULL == app->new_cmd_queue )
             {
-                g_warning( "Unable to parse %s in %s", "X-Squeeze-New", filename );
-                g_object_unref( factory );
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Unable to parse %s in %s",
+                        "New",
+                        filename
+                    );
                 return NULL;
             }
         }
@@ -264,35 +430,62 @@ lsq_support_reader_parse_file ( const gchar *filename )
         /* Read the 'add-to-archive' command-queue from file */	
         if ( NULL != add_str_queue )
         {
-            s_template->add_cmd_queue = lsq_command_queue_new( add_str_queue );
-            if ( NULL == s_template->add_cmd_queue )
+            app->add_cmd_queue = lsq_command_queue_new( add_str_queue, LSQ_COMMAND_TYPE_ADD );
+            if ( NULL == app->add_cmd_queue )
             {
-                g_warning( "Unable to parse %s in %s", "X-Squeeze-Add", filename );
-                g_object_unref( factory );
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Unable to parse %s in %s",
+                        "Add",
+                        filename
+                    );
                 return NULL;
             }
         }
 
-        /* Read the 'remove-to-archive' command-queue from file */	
+        /* Read the 'remove-from-archive' command-queue from file */	
         if ( NULL != remove_str_queue )
         {
-            s_template->remove_cmd_queue = lsq_command_queue_new( remove_str_queue );
-            if ( NULL == s_template->remove_cmd_queue )
+            app->remove_cmd_queue = lsq_command_queue_new( remove_str_queue, LSQ_COMMAND_TYPE_REMOVE );
+            if ( NULL == app->remove_cmd_queue )
             {
-                g_warning( "Unable to parse %s in %s", "X-Squeeze-Remove", filename );
-                g_object_unref( factory );
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Unable to parse %s in %s",
+                        "Remove",
+                        filename
+                    );
                 return NULL;
             }
         }
 
-        /* Read the 'extract-to-archive' command-queue from file */	
+        /* Read the 'extract-from-archive' command-queue from file */	
         if ( NULL != extract_str_queue )
         {
-            s_template->extract_cmd_queue = lsq_command_queue_new( extract_str_queue );
-            if ( NULL == s_template->extract_cmd_queue )
+            app->extract_cmd_queue = lsq_command_queue_new( extract_str_queue, LSQ_COMMAND_TYPE_EXTRACT );
+            if ( NULL == app->extract_cmd_queue )
             {
-                g_warning( "Unable to parse %s in %s", "X-Squeeze-Extract", filename );
-                g_object_unref( factory );
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Unable to parse %s in %s",
+                        "Extract",
+                        filename
+                    );
                 return NULL;
             }
         }
@@ -300,39 +493,32 @@ lsq_support_reader_parse_file ( const gchar *filename )
         /* Read the 'refresh-archive' command-queue from file */	
         if ( NULL != refresh_str_queue )
         {
-            s_template->refresh_cmd_queue = lsq_command_queue_new( refresh_str_queue );
-            if ( NULL == s_template->refresh_cmd_queue )
+            app->refresh_cmd_queue = lsq_command_queue_new( refresh_str_queue, LSQ_COMMAND_TYPE_REFRESH );
+            if ( NULL == app->refresh_cmd_queue )
             {
-                g_warning( "Unable to parse %s in %s", "X-Squeeze-Refresh", filename );
-                g_object_unref( factory );
+                xfce_rc_close( rc );
+                g_strfreev( mime_types );
+                g_object_unref( support_file );
+                g_set_error(
+                        error,
+                        LSQ_SUPPORT_ERROR,
+                        LSQ_SUPPORT_ERROR_FAILED,
+                        "Unable to parse %s in %s",
+                        "Refresh",
+                        filename
+                    );
                 return NULL;
             }
         }
 
-        /* Add the appropriate options to the template */
-        s_template->add_options = add_options;
-        s_template->remove_options = remove_options;
-        s_template->extract_options = extract_options;
-
-
-        s_template->n_properties = g_strv_length(column_names);
-        s_template->property_names = column_names;
-        s_template->parser = parser;
-
-#ifdef DEBUG
-        if ( TRUE == s_template->supported )
-        {
-            g_debug( "%s supported\n", _mime_types[i] );
-        }
-        else
-        {
-            g_debug( "%s not supported\n", _mime_types[i] );
-        }
-#endif
-
-        lsq_support_factory_add_template( factory, s_template );
+        info = lsq_support_info_new( *mime_type );
+        app->support_info = info;
+        lsq_support_info_add_app( info, app );
     }
 
-    return factory;
+    xfce_rc_close( rc );
+    g_strfreev( mime_type );
+
+    return support_file;
 }
 
diff --git a/libsqueeze/support-reader.h b/libsqueeze/support-reader.h
index 8990494..8b14513 100644
--- a/libsqueeze/support-reader.h
+++ b/libsqueeze/support-reader.h
@@ -13,16 +13,21 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  */
 
-#ifndef __LIBSQUEEZE_SUPPORT_READER_H__
-#define __LIBSQUEEZE_SUPPORT_READER_H__ 
+#ifndef __SUPPORT_READER_H__
+#define __SUPPORT_READER_H__ 
+
+#include "internal-types.h"
 
 G_BEGIN_DECLS
 
 
-LSQSupportFactory *
-lsq_support_reader_parse_file ( const gchar *filename ) G_GNUC_WARN_UNUSED_RESULT;
+LSQSupportFile *
+lsq_support_reader_parse_file (
+        const gchar *filename,
+        GError **error
+    ) G_GNUC_WARN_UNUSED_RESULT;
 
 
 G_END_DECLS
-#endif /* __LIBSQUEEZE_SUPPORT_READER_H__ */
 
+#endif /* __SUPPORT_READER_H__ */
diff --git a/libsqueeze/support-template.c b/libsqueeze/support-template.c
deleted file mode 100644
index 480c832..0000000
--- a/libsqueeze/support-template.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* 
- *  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 Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-#include <string.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib-object.h> 
-#include <gio/gio.h>
-
-#include <libxfce4util/libxfce4util.h>
-
-#include "libsqueeze.h"
-#include "parser-context.h"
-#include "parser.h"
-#include "support-template.h"
-
-GType
-lsq_support_template_get_property_type (
-        LSQSupportTemplate *templ,
-        guint nr
-    )
-{
-#ifdef DEBUG
-    g_return_val_if_fail( NULL != templ, G_TYPE_NONE );
-    g_return_val_if_fail( templ->n_properties > nr, G_TYPE_NONE );
-    g_return_val_if_fail( LSQ_IS_PARSER( templ->parser ), G_TYPE_NONE);
-#endif
-    return lsq_parser_get_property_type( templ->parser, nr );
-}
-
-guint
-lsq_support_template_get_property_offset (
-        LSQSupportTemplate *templ,
-        guint nr
-    )
-{
-#ifdef DEBUG
-    g_return_val_if_fail( NULL != templ, 0 );
-    g_return_val_if_fail( templ->n_properties > nr, 0 );
-    g_return_val_if_fail( LSQ_IS_PARSER( templ->parser ), 0 );
-#endif
-    return lsq_parser_get_property_offset( templ->parser, nr );
-}
-
-const gchar *
-lsq_support_template_get_property_name (
-        LSQSupportTemplate *templ,
-        guint nr
-    )
-{
-    g_return_val_if_fail( NULL != templ, NULL );
-    g_return_val_if_fail( templ->n_properties > nr, NULL );
-
-    return templ->property_names[nr];
-}
-
-guint
-lsq_support_template_get_n_properties ( LSQSupportTemplate *templ )
-{
-    guint n_props;
-
-#ifdef DEBUG
-    g_return_val_if_fail( NULL != templ, 0 );
-    g_return_val_if_fail( LSQ_IS_PARSER( templ->parser ), 0 );
-#endif
-
-    n_props = lsq_parser_n_properties( templ->parser );
-
-    if ( templ->n_properties > n_props )
-    {
-        n_props = templ->n_properties;
-    }
-    return n_props;
-}
-
-guint
-lsq_support_template_get_properties_size ( LSQSupportTemplate *templ )
-{
-#ifdef DEBUG
-    g_return_val_if_fail( NULL != templ, 0 );
-    g_return_val_if_fail( LSQ_IS_PARSER( templ->parser ), 0 );
-#endif
-    return lsq_parser_get_properties_size( templ->parser );
-}
diff --git a/libsqueeze/support-template.h b/libsqueeze/support-template.h
deleted file mode 100644
index 6f01571..0000000
--- a/libsqueeze/support-template.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* 
- *  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 Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __SUPPORT_TEMPLATE_H__
-#define __SUPPORT_TEMPLATE_H__
-
-typedef enum
-{
-    LSQ_SUPPORT_FILES    = 1 << 0x0,
-    LSQ_SUPPORT_FOLDERS  = 1 << 0x1,
-    LSQ_SUPPORT_MANY     = 1 << 0x2
-} LSQSupportType;
-
-typedef enum
-{
-    LSQ_COMMAND_TYPE_ADD,
-    LSQ_COMMAND_TYPE_REMOVE,
-    LSQ_COMMAND_TYPE_EXTRACT,
-    LSQ_COMMAND_TYPE_REFRESH,
-    LSQ_COMMAND_TYPE_OPEN,
-    LSQ_COMMAND_TYPE_TEST
-} LSQCommandType;
-
-typedef struct _LSQParser LSQParser;
-
-typedef struct _LSQCommandQueue LSQCommandQueue;
-
-typedef struct _LSQSupportTemplate LSQSupportTemplate;
-
-struct _LSQSupportTemplate
-{
-    const gchar        *id;
-    gchar             **required_apps;
-    gboolean            supported;
-    gchar              *content_type;
-
-    guint               n_properties;
-    gchar             **property_names;
-    LSQParser          *parser;
-
-    LSQCommandQueue    *new_cmd_queue;
-    LSQCommandQueue    *add_cmd_queue;
-    LSQCommandOption  **add_options;
-    LSQCommandQueue    *remove_cmd_queue;
-    LSQCommandOption  **remove_options;
-    LSQCommandQueue    *extract_cmd_queue;
-    LSQCommandOption  **extract_options;
-    LSQCommandQueue    *refresh_cmd_queue;
-    LSQSupportType      support_mask;
-};
-
-GType
-lsq_support_template_get_property_type (
-        LSQSupportTemplate *s_template,
-        guint n
-    ) G_GNUC_PURE;
-guint
-lsq_support_template_get_property_offset (
-        LSQSupportTemplate *s_template,
-        guint n
-    ) G_GNUC_PURE;
-const gchar *
-lsq_support_template_get_property_name (
-        LSQSupportTemplate *s_template,
-        guint n
-    ) G_GNUC_PURE;
-guint
-lsq_support_template_get_n_properties ( LSQSupportTemplate *s_template) G_GNUC_PURE;
-guint
-lsq_support_template_get_properties_size ( LSQSupportTemplate *s_template ) G_GNUC_PURE;
-
-
-#endif /* __SUPPORT_TEMPLATE_H__ */
-


More information about the Xfce4-commits mailing list