diff --git a/ChangeLog b/ChangeLog
index 00f49321c3db718f7192cbd7ee18254956685615..ccb465417cb62d64b523f6bedaf8861388d2bffe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2006-02-06	Benedikt Meurer <benny@xfce.org>
+
+	* thunar-vfs/thunar-vfs-chmod-job.c, thunar-vfs/thunar-vfs-chown-job.c,
+	  thunar-vfs/thunar-vfs-listdir-job.c, thunar-vfs/thunar-vfs-scandir.c,
+	  thunar-vfs/thunar-vfs-scandir.h, thunar-vfs/thunar-vfs-transfer-job.c,
+	  thunar-vfs/thunar-vfs-unlink-job.c: The directory scanning is now
+	  cancelable. Bug #1239.
+	* thunar/thunar-icon-factory.c: Properly reload/regenerate thumbnails
+	  when image files are changed. Bug #1435.
+	* thunar-vfs/thunar-vfs-mime-application.c
+	  (thunar_vfs_mime_application_new_from_file): Check TryExec (or Exec)
+	  first prior to allocating a ThunarVfsMimeApplication for a .desktop
+	  file, whose associated program cannot be run. Bug #1436.
+
 2006-02-06	Benedikt Meurer <benny@xfce.org>
 
 	* thunar/thunar-standard-view.c: Autoscroll while dragging to a
diff --git a/thunar-vfs/thunar-vfs-chmod-job.c b/thunar-vfs/thunar-vfs-chmod-job.c
index 60eec75dafd1236e57911c24e02c331c2f839a39..927a7eac2b943cc004861af2ede5ff8e96127815 100644
--- a/thunar-vfs/thunar-vfs-chmod-job.c
+++ b/thunar-vfs/thunar-vfs-chmod-job.c
@@ -169,7 +169,7 @@ thunar_vfs_chmod_job_execute (ThunarVfsJob *job)
 
   /* check if we should operate recursively and collect the paths */
   if (G_UNLIKELY (chmod_job->recursive))
-    path_list = thunar_vfs_scandir (chmod_job->path, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, NULL);
+    path_list = thunar_vfs_scandir (chmod_job->path, &job->cancelled, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, NULL);
   path_list = thunar_vfs_path_list_prepend (path_list, chmod_job->path);
 
   /* determine the total number of paths (atleast one!) */
diff --git a/thunar-vfs/thunar-vfs-chown-job.c b/thunar-vfs/thunar-vfs-chown-job.c
index af54ee0bb75663acf704e5894f8a557a94c0518a..9b47de8e3adf0db79f899708cd0594b4daed744b 100644
--- a/thunar-vfs/thunar-vfs-chown-job.c
+++ b/thunar-vfs/thunar-vfs-chown-job.c
@@ -167,7 +167,7 @@ thunar_vfs_chown_job_execute (ThunarVfsJob *job)
 
   /* check if we should operate recursively and collect the paths */
   if (G_UNLIKELY (chown_job->recursive))
-    path_list = thunar_vfs_scandir (chown_job->path, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, NULL);
+    path_list = thunar_vfs_scandir (chown_job->path, &job->cancelled, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, NULL);
   path_list = thunar_vfs_path_list_prepend (path_list, chown_job->path);
 
   /* determine the total number of paths (atleast one!) */
diff --git a/thunar-vfs/thunar-vfs-listdir-job.c b/thunar-vfs/thunar-vfs-listdir-job.c
index 119ea85d416f8e3192392e09329a6ff2a0a04de4..9657531732aad5f7cd1f722434483149fe4d2afe 100644
--- a/thunar-vfs/thunar-vfs-listdir-job.c
+++ b/thunar-vfs/thunar-vfs-listdir-job.c
@@ -179,7 +179,7 @@ thunar_vfs_listdir_job_execute (ThunarVfsJob *job)
   guint        n;
 
   /* scan the given directory */
