diff --git a/ChangeLog b/ChangeLog
index 5bc5cd9c119a9b2c6d788eb7f63af18c88948e4a..bf6467f74e3f8c489ff599920959f6705ade3630 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-29	Benedikt Meurer <benny@xfce.org>
+
+	* thunar-vfs/thunar-vfs-job.{c,h}: Add a parameter spec for
+	  ThunarVfsJob and derived types. Add support methods to handle
+	  GValues easily.
+	* thunar-vfs/thunar-vfs-listdir-job.{c,h}, thunar-vfs/Makefile.am,
+	  thunar-vfs/thunar-vfs.h, thunar/thunar-local-folder.c: Rename the
+	  ThunarVfsJobListdir class to ThunarVfsListdirJob.
+
 2005-07-25	Benedikt Meurer <benny@xfce.org>
 
 	* thunar-vfs/thunar-vfs-sysdep.{c,h}: Add _thunar_vfs_sysdep_readdir()
diff --git a/thunar-vfs/Makefile.am b/thunar-vfs/Makefile.am
index 2002252f4df2ba48e6214bd37c3283a0d0cbdb62..8a203599ac036e792e708123032d22992e70caa0 100644
--- a/thunar-vfs/Makefile.am
+++ b/thunar-vfs/Makefile.am
@@ -20,7 +20,7 @@ libthunar_vfs_built_sources =						\
 libthunar_vfs_headers =							\
 	thunar-vfs-info.h						\
 	thunar-vfs-job.h						\
-	thunar-vfs-job-listdir.h					\
+	thunar-vfs-listdir-job.h					\
 	thunar-vfs-mime.h						\
 	thunar-vfs-monitor.h						\
 	thunar-vfs-trash.h						\
@@ -35,7 +35,7 @@ libthunar_vfs_la_SOURCES =						\
 	$(libthunar_vfs_headers)					\
 	thunar-vfs-info.c						\
 	thunar-vfs-job.c						\
-	thunar-vfs-job-listdir.c					\
+	thunar-vfs-listdir-job.c					\
 	thunar-vfs-mime.c						\
 	thunar-vfs-mime-parser.h					\
 	thunar-vfs-mime-parser.c					\
diff --git a/thunar-vfs/thunar-vfs-job.c b/thunar-vfs/thunar-vfs-job.c
index c91b1fc3e13defa8a0bebd601bcc25268bd06d41..f9a7d1595673a08f05a17e1318726760f3e318ee 100644
--- a/thunar-vfs/thunar-vfs-job.c
+++ b/thunar-vfs/thunar-vfs-job.c
@@ -472,6 +472,156 @@ thunar_vfs_job_emit (ThunarVfsJob *job,
 
 
 
+
+GType
+thunar_vfs_param_spec_job_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (GParamSpecClass),
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        sizeof (ThunarVfsParamSpecJob),
+        0,
+        NULL,
+        NULL,
+      };
+
+      type = g_type_register_static (G_TYPE_PARAM,
+                                     "ThunarVfsParamSpecJob",
+                                     &info, 0);
+    }
+
+  return type;
+}
+
+
+
+/**
+ * thunar_vfs_param_spec_job:
+ * @name
+ * @nick
+ * @blurb
+ * @job_type
+ * @flags
+ *
+ * Return value:
+ **/
+GParamSpec*
+thunar_vfs_param_spec_job (const gchar *name,
+                           const gchar *nick,
+                           const gchar *blurb,
+                           GType        job_type,
+                           GParamFlags  flags)
+{
+  GParamSpec *pspec;
+
+  g_return_val_if_fail (g_type_is_a (job_type, THUNAR_VFS_TYPE_JOB), NULL);
+
+  pspec = g_param_spec_internal (THUNAR_VFS_TYPE_PARAM_JOB, name, nick, blurb, flags);
+  pspec->value_type = job_type;
+
+  return pspec;
+}
+
+
+
+/**
+ * thunar_vfs_value_set_job:
+ * @value : a valid #GValue of type #THUNAR_VFS_TYPE_JOB or a derived type.
+ * @job   : the #ThunarVfsJob to set or %NULL.
+ *
+ * Sets the contents of @value to @job.
+ **/
+void
+thunar_vfs_value_set_job (GValue  *value,
+                          gpointer job)
+{
+  g_return_if_fail (THUNAR_VFS_VALUE_HOLDS_JOB (value));
+  g_return_if_fail (job == NULL || THUNAR_VFS_IS_JOB (job));
+  g_return_if_fail (job == NULL || g_value_type_compatible (G_TYPE_FROM_INSTANCE (job), G_VALUE_TYPE (value)));
+
+  if (value->data[0].v_pointer != NULL)
+    thunar_vfs_job_unref (value->data[0].v_pointer);
+
+  value->data[0].v_pointer = job;
+
+  if (G_LIKELY (job != NULL))
+    thunar_vfs_job_ref (job);
+}
+
+
+
+/**
+ * thunar_vfs_value_take_job:
+ * @value : a valid #GValue of type #THUNAR_VFS_TYPE_JOB or a derived type.
+ * @job   : the #ThunarVfsJob to take over or %NULL.
+ *
+ * Sets the contents of @value to @job and takes over the ownership of
+ * the callers reference to @job; the caller doesn't have to unref it
+ * any more.
+ **/
+void
+thunar_vfs_value_take_job (GValue  *value,
+                           gpointer job)
+{
+  g_return_if_fail (THUNAR_VFS_VALUE_HOLDS_JOB (value));
+  g_return_if_fail (job == NULL || THUNAR_VFS_IS_JOB (job));
+  g_return_if_fail (job == NULL || g_value_type_compatible (G_TYPE_FROM_INSTANCE (job), G_VALUE_TYPE (value)));
+
+  if (value->data[0].v_pointer != NULL)
+    thunar_vfs_job_unref (value->data[0].v_pointer);
+
+  value->data[0].v_pointer = job;
+}
+
+
+
+/**
+ * thunar_vfs_value_get_job:
+ * @value : a valid #GValue of type #THUNAR_VFS_TYPE_JOB or a derived type.
+ *
+ * Queries the #ThunarVfsJob stored within @value and returns it. The
+ * stored value may be %NULL.
+ *
+ * Return value: the #ThunarVfsJob stored in @value.
+ **/
+gpointer
+thunar_vfs_value_get_job (const GValue *value)
+{
+  g_return_val_if_fail (THUNAR_VFS_VALUE_HOLDS_JOB (value), NULL);
+  return value->data[0].v_pointer;
+}
+
+
+
+/**
+ * thunar_vfs_value_dup_job:
+ * @value : a valid #GValue of type #THUNAR_VFS_TYPE_JOB or a derived type.
+ *
+ * Similar to #thunar_vfs_value_get_job(), but also takes a reference for
+ * the caller if @value contains a valid #ThunarVfsJob.
+ *
+ * Return value: the #ThunarVfsJob stored in @value with an additional
+ *               reference taken for the caller.
+ **/
+gpointer
+thunar_vfs_value_dup_job (const GValue *value)
+{
+  g_return_val_if_fail (THUNAR_VFS_VALUE_HOLDS_JOB (value), NULL);
+  return (value->data[0].v_pointer != NULL) ? thunar_vfs_job_ref (value->data[0].v_pointer) : NULL;
+}
+
+
+
+
 /**
  * _thunar_vfs_job_init:
  *
@@ -487,3 +637,5 @@ _thunar_vfs_job_init (void)
 }
 
 
+
+
diff --git a/thunar-vfs/thunar-vfs-job.h b/thunar-vfs/thunar-vfs-job.h
index 37fb7c5fa134aea014beb1b2c2b1cf41ec86434f..b92cc7c29258e9e86304a71192ae664154118a4e 100644
--- a/thunar-vfs/thunar-vfs-job.h
+++ b/thunar-vfs/thunar-vfs-job.h
@@ -77,6 +77,35 @@ void          thunar_vfs_job_emit         (ThunarVfsJob       *job,
                                            GQuark              signal_detail,
                                            ...);
 
+
+typedef struct _ThunarVfsParamSpecJob ThunarVfsParamSpecJob;
+
+#define THUNAR_VFS_TYPE_PARAM_JOB           (thunar_vfs_param_spec_job_get_type ())
+#define THUNAR_VFS_PARAM_SPEC_JOB(pspec)    (G_TYPE_CHECK_INSTANCE_CAST ((pspec), THUNAR_VFS_TYPE_PARAM_JOB, ThunarVfsParamJob))
+#define THUNAR_VFS_IS_PARAM_SPEC_JOB(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), THUNAR_VFS_TYPE_PARAM_JOB))
+#define THUNAR_VFS_VALUE_HOLDS_JOB(value)   (G_TYPE_CHECK_VALUE_TYPE ((value), THUNAR_VFS_TYPE_JOB))
+
+struct _ThunarVfsParamSpecJob
+{
+  /*< private >*/
+  GParamSpec __parent__;
+};
+
+GType       thunar_vfs_param_spec_job_get_type (void) G_GNUC_CONST;
+
+GParamSpec *thunar_vfs_param_spec_job          (const gchar   *name,
+                                                const gchar   *nick,
+                                                const gchar   *blurb,
+                                                GType          job_type,
+                                                GParamFlags    flags);
+
+void        thunar_vfs_value_set_job           (GValue        *value,
+                                     gpointer       job);
+void      thunar_vfs_value_take_job (GValue        *value,
+                                     gpointer       job);
+gpointer  thunar_vfs_value_get_job  (const GValue  *value);
+gpointer  thunar_vfs_value_dup_job  (const GValue  *value);
+
 G_END_DECLS;
 
 #endif /* !__THUNAR_VFS_JOB_H__ */