-  list = thunar_vfs_scandir (THUNAR_VFS_LISTDIR_JOB (job)->path, THUNAR_VFS_SCANDIR_FOLLOW_LINKS, pathcmp, &error);
+  list = thunar_vfs_scandir (THUNAR_VFS_LISTDIR_JOB (job)->path, &job->cancelled, THUNAR_VFS_SCANDIR_FOLLOW_LINKS, pathcmp, &error);
   if (G_LIKELY (list != NULL))
     {
       for (lp = hp = list, n = 0; lp != NULL; lp = lp->next, ++n)
diff --git a/thunar-vfs/thunar-vfs-mime-application.c b/thunar-vfs/thunar-vfs-mime-application.c
index e7463883f05a4886ddae01749afe6af116ae78da..e194ad6f45c4c24f5d84e699e370384da11a96a8 100644
--- a/thunar-vfs/thunar-vfs-mime-application.c
+++ b/thunar-vfs/thunar-vfs-mime-application.c
@@ -199,9 +199,11 @@ thunar_vfs_mime_application_new_from_file (const gchar *path,
   ThunarVfsMimeHandlerFlags flags = 0;
   ThunarVfsMimeApplication *application = NULL;
   ThunarVfsMimeAction      *action;
+  const gchar              *tryexec;
   const gchar              *exec;
   const gchar              *icon;
   const gchar              *name;
+  gboolean                  present;
   XfceRc                   *rc;
   gchar                    *command;
   gchar                   **actions;
@@ -224,6 +226,33 @@ thunar_vfs_mime_application_new_from_file (const gchar *path,
   exec = xfce_rc_read_entry_untranslated (rc, "Exec", NULL);
   icon = xfce_rc_read_entry_untranslated (rc, "Icon", NULL);
 
+  /* check if we have a TryExec field */
+  tryexec = xfce_rc_read_entry_untranslated (rc, "TryExec", NULL);
+  tryexec = (tryexec != NULL) ? tryexec : exec;
+  if (G_LIKELY (tryexec != NULL && g_shell_parse_argv (tryexec, NULL, &mt, NULL)))
+    {
+      /* check if we have an absolute path to an existing file */
+      present = g_file_test (mt[0], G_FILE_TEST_EXISTS);
+
+      /* else, we may have a program in $PATH */
+      if (G_LIKELY (!present))
+        {
+          command = g_find_program_in_path (mt[0]);
+          present = (command != NULL);
+          g_free (command);
+        }
+
+      /* cleanup */
+      g_strfreev (mt);
+
+      /* if the program is not present, there's no reason to allocate a MimeApplication for it */
+      if (G_UNLIKELY (!present))
+        {
+          xfce_rc_close (rc);
+          return NULL;
+        }
+    }
+
   /* generate the application object */
   if (G_LIKELY (exec != NULL && name != NULL && g_utf8_validate (name, -1, NULL)))
     {
diff --git a/thunar-vfs/thunar-vfs-scandir.c b/thunar-vfs/thunar-vfs-scandir.c
index 442a2693d725260db0204417831c3de311aac4eb..70fbd95158e880e50033e663deaa939cb56e11e5 100644
--- a/thunar-vfs/thunar-vfs-scandir.c
+++ b/thunar-vfs/thunar-vfs-scandir.c
@@ -89,6 +89,7 @@ static gboolean thunar_vfs_scandir_collect_slow (ThunarVfsScandirHandle *handle,
                                                  ThunarVfsPath          *path,
                                                  GList                 **directoriesp);
 static gboolean thunar_vfs_scandir_collect      (ThunarVfsScandirHandle *handle,
+                                                 volatile gboolean      *cancelled,
                                                  ThunarVfsPath          *path);
 
 
@@ -374,6 +375,7 @@ error:
 
 static gboolean
 thunar_vfs_scandir_collect (ThunarVfsScandirHandle *handle,
+                            volatile gboolean      *cancelled,
                             ThunarVfsPath          *path)
 {
   gboolean succeed = FALSE;
@@ -402,7 +404,16 @@ thunar_vfs_scandir_collect (ThunarVfsScandirHandle *handle,
       /* perform the recursion */
       for (lp = directories; lp != NULL && succeed; lp = lp->next)
         {
-          succeed = thunar_vfs_scandir_collect (handle, lp->data);
+          /* check if the user cancelled the scanning */
+          if (G_UNLIKELY (cancelled != NULL && *cancelled))
+            {
+              succeed = FALSE;
+              errno = EINTR;
+              break;
+            }
+
+          /* collect the files for this directory */
+          succeed = thunar_vfs_scandir_collect (handle, cancelled, lp->data);
           if (G_UNLIKELY (!succeed))
             {
               /* we can ignore certain errors here */
@@ -425,6 +436,10 @@ thunar_vfs_scandir_collect (ThunarVfsScandirHandle *handle,
 /**
  * thunar_vfs_scandir:
  * @path
+ * @cancelled : pointer to a volatile boolean variable, which if
+ *              %TRUE means to cancel the scan operation. May be
+ *              %NULL in which case the scanner cannot be
+ *              cancelled.
  * @flags
  * @func
  * @error     : return location for errors or %NULL.
@@ -433,10 +448,14 @@ thunar_vfs_scandir_collect (ThunarVfsScandirHandle *handle,
  * using thunar_vfs_path_list_free() when no longer
  * needed.
  *
+ * If @cancelled becomes true during the scan operation, %NULL
+ * will be returned and @error will be set to %G_FILE_ERROR_INTR.
+ *
  * Return value:
  **/
 GList*
 thunar_vfs_scandir (ThunarVfsPath        *path,
+                    volatile gboolean    *cancelled,
                     ThunarVfsScandirFlags flags,
                     GCompareFunc          func,
                     GError              **error)
@@ -452,7 +471,7 @@ thunar_vfs_scandir (ThunarVfsPath        *path,
   handle.path_list = NULL;
 
   /* collect the paths */
-  if (!thunar_vfs_scandir_collect (&handle, path))
+  if (!thunar_vfs_scandir_collect (&handle, cancelled, path))
     {
       /* forward the error */
       g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), g_strerror (errno));
diff --git a/thunar-vfs/thunar-vfs-scandir.h b/thunar-vfs/thunar-vfs-scandir.h
index 72ad4e4ed5064326e41c40ec9fc19425267ae0a3..b931c761a91d3deeb119416363ed72471ddb42b2 100644
--- a/thunar-vfs/thunar-vfs-scandir.h
+++ b/thunar-vfs/thunar-vfs-scandir.h
@@ -37,6 +37,7 @@ typedef enum /*< flags >*/
 } ThunarVfsScandirFlags;
 
 GList *thunar_vfs_scandir       (ThunarVfsPath        *path,
+                                 volatile gboolean    *cancelled,
                                  ThunarVfsScandirFlags flags,
                                  GCompareFunc          func,
                                  GError              **error) G_GNUC_INTERNAL;
diff --git a/thunar-vfs/thunar-vfs-transfer-job.c b/thunar-vfs/thunar-vfs-transfer-job.c
index ea84a8a2088ad2bc83286e0d64737254814fc8ac..49ceb6955115ccc7f9b0b8492cc823ed950376d6 100644
--- a/thunar-vfs/thunar-vfs-transfer-job.c
+++ b/thunar-vfs/thunar-vfs-transfer-job.c
@@ -535,7 +535,7 @@ thunar_vfs_transfer_job_collect_pairs (ThunarVfsTransferJob  *transfer_job,
     return NULL;
 
   /* scan the pair directory */
-  paths = thunar_vfs_scandir (pair->source_path, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, &serror);
+  paths = thunar_vfs_scandir (pair->source_path, &THUNAR_VFS_JOB (transfer_job)->cancelled, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, &serror);
   if (G_UNLIKELY (serror != NULL))
     {
       g_propagate_error (error, serror);
diff --git a/thunar-vfs/thunar-vfs-unlink-job.c b/thunar-vfs/thunar-vfs-unlink-job.c
index b84a02a9cd8995808c14e2fec44a67b0c82f002d..0b38416759e135c8cee5242b1bb95d96ac3f5178 100644
--- a/thunar-vfs/thunar-vfs-unlink-job.c
+++ b/thunar-vfs/thunar-vfs-unlink-job.c
@@ -165,7 +165,7 @@ thunar_vfs_unlink_job_execute (ThunarVfsJob *job)
   for (lp = unlink_job->path_list; lp != NULL && !thunar_vfs_job_cancelled (job); lp = lp->next)
     {
       /* scan the directory */
-      paths = thunar_vfs_scandir (lp->data, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, &error);
+      paths = thunar_vfs_scandir (lp->data, &job->cancelled, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, &error);
       if (G_UNLIKELY (error != NULL))
         {
           /* we can safely ignore ENOTDIR errors here */
diff --git a/thunar/thunar-icon-factory.c b/thunar/thunar-icon-factory.c
index bbbdda672ac6c1b017c8769f359809ebdb32bc30..1b1b31af2d4d8690f76813f28befcd8bb86a3c4d 100644
--- a/thunar/thunar-icon-factory.c
+++ b/thunar/thunar-icon-factory.c
@@ -133,6 +133,8 @@ struct _ThunarIconKey
 
 static GObjectClass *thunar_icon_factory_parent_class = NULL;
 static GQuark        thunar_icon_factory_quark = 0;
+static GQuark        thunar_icon_thumb_path_quark = 0;
+static GQuark        thunar_icon_thumb_time_quark = 0;
 static GQuark        thunar_file_thumb_path_quark = 0;
 
 
@@ -174,6 +176,10 @@ thunar_icon_factory_class_init (ThunarIconFactoryClass *klass)
   /* determine the parent type class */
   thunar_icon_factory_parent_class = g_type_class_peek_parent (klass);
 
+  /* setup the thunar-icon-thumb-{path,time} quarks */
+  thunar_icon_thumb_path_quark = g_quark_from_static_string ("thunar-icon-thumb-path");
+  thunar_icon_thumb_time_quark = g_quark_from_static_string ("thunar-icon-thumb-time");
+
   /* setup the thunar-file-thumb-path quark */
   thunar_file_thumb_path_quark = g_quark_from_static_string ("thunar-file-thumb-path");
 
@@ -837,7 +843,10 @@ thunar_icon_factory_load_file_icon (ThunarIconFactory  *factory,
                                     gint                icon_size)
 {
   ThunarFileThumbState thumb_state;
+  ThunarVfsFileTime    time;
   ThunarVfsInfo       *info;
+  ThunarVfsPath       *path;
+  ThunarIconKey        key;
   const gchar         *icon_name;
   GdkPixbuf           *icon;
   gchar               *thumb_path;
@@ -865,6 +874,7 @@ thunar_icon_factory_load_file_icon (ThunarIconFactory  *factory,
       /* check if we haven't yet determine the thumbnail state */
       if (thumb_state == THUNAR_FILE_THUMB_STATE_UNKNOWN)
         {
+again:
           /* determine the ThunarVfsInfo for the file */
           info = thunar_file_get_info (file);
 
@@ -913,10 +923,46 @@ thunar_icon_factory_load_file_icon (ThunarIconFactory  *factory,
           thumb_path = g_object_get_qdata (G_OBJECT (file), thunar_file_thumb_path_quark);
           if (G_LIKELY (thumb_path != NULL))
             {
-              // FIXME: Check mtime and URI for the returned icon
+              /* try to load the thumbnail for the given path */
               icon = thunar_icon_factory_lookup_icon (factory, thumb_path, icon_size, FALSE);
               if (G_LIKELY (icon != NULL))
-                return icon;
+                {
+                  /* determine the VFS info for the file */
+                  info = thunar_file_get_info (file);
+
+                  /* determine mtime and path for the thumbnail */
+                  path = g_object_get_qdata (G_OBJECT (icon), thunar_icon_thumb_path_quark);
+                  time = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (icon), thunar_icon_thumb_time_quark));
+
+                  /* check if mtime and path was already associated with the thumbnail */
+                  if (G_UNLIKELY (path == NULL))
+                    {
+                      /* just save mtime and path for the thumbnail */
+                      g_object_set_qdata_full (G_OBJECT (icon), thunar_icon_thumb_path_quark,
+                                               thunar_vfs_path_ref (info->path),
+                                               (GDestroyNotify) thunar_vfs_path_unref);
+                      g_object_set_qdata (G_OBJECT (icon), thunar_icon_thumb_time_quark,
+                                          GUINT_TO_POINTER (info->mtime));
+                    }
+                  else if (G_UNLIKELY (time != info->mtime || !thunar_vfs_path_equal (path, info->path)))
+                    {
+                      /* the thumbnail is no longer valid, remove it from our internal cache */
+                      key.name = thumb_path;
+                      key.size = icon_size;
+
+                      /* try to remove based on the key */
+                      if (g_hash_table_remove (factory->icon_cache, &key))
+                        {
+                          /* we only restart the operation if we were successfull, else we could recurse infinitely */
+                          thumb_state = THUNAR_FILE_THUMB_STATE_UNKNOWN;
+                          g_object_unref (G_OBJECT (icon));
+                          goto again;
+                        }
+                    }
+
+                  /* ok, we have a valid thumbnail */
+                  return icon;
+                }
             }
         }