diff --git a/thunar-vfs/thunar-vfs-job-listdir.c b/thunar-vfs/thunar-vfs-listdir-job.c
similarity index 73%
rename from thunar-vfs/thunar-vfs-job-listdir.c
rename to thunar-vfs/thunar-vfs-listdir-job.c
index 0a5615d2826e8414b40bca481714b0c848c5f0aa..47df5e840914aa4a1cc3bd34dd34d34784db8ca8 100644
--- a/thunar-vfs/thunar-vfs-job-listdir.c
+++ b/thunar-vfs/thunar-vfs-listdir-job.c
@@ -42,7 +42,7 @@
 #include <time.h>
 #endif
 
-#include <thunar-vfs/thunar-vfs-job-listdir.h>
+#include <thunar-vfs/thunar-vfs-listdir-job.h>
 #include <thunar-vfs/thunar-vfs-sysdep.h>
 
 
@@ -56,13 +56,13 @@ enum
 
 
 
-static void  thunar_vfs_job_listdir_register_type (GType             *type);
-static void  thunar_vfs_job_listdir_class_init    (ThunarVfsJobClass *klass);
-static void  thunar_vfs_job_listdir_execute       (ThunarVfsJob      *job);
-static void  thunar_vfs_job_listdir_finalize      (ThunarVfsJob      *job);
+static void  thunar_vfs_listdir_job_register_type (GType             *type);
+static void  thunar_vfs_listdir_job_class_init    (ThunarVfsJobClass *klass);
+static void  thunar_vfs_listdir_job_execute       (ThunarVfsJob      *job);
+static void  thunar_vfs_listdir_job_finalize      (ThunarVfsJob      *job);
 
 
-struct _ThunarVfsJobListdir
+struct _ThunarVfsListdirJob
 {
   ThunarVfsJob __parent__;
 
@@ -76,13 +76,13 @@ static guint listdir_signals[LAST_SIGNAL];
 
 
 GType
-thunar_vfs_job_listdir_get_type (void)
+thunar_vfs_listdir_job_get_type (void)
 {
   static GType type = G_TYPE_INVALID;
   static GOnce once = G_ONCE_INIT;
 
   /* thread-safe type registration */
-  g_once (&once, (GThreadFunc) thunar_vfs_job_listdir_register_type, &type);
+  g_once (&once, (GThreadFunc) thunar_vfs_listdir_job_register_type, &type);
 
   return type;
 }
@@ -90,37 +90,37 @@ thunar_vfs_job_listdir_get_type (void)
 
 
 static void
-thunar_vfs_job_listdir_register_type (GType *type)
+thunar_vfs_listdir_job_register_type (GType *type)
 {
   static const GTypeInfo info =
   {
     sizeof (ThunarVfsJobClass),
     NULL,
     NULL,
-    (GClassInitFunc) thunar_vfs_job_listdir_class_init,
+    (GClassInitFunc) thunar_vfs_listdir_job_class_init,
     NULL,
     NULL,
-    sizeof (ThunarVfsJobListdir),
+    sizeof (ThunarVfsListdirJob),
     0,
     NULL,
     NULL,
   };
 
   *type = g_type_register_static (THUNAR_VFS_TYPE_JOB,
-                                  "ThunarVfsJobListdir",
+                                  "ThunarVfsListdirJob",
                                   &info, 0);
 }
 
 
 
 static void
-thunar_vfs_job_listdir_class_init (ThunarVfsJobClass *klass)
+thunar_vfs_listdir_job_class_init (ThunarVfsJobClass *klass)
 {
-  klass->execute = thunar_vfs_job_listdir_execute;
-  klass->finalize = thunar_vfs_job_listdir_finalize;
+  klass->execute = thunar_vfs_listdir_job_execute;
+  klass->finalize = thunar_vfs_listdir_job_finalize;
 
   /**
-   * ThunarVfsJobListdir::error-occurred:
+   * ThunarVfsListdirJob::error-occurred:
    * @job   : a #ThunarVfsJob.
    * @error : a #GError describing the cause.
    *
@@ -135,7 +135,7 @@ thunar_vfs_job_listdir_class_init (ThunarVfsJobClass *klass)
                   G_TYPE_NONE, 1, G_TYPE_POINTER);
 
   /**
-   * ThunarVfsJobListdir::infos-ready:
+   * ThunarVfsListdirJob::infos-ready:
    * @job   : a #ThunarVfsJob.
    * @infos : a list of #ThunarVfsInfo<!---->s.
    *
@@ -154,7 +154,7 @@ thunar_vfs_job_listdir_class_init (ThunarVfsJobClass *klass)
 
 
 static void
-thunar_vfs_job_listdir_execute (ThunarVfsJob *job)
+thunar_vfs_listdir_job_execute (ThunarVfsJob *job)
 {
   ThunarVfsInfo *info;
   struct dirent  d_buffer;
@@ -169,7 +169,7 @@ thunar_vfs_job_listdir_execute (ThunarVfsJob *job)
   time_t         current_time;
   DIR           *dp;
 
-  dp = opendir (thunar_vfs_uri_get_path (THUNAR_VFS_JOB_LISTDIR (job)->uri));
+  dp = opendir (thunar_vfs_uri_get_path (THUNAR_VFS_LISTDIR_JOB (job)->uri));
   if (G_UNLIKELY (dp == NULL))
     {
       error = g_error_new_literal (G_FILE_ERROR, g_file_error_from_errno (errno), g_strerror (errno));
@@ -182,17 +182,8 @@ thunar_vfs_job_listdir_execute (ThunarVfsJob *job)
        * (hopefully) avoid a bit unnecessary
        * disk seeking.
        */
-      for (;;)
-        {
-          if (G_UNLIKELY (!_thunar_vfs_sysdep_readdir (dp, &d_buffer, &d, &error)))
-            break;
-
-          /* check for end of directory */
-          if (G_UNLIKELY (d == NULL))
-              break;
-
-          names = g_slist_insert_sorted (names, g_string_chunk_insert (names_chunk, d->d_name), (GCompareFunc) strcmp);
-        }
+      while (_thunar_vfs_sysdep_readdir (dp, &d_buffer, &d, &error) && d != NULL)
+        names = g_slist_insert_sorted (names, g_string_chunk_insert (names_chunk, d->d_name), (GCompareFunc) strcmp);
 
       closedir (dp);
 
@@ -207,7 +198,7 @@ thunar_vfs_job_listdir_execute (ThunarVfsJob *job)
           if (thunar_vfs_job_cancelled (job) || error != NULL)
             break;
 
-          file_uri = thunar_vfs_uri_relative (THUNAR_VFS_JOB_LISTDIR (job)->uri, lp->data);
+          file_uri = thunar_vfs_uri_relative (THUNAR_VFS_LISTDIR_JOB (job)->uri, lp->data);
           info = thunar_vfs_info_new_for_uri (file_uri, NULL);
           if (G_LIKELY (info != NULL))
             infos = g_slist_prepend (infos, info);
@@ -246,13 +237,13 @@ thunar_vfs_job_listdir_execute (ThunarVfsJob *job)
 
 
 static void
-thunar_vfs_job_listdir_finalize (ThunarVfsJob *job)
+thunar_vfs_listdir_job_finalize (ThunarVfsJob *job)
 {
-  ThunarVfsJobListdir *job_listdir = THUNAR_VFS_JOB_LISTDIR (job);
+  ThunarVfsListdirJob *listdir_job = THUNAR_VFS_LISTDIR_JOB (job);
 
   /* free the folder uri */
-  if (G_LIKELY (job_listdir->uri != NULL))
-    thunar_vfs_uri_unref (job_listdir->uri);
+  if (G_LIKELY (listdir_job->uri != NULL))
+    thunar_vfs_uri_unref (listdir_job->uri);
 }
 
 
@@ -261,7 +252,7 @@ thunar_vfs_job_listdir_finalize (ThunarVfsJob *job)
  * thunar_vfs_job_new:
  * @folder_uri : the #ThunarVfsURI of the directory whose contents to query.
  *
- * Allocates a new #ThunarVfsJobListdir object, which can be used to
+ * Allocates a new #ThunarVfsListdirJob object, which can be used to
  * query the contents of the directory @folder_uri.
  *
  * You need to call #thunar_vfs_job_launch() in order to start the
@@ -275,16 +266,16 @@ thunar_vfs_job_listdir_finalize (ThunarVfsJob *job)
  *               directory listing.
  **/
 ThunarVfsJob*
-thunar_vfs_job_listdir_new (ThunarVfsURI *folder_uri)
+thunar_vfs_listdir_job_new (ThunarVfsURI *folder_uri)
 {
-  ThunarVfsJobListdir *job_listdir;
+  ThunarVfsListdirJob *listdir_job;
 
   g_return_val_if_fail (THUNAR_VFS_IS_URI (folder_uri), NULL);
 
-  job_listdir = (ThunarVfsJobListdir *) g_type_create_instance (THUNAR_VFS_TYPE_JOB_LISTDIR);
-  job_listdir->uri = thunar_vfs_uri_ref (folder_uri);
+  listdir_job = (ThunarVfsListdirJob *) g_type_create_instance (THUNAR_VFS_TYPE_LISTDIR_JOB);
+  listdir_job->uri = thunar_vfs_uri_ref (folder_uri);
 
-  return THUNAR_VFS_JOB (job_listdir);
+  return THUNAR_VFS_JOB (listdir_job);
 }
 
 
diff --git a/thunar-vfs/thunar-vfs-job-listdir.h b/thunar-vfs/thunar-vfs-listdir-job.h
similarity index 60%
rename from thunar-vfs/thunar-vfs-job-listdir.h
rename to thunar-vfs/thunar-vfs-listdir-job.h
index 5f0b8b293373b1739d6b4e81dfdd1e0271a1a0b4..ce68441016f51b086b165a38925f888bc2747bce 100644
--- a/thunar-vfs/thunar-vfs-job-listdir.h
+++ b/thunar-vfs/thunar-vfs-listdir-job.h
@@ -18,23 +18,23 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#ifndef __THUNAR_VFS_JOB_LISTDIR_H__
-#define __THUNAR_VFS_JOB_LISTDIR_H__
+#ifndef __THUNAR_VFS_LISTDIR_JOB_H__
+#define __THUNAR_VFS_LISTDIR_JOB_H__
 
 #include <thunar-vfs/thunar-vfs-job.h>
 
 G_BEGIN_DECLS;
 
-typedef struct _ThunarVfsJobListdir ThunarVfsJobListdir;
+typedef struct _ThunarVfsListdirJob ThunarVfsListdirJob;
 
-#define THUNAR_VFS_TYPE_JOB_LISTDIR     (thunar_vfs_job_listdir_get_type ())
-#define THUNAR_VFS_JOB_LISTDIR(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_JOB_LISTDIR, ThunarVfsJobListdir))
-#define THUNAR_VFS_IS_JOB_LISTDIR(obj)  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_JOB_LISTDIR))
+#define THUNAR_VFS_TYPE_LISTDIR_JOB     (thunar_vfs_listdir_job_get_type ())
+#define THUNAR_VFS_LISTDIR_JOB(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_LISTDIR_JOB, ThunarVfsListdirJob))
+#define THUNAR_VFS_IS_LISTDIR_JOB(obj)  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_LISTDIR_JOB))
 
-GType         thunar_vfs_job_listdir_get_type (void) G_GNUC_CONST;
+GType         thunar_vfs_listdir_job_get_type (void) G_GNUC_CONST;
 
-ThunarVfsJob *thunar_vfs_job_listdir_new      (ThunarVfsURI *folder_uri);
+ThunarVfsJob *thunar_vfs_listdir_job_new      (ThunarVfsURI *folder_uri);
 
 G_END_DECLS;
 
-#endif /* !__THUNAR_VFS_JOB_LISTDIR_H__ */
+#endif /* !__THUNAR_VFS_LISTDIR_JOB_H__ */
diff --git a/thunar-vfs/thunar-vfs.h b/thunar-vfs/thunar-vfs.h
index 52127a2c8312232cfd729a39b97fb01966f74dda..1e42e008ead22e85a552e765a87abe859a05b04b 100644
--- a/thunar-vfs/thunar-vfs.h
+++ b/thunar-vfs/thunar-vfs.h
@@ -24,7 +24,7 @@
 #include <thunar-vfs/thunar-vfs-enum-types.h>
 #include <thunar-vfs/thunar-vfs-info.h>
 #include <thunar-vfs/thunar-vfs-job.h>
-#include <thunar-vfs/thunar-vfs-job-listdir.h>
+#include <thunar-vfs/thunar-vfs-listdir-job.h>
 #include <thunar-vfs/thunar-vfs-mime.h>
 #include <thunar-vfs/thunar-vfs-monitor.h>
 #include <thunar-vfs/thunar-vfs-trash.h>
diff --git a/thunar/thunar-local-folder.c b/thunar/thunar-local-folder.c
index b85c7401323a5669f26fb1f953794b8a325629dd..98a5b70fadcf8b5fe3abaf583150636de587b940 100644
--- a/thunar/thunar-local-folder.c
+++ b/thunar/thunar-local-folder.c
@@ -390,7 +390,7 @@ thunar_local_folder_get_for_file (ThunarLocalFile *local_file,
       g_object_set_data (G_OBJECT (local_file), "thunar-local-folder", local_folder);
 
       /* schedule the loading of the folder */
-      local_folder->job = thunar_vfs_job_listdir_new (thunar_file_get_uri (THUNAR_FILE (local_file)));
+      local_folder->job = thunar_vfs_listdir_job_new (thunar_file_get_uri (THUNAR_FILE (local_file)));
       g_signal_connect (local_folder->job, "error-occurred", G_CALLBACK (thunar_local_folder_error_occurred), local_folder);
       g_signal_connect (local_folder->job, "infos-ready", G_CALLBACK (thunar_local_folder_infos_ready), local_folder);
       g_signal_connect (local_folder->job, "finished", G_CALLBACK (thunar_local_folder_finished), local_folder);