diff --git a/ChangeLog b/ChangeLog
index 94d07f7f4b2b06b647830d1470c7f18ffd88ac78..4baff12d67cc90af6f37ae64959fdfff15ade43b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-12-28	Benedikt Meurer <benny@xfce.org>
+
+	* thunar/: Several improvements to the GtkTreeModel implementations
+	  that should further speed up loading really large folders. For the
+	  icon view, the real bottleneck is still Pango.
+
 2006-12-21	Benedikt Meurer <benny@xfce.org>
 
 	* thunar-vfs/Makefile.am, thunar-vfs/thunar-vfs.c: Apply Brian's
diff --git a/thunar/thunar-column-model.c b/thunar/thunar-column-model.c
index 1694d89a1f522c267d5b9b426b2e226f5c77847f..d458da3b6c677e79dd7f8a4ed5ebb7ef91fdd6b8 100644
--- a/thunar/thunar-column-model.c
+++ b/thunar/thunar-column-model.c
@@ -103,11 +103,18 @@ struct _ThunarColumnModel
 {
   GObject __parent__;
 
+  /* the model stamp is only used when debugging is
+   * enabled, to make sure we don't accept iterators
+   * generated by another model.
+   */
+#ifndef NDEBUG
+  guint              stamp;
+#endif
+
   ThunarPreferences *preferences;
   ThunarColumn       order[THUNAR_N_VISIBLE_COLUMNS];
   gboolean           visible[THUNAR_N_VISIBLE_COLUMNS];
   gint               width[THUNAR_N_VISIBLE_COLUMNS];
-  guint              stamp;
 };
 
 
@@ -216,8 +223,10 @@ thunar_column_model_init (ThunarColumnModel *column_model)
   g_signal_connect (G_OBJECT (column_model->preferences), "notify::last-details-view-visible-columns",
                     G_CALLBACK (thunar_column_model_notify_visible_columns), column_model);
 
-  /* generate a random stamp */
+  /* generate a random stamp if we're in debug mode */
+#ifndef NDEBUG
   column_model->stamp = g_random_int ();
+#endif
 
   /* load the column order */
   thunar_column_model_load_column_order (column_model);
@@ -300,9 +309,7 @@ thunar_column_model_get_iter (GtkTreeModel *tree_model,
     return FALSE;
 
   /* generate an iterator */
-  iter->stamp = column_model->stamp;
-  iter->user_data = GINT_TO_POINTER (column);
-
+  GTK_TREE_ITER_INIT (*iter, column_model->stamp, GINT_TO_POINTER (column));
   return TRUE;
 }
 
@@ -395,8 +402,8 @@ thunar_column_model_iter_children (GtkTreeModel *tree_model,
 
   if (G_LIKELY (parent == NULL))
     {
-      iter->stamp = column_model->stamp;
-      iter->user_data = GINT_TO_POINTER (0);
+      GTK_TREE_ITER_INIT (*iter, column_model->stamp, GINT_TO_POINTER (0));
+      return TRUE;
     }
 
   return FALSE;
@@ -436,8 +443,7 @@ thunar_column_model_iter_nth_child (GtkTreeModel *tree_model,
 
   if (G_LIKELY (parent == NULL && n < THUNAR_N_VISIBLE_COLUMNS))
     {
-      iter->stamp = column_model->stamp;
-      iter->user_data = GINT_TO_POINTER (n);
+      GTK_TREE_ITER_INIT (*iter, column_model->stamp, GINT_TO_POINTER (n));
       return TRUE;
     }
 
diff --git a/thunar/thunar-list-model.c b/thunar/thunar-list-model.c
index bde729478f572e087b364dbfd261e39b3acd7b73..ef1ef1eac16ade0e5a7f355d72d11d70ead4847e 100644
--- a/thunar/thunar-list-model.c
+++ b/thunar/thunar-list-model.c
@@ -202,7 +202,14 @@ struct _ThunarListModel
 {
   GObject __parent__;
 
+  /* the model stamp is only used when debugging is
+   * enabled, to make sure we don't accept iterators
+   * generated by another model.
+   */
+#ifndef NDEBUG
   guint          stamp;
+#endif
+
   gint           nrows;
   GSList        *rows;
   GSList        *hidden;
@@ -439,7 +446,10 @@ thunar_list_model_sortable_init (GtkTreeSortableIface *iface)
 static void
 thunar_list_model_init (ThunarListModel *store)
 {
+  /* generate a unique stamp if we're in debug mode */
+#ifndef NDEBUG
   store->stamp                = g_random_int ();
+#endif
 
   store->volume_manager       = thunar_vfs_volume_manager_get_default ();
 
@@ -629,8 +639,7 @@ thunar_list_model_get_iter (GtkTreeModel *model,
   row = g_slist_nth (store->rows, gtk_tree_path_get_indices (path)[0]);
   if (G_LIKELY (row != NULL))
     {
-      iter->stamp = store->stamp;
-      iter->user_data = row;
+      GTK_TREE_ITER_INIT (*iter, store->stamp, row);
       return TRUE;
     }
 
@@ -797,8 +806,7 @@ thunar_list_model_iter_children (GtkTreeModel *model,
 
   if (G_LIKELY (parent == NULL && store->rows != NULL))
     {
-      iter->stamp = store->stamp;
-      iter->user_data = store->rows;
+      GTK_TREE_ITER_INIT (*iter, store->stamp, store->rows);
       return TRUE;
     }
 
@@ -841,8 +849,7 @@ thunar_list_model_iter_nth_child (GtkTreeModel *model,
 
   if (G_LIKELY (parent == NULL))
     {
-      iter->stamp = store->stamp;
-      iter->user_data = g_slist_nth (store->rows, n);
+      GTK_TREE_ITER_INIT (*iter, store->stamp, g_slist_nth (store->rows, n));
       return (iter->user_data != NULL);
     }
 
@@ -1107,13 +1114,14 @@ thunar_list_model_remove (ThunarListModel *store,
 
   if (next != NULL)
     {
-      iter->stamp = store->stamp;
-      iter->user_data = next;
+      GTK_TREE_ITER_INIT (*iter, store->stamp, next);
       return TRUE;
     }
   else
     {
+#ifndef NDEBUG
       iter->stamp = 0;
+#endif
       return FALSE;
     }
 }
@@ -1205,8 +1213,7 @@ thunar_list_model_file_changed (ThunarFileMonitor *file_monitor,
     if (G_UNLIKELY (row->data == file))
       {
         /* generate the iterator for this row */
-        iter.stamp = store->stamp;
-        iter.user_data = row;
+        GTK_TREE_ITER_INIT (iter, store->stamp, row);
 
         /* notify the view that it has to redraw the file */
         path = gtk_tree_path_new_from_indices (n, -1);
@@ -1269,9 +1276,18 @@ thunar_list_model_files_added (ThunarFolder    *folder,
   ThunarFile  *file;
   GSList      *prev = NULL;
   GSList      *row;
+  gint        *indices;
   gint         index = 0;
 
-  // TODO: pre-sort files to get faster insert?!
+  /* we use a simple trick here to avoid allocating
+   * GtkTreePath's again and again, by simply accessing
+   * the indices directly and only modifying the first
+   * item in the integer array... looks a hack, eh?
+   */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  indices = gtk_tree_path_get_indices (path);
+
+  /* process all added files */
   for (; files != NULL; files = files->next)
     {
       /* take a reference on that file */
@@ -1285,6 +1301,7 @@ thunar_list_model_files_added (ThunarFolder    *folder,
         }
       else
         {
+          /* allocate a new row */
           row = g_slist_alloc ();
           row->data = file;
 
@@ -1318,15 +1335,18 @@ thunar_list_model_files_added (ThunarFolder    *folder,
 
           store->nrows += 1;
 
-          iter.stamp = store->stamp;
-          iter.user_data = row;
+          /* generate an iterator for the new item */
+          GTK_TREE_ITER_INIT (iter, store->stamp, row);
 
-          path = gtk_tree_path_new_from_indices (index, -1);
+          /* tell the view about the new item */
+          indices[0] = index;
           gtk_tree_model_row_inserted (GTK_TREE_MODEL (store), path, &iter);
-          gtk_tree_path_free (path);
         }
     }
 
+  /* release the path */
+  gtk_tree_path_free (path);
+
   /* number of visible files may have changed */
   g_object_notify (G_OBJECT (store), "num-files");
 }
@@ -1353,8 +1373,7 @@ thunar_list_model_files_removed (ThunarFolder    *folder,
       for (row = store->rows; row != NULL; row = row->next)
         if (row->data == file)
           {
-            iter.stamp = store->stamp;
-            iter.user_data = row;
+            GTK_TREE_ITER_INIT (iter, store->stamp, row);
             thunar_list_model_remove (store, &iter, FALSE);
             break;
           }
@@ -1754,9 +1773,8 @@ thunar_list_model_set_folder (ThunarListModel *store,
           /* sort the files before inserting them into the model */
           files = g_list_sort_with_data (files, thunar_list_model_cmp_list, store);
 
-          /* setup path/iter for "row-inserted" */
+          /* setup path for "row-inserted" */
           path = gtk_tree_path_new_from_indices (0, -1);
-          iter.stamp = store->stamp;
 
           /* insert the files */
           for (lp = files; lp != NULL; lp = lp->next)
@@ -1783,7 +1801,7 @@ thunar_list_model_set_folder (ThunarListModel *store,
                   if (G_UNLIKELY (has_handler))
                     {
                       /* update the iter for the new row */
-                      iter.user_data = row;
+                      GTK_TREE_ITER_INIT (iter, store->stamp, row);
 
                       /* tell the view about the new row */
                       gtk_tree_model_row_inserted (GTK_TREE_MODEL (store), path, &iter);
@@ -1921,8 +1939,7 @@ thunar_list_model_set_show_hidden (ThunarListModel *store,
 
           store->nrows += 1;
 
-          iter.stamp = store->stamp;
-          iter.user_data = row;
+          GTK_TREE_ITER_INIT (iter, store->stamp, row);
 
           path = thunar_list_model_get_path (GTK_TREE_MODEL (store), &iter);
           gtk_tree_model_row_inserted (GTK_TREE_MODEL (store), path, &iter);
@@ -1947,8 +1964,7 @@ thunar_list_model_set_show_hidden (ThunarListModel *store,
         {
           for (lp = hidden_rows; lp != NULL; lp = lp->next)
             {
-              iter.stamp = store->stamp;
-              iter.user_data = lp->data;
+              GTK_TREE_ITER_INIT (iter, store->stamp, lp->data);
               thunar_list_model_remove (store, &iter, FALSE);
             }
           g_slist_free (hidden_rows);
diff --git a/thunar/thunar-private.h b/thunar/thunar-private.h
index f37bb2d4c37560d48c9b8c086151a2fa13a1d48c..08aa2b20e07b70455b1dbff10d8403df294750d0 100644
--- a/thunar/thunar-private.h
+++ b/thunar/thunar-private.h
@@ -77,6 +77,20 @@ G_BEGIN_DECLS;
 #define g_value_get_object(v)   (((const GValue *) (v))->data[0].v_pointer)
 #endif
 
+/* support macros for the GtkTreeModel implementations */
+#ifndef NDEBUG
+#define GTK_TREE_ITER_INIT(iter, iter_stamp, iter_user_data)  \
+G_STMT_START{                                                 \
+  (iter).stamp = iter_stamp;                                  \
+  (iter).user_data = iter_user_data;                          \
+}G_STMT_END
+#else
+#define GTK_TREE_ITER_INIT(iter, iter_stamp, iter_user_data)  \
+G_STMT_START{                                                 \
+  (iter).user_data = iter_user_data;                          \
+}G_STMT_END
+#endif
+
 G_END_DECLS;
 
 #endif /* !__THUNAR_PRIVATE_H__ */
diff --git a/thunar/thunar-renamer-model.c b/thunar/thunar-renamer-model.c
index 356c41e8acae74864b78472b19d8c202e80470fd..6bda79ae478f6d93e548339bfe00571e46d9c868 100644
--- a/thunar/thunar-renamer-model.c
+++ b/thunar/thunar-renamer-model.c
@@ -125,17 +125,25 @@ struct _ThunarRenamerModelClass
 struct _ThunarRenamerModel
 {
   GObject            __parent__;
+
+  /* the model stamp is only used when debugging is
+   * enabled, to make sure we don't accept iterators
+   * generated by another model.
+   */
+#ifndef NDEBUG
+  guint              stamp;
+#endif
+
   ThunarRenamerMode  mode;
   ThunarFileMonitor *file_monitor;
   ThunarxRenamer    *renamer;
   GList             *items;
-  guint              stamp;
 
   /* TRUE if the model is currently frozen */
   gboolean           frozen;
 
   /* the idle source used to update the model */
-  gint               update_idle_id;
+  guint              update_idle_id;
 };
 
 struct _ThunarRenamerModelItem
@@ -286,8 +294,10 @@ thunar_renamer_model_tree_model_init (GtkTreeModelIface *iface)
 static void
 thunar_renamer_model_init (ThunarRenamerModel *renamer_model)
 {
+  /* generate a unique if we're in debug mode */
+#ifndef NDEBUG
   renamer_model->stamp = g_random_int ();
-  renamer_model->update_idle_id = -1;
+#endif
 
   /* connect to the file monitor */
   renamer_model->file_monitor = thunar_file_monitor_get_default ();
@@ -317,7 +327,7 @@ thunar_renamer_model_finalize (GObject *object)
   g_object_unref (G_OBJECT (renamer_model->file_monitor));
 
   /* be sure to cancel any pending update idle source (must be last!) */
-  if (G_UNLIKELY (renamer_model->update_idle_id >= 0))
+  if (G_UNLIKELY (renamer_model->update_idle_id != 0))
     g_source_remove (renamer_model->update_idle_id);
 
   (*G_OBJECT_CLASS (thunar_renamer_model_parent_class)->finalize) (object);
@@ -445,8 +455,7 @@ thunar_renamer_model_get_iter (GtkTreeModel *tree_model,
   lp = g_list_nth (renamer_model->items, gtk_tree_path_get_indices (path)[0]);
   if (G_LIKELY (lp != NULL))
     {
-      iter->stamp = renamer_model->stamp;
-      iter->user_data = lp;
+      GTK_TREE_ITER_INIT (*iter, renamer_model->stamp, lp);
       return TRUE;
     }
 
@@ -547,8 +556,7 @@ thunar_renamer_model_iter_children (GtkTreeModel *tree_model,
 
   if (G_LIKELY (parent == NULL && renamer_model->items != NULL))
     {
-      iter->stamp = renamer_model->stamp;
-      iter->user_data = renamer_model->items;
+      GTK_TREE_ITER_INIT (*iter, renamer_model->stamp, renamer_model->items);
       return TRUE;
     }
 
@@ -587,8 +595,7 @@ thunar_renamer_model_iter_nth_child (GtkTreeModel *tree_model,
 
   if (G_LIKELY (parent == NULL))
     {
-      iter->stamp = renamer_model->stamp;
-      iter->user_data = g_list_nth (renamer_model->items, n);
+      GTK_TREE_ITER_INIT (*iter, renamer_model->stamp, g_list_nth (renamer_model->items, n));
       return (iter->user_data != NULL);
     }
 
@@ -647,8 +654,7 @@ thunar_renamer_model_file_changed (ThunarRenamerModel *renamer_model,
           }
 
         /* determine the iter for the item */
-        iter.stamp = renamer_model->stamp;
-        iter.user_data = lp;
+        GTK_TREE_ITER_INIT (iter, renamer_model->stamp, lp);
 
         /* emit "row-changed" to display up2date file name */
         path = gtk_tree_model_get_path (GTK_TREE_MODEL (renamer_model), &iter);
@@ -720,7 +726,7 @@ thunar_renamer_model_invalidate_item (ThunarRenamerModel     *renamer_model,
   item->dirty = TRUE;
 
   /* check if the update idle source is already running and not frozen */
-  if (G_UNLIKELY (renamer_model->update_idle_id < 0 && !renamer_model->frozen))
+  if (G_UNLIKELY (renamer_model->update_idle_id == 0 && !renamer_model->frozen))
     {
       /* schedule the update idle source */
       renamer_model->update_idle_id = g_idle_add_full (G_PRIORITY_LOW, thunar_renamer_model_update_idle,
@@ -780,8 +786,7 @@ thunar_renamer_model_conflict_item (ThunarRenamerModel     *renamer_model,
               oitem->conflict = TRUE;
 
               /* determine iter for other item */
-              iter.stamp = renamer_model->stamp;
-              iter.user_data = lp;
+              GTK_TREE_ITER_INIT (iter, renamer_model->stamp, lp);
 
               /* emit "row-changed" for the other item */
               path = gtk_tree_model_get_path (GTK_TREE_MODEL (renamer_model), &iter);
@@ -953,8 +958,7 @@ thunar_renamer_model_update_idle (gpointer user_data)
           if (G_LIKELY (changed))
             {
               /* generate the iter for the item */
-              iter.stamp = renamer_model->stamp;
-              iter.user_data = lp;
+              GTK_TREE_ITER_INIT (iter, renamer_model->stamp, lp);
 
               /* emit "row-changed" for this item */
               path = gtk_tree_path_new_from_indices (index, -1);
@@ -976,7 +980,7 @@ static void
 thunar_renamer_model_update_idle_destroy (gpointer user_data)
 {
   /* reset the update idle id... */
-  THUNAR_RENAMER_MODEL (user_data)->update_idle_id = -1;
+  THUNAR_RENAMER_MODEL (user_data)->update_idle_id = 0;
 
   /* ...and notify listeners */
   g_object_notify (G_OBJECT (user_data), "can-rename");
@@ -1047,7 +1051,7 @@ thunar_renamer_model_get_can_rename (ThunarRenamerModel *renamer_model)
 
   _thunar_return_val_if_fail (THUNAR_IS_RENAMER_MODEL (renamer_model), FALSE);
 
-  if (G_LIKELY (renamer_model->renamer != NULL && !renamer_model->frozen && renamer_model->update_idle_id < 0))
+  if (G_LIKELY (renamer_model->renamer != NULL && !renamer_model->frozen && renamer_model->update_idle_id == 0))
     {
       /* check if atleast one item has a new name and no conflicts exist */
       for (lp = renamer_model->items; lp != NULL; lp = lp->next)
@@ -1114,7 +1118,7 @@ thunar_renamer_model_set_frozen (ThunarRenamerModel *renamer_model,
       if (G_LIKELY (frozen))
         {
           /* cancel any pending update idle source */
-          if (G_UNLIKELY (renamer_model->update_idle_id >= 0))
+          if (G_UNLIKELY (renamer_model->update_idle_id != 0))
             g_source_remove (renamer_model->update_idle_id);
         }
       else
@@ -1275,8 +1279,7 @@ thunar_renamer_model_append (ThunarRenamerModel *renamer_model,
   renamer_model->items = g_list_append (renamer_model->items, item);
 
   /* determine the iterator for the new item */
-  iter.stamp = renamer_model->stamp;
-  iter.user_data = g_list_last (renamer_model->items);
+  GTK_TREE_ITER_INIT (iter, renamer_model->stamp, g_list_last (renamer_model->items));
 
   /* emit the "row-inserted" signal */
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (renamer_model), &iter);
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index 0fc03b9ea57a536d4a06845624bfc7e7e04a3ac2..5c96cfa9dc9b8bad9bd1a068f37c4084c1504d8a 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -131,7 +131,14 @@ struct _ThunarShortcutsModel
 {
   GObject __parent__;
 
+  /* the model stamp is only used when debugging is
+   * enabled, to make sure we don't accept iterators
+   * generated by another model.
+   */
+#ifndef NDEBUG
   guint                   stamp;
+#endif
+
   GList                  *shortcuts;
   GList                  *hidden_volumes;
   ThunarVfsVolumeManager *volume_manager;
@@ -257,7 +264,9 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model)
   GList           *lp;
   guint            n;
 
+#ifndef NDEBUG
   model->stamp = g_random_int ();
+#endif
 
   /* connect to the volume manager */
   model->volume_manager = thunar_vfs_volume_manager_get_default ();
@@ -444,8 +453,7 @@ thunar_shortcuts_model_get_iter (GtkTreeModel *tree_model,
   lp = g_list_nth (model->shortcuts, gtk_tree_path_get_indices (path)[0]);
   if (G_LIKELY (lp != NULL))
     {
-      iter->stamp = model->stamp;
-      iter->user_data = lp;
+      GTK_TREE_ITER_INIT (*iter, model->stamp, lp);
       return TRUE;
     }
 
@@ -564,8 +572,7 @@ thunar_shortcuts_model_iter_children (GtkTreeModel *tree_model,
 
   if (G_LIKELY (parent == NULL && model->shortcuts != NULL))
     {
-      iter->stamp = model->stamp;
-      iter->user_data = model->shortcuts;
+      GTK_TREE_ITER_INIT (*iter, model->stamp, model->shortcuts);
       return TRUE;
     }
 
@@ -608,8 +615,7 @@ thunar_shortcuts_model_iter_nth_child (GtkTreeModel *tree_model,
 
   if (G_LIKELY (parent == NULL))
     {
-      iter->stamp = model->stamp;
-      iter->user_data = g_list_nth (model->shortcuts, n);
+      GTK_TREE_ITER_INIT (*iter, model->stamp, g_list_nth (model->shortcuts, n));
       return (iter->user_data != NULL);
     }
 
@@ -956,8 +962,7 @@ thunar_shortcuts_model_file_changed (ThunarFile           *file,
       shortcut = THUNAR_SHORTCUT (lp->data);
       if (shortcut->file == file)
         {
-          iter.stamp = model->stamp;
-          iter.user_data = lp;
+          GTK_TREE_ITER_INIT (iter, model->stamp, lp);
 
           path = gtk_tree_path_new_from_indices (index, -1);
           gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
@@ -1072,8 +1077,7 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume      *volume,
       else
         {
           /* generate an iterator for the path */
-          iter.stamp = model->stamp;
-          iter.user_data = lp;
+          GTK_TREE_ITER_INIT (iter, model->stamp, lp);
 
           /* tell the view that the volume has changed in some way */
           path = gtk_tree_path_new_from_indices (index, -1);
@@ -1254,8 +1258,7 @@ thunar_shortcuts_model_iter_for_file (ThunarShortcutsModel *model,
       /* check if we have a file that matches */
       if (THUNAR_SHORTCUT (lp->data)->file == file)
         {
-          iter->stamp = model->stamp;
-          iter->user_data = lp;
+          GTK_TREE_ITER_INIT (*iter, model->stamp, lp);
           return TRUE;
         }
 
@@ -1266,8 +1269,7 @@ thunar_shortcuts_model_iter_for_file (ThunarShortcutsModel *model,
           mount_point = thunar_vfs_volume_get_mount_point (THUNAR_SHORTCUT (lp->data)->volume);
           if (G_LIKELY (mount_point != NULL && thunar_vfs_path_equal (mount_point, thunar_file_get_path (file))))
             {
-              iter->stamp = model->stamp;
-              iter->user_data = lp;
+              GTK_TREE_ITER_INIT (*iter, model->stamp, lp);
               return TRUE;
             }
         }
diff --git a/thunar/thunar-tree-model.c b/thunar/thunar-tree-model.c
index 0004276ca943b19995ff363dbd657e7851b53ec3..3b710e1279702b74fb69f0e1f3c7618ca59eb6d0 100644
--- a/thunar/thunar-tree-model.c
+++ b/thunar/thunar-tree-model.c
@@ -161,6 +161,14 @@ struct _ThunarTreeModel
 {
   GObject                 __parent__;
 
+  /* the model stamp is only used when debugging is
+   * enabled, to make sure we don't accept iterators
+   * generated by another model.
+   */
+#ifndef NDEBUG
+  guint                   stamp;
+#endif
+
   /* removable volumes */
   ThunarVfsVolumeManager *volume_manager;
   GList                  *hidden_volumes;
@@ -170,7 +178,6 @@ struct _ThunarTreeModel
   gboolean                sort_case_sensitive;
 
   GNode                  *root;
-  guint                   stamp;
 };
 
 struct _ThunarTreeModelItem
@@ -293,9 +300,13 @@ thunar_tree_model_init (ThunarTreeModel *model)
   GNode               *node;
   guint                n;
 
+  /* generate a unique stamp if we're in debug mode */
+#ifndef NDEBUG
+  model->stamp = g_random_int ();
+#endif
+
   /* initialize the model data */
   model->sort_case_sensitive = TRUE;
-  model->stamp = g_random_int ();
 
   /* connect to the file monitor */
   model->file_monitor = thunar_file_monitor_get_default ();
@@ -479,9 +490,7 @@ thunar_tree_model_get_iter (GtkTreeModel *tree_model,
   indices = gtk_tree_path_get_indices (path);
 
   /* initialize the parent iterator with the root element */
-  parent.stamp = model->stamp;
-  parent.user_data = model->root;
-
+  GTK_TREE_ITER_INIT (parent, model->stamp, model->root);
   if (!gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[0]))
     return FALSE;
 
@@ -528,8 +537,7 @@ thunar_tree_model_get_path (GtkTreeModel *tree_model,
   else
     {
       /* determine the iterator for the parent node */
-      tmp_iter.stamp = model->stamp;
-      tmp_iter.user_data = node->parent;
+      GTK_TREE_ITER_INIT (tmp_iter, model->stamp, node->parent);
 
       /* determine the path for the parent node */
       path = gtk_tree_model_get_path (tree_model, &tmp_iter);
@@ -654,8 +662,7 @@ thunar_tree_model_iter_children (GtkTreeModel *tree_model,
 
   if (G_LIKELY (children != NULL))
     {
-      iter->stamp = model->stamp;
-      iter->user_data = children;
+      GTK_TREE_ITER_INIT (*iter, model->stamp, children);
       return TRUE;
     }
 
@@ -705,8 +712,7 @@ thunar_tree_model_iter_nth_child (GtkTreeModel *tree_model,
   child = g_node_nth_child ((parent != NULL) ? parent->user_data : model->root, n);
   if (G_LIKELY (child != NULL))
     {
-      iter->stamp = model->stamp;
-      iter->user_data = child;
+      GTK_TREE_ITER_INIT (*iter, model->stamp, child);
       return TRUE;
     }
 
@@ -731,8 +737,7 @@ thunar_tree_model_iter_parent (GtkTreeModel *tree_model,
   parent = G_NODE (child->user_data)->parent;
   if (G_LIKELY (parent != model->root))
     {
-      iter->user_data = parent;
-      iter->stamp = model->stamp;
+      GTK_TREE_ITER_INIT (*iter, model->stamp, parent);
       return TRUE;
     }
   else
@@ -874,8 +879,7 @@ thunar_tree_model_sort (ThunarTreeModel *model,
     }
 
   /* determine the iterator for the parent node */
-  iter.stamp = model->stamp;
-  iter.user_data = node;
+  GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
   /* tell the view about the new item order */
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
@@ -938,8 +942,7 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume,
           node = g_node_insert_data_before (model->root, node, item);
 
           /* determine the iterator for the new node */
-          iter.stamp = model->stamp;
-          iter.user_data = node;
+          GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
           /* tell the view about the new node */
           path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
@@ -950,8 +953,7 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume,
           node = g_node_append_data (node, NULL);
 
           /* determine the iterator for the dummy node */
-          iter.stamp = model->stamp;
-          iter.user_data = node;
+          GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
           /* tell the view about the dummy node */
           path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
@@ -1016,8 +1018,7 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume,
               dummy = g_node_append_data (node, NULL);
 
               /* determine the iterator for the dummy node */
-              iter.stamp = model->stamp;
-              iter.user_data = dummy;
+              GTK_TREE_ITER_INIT (iter, model->stamp, dummy);
 
               /* tell the view about the dummy node */
               path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
@@ -1026,8 +1027,7 @@ thunar_tree_model_volume_changed (ThunarVfsVolume *volume,
             }
 
           /* generate an iterator for the item */
-          iter.stamp = model->stamp;
-          iter.user_data = node;
+          GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
           /* tell the view that the volume has changed in some way */
           path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
@@ -1072,8 +1072,7 @@ thunar_tree_model_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager,
   node = g_node_append_data (node, NULL);
 
   /* determine the iterator for the dummy node */
-  iter.stamp = model->stamp;
-  iter.user_data = node;
+  GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
   /* tell the view about the dummy node */
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
@@ -1306,8 +1305,7 @@ thunar_tree_model_item_files_added (ThunarTreeModelItem *item,
           child_node->data = child_item;
 
           /* determine the tree iter for the child */
-          child_iter.stamp = model->stamp;
-          child_iter.user_data = child_node;
+          GTK_TREE_ITER_INIT (child_iter, model->stamp, child_node);
 
           /* emit a "row-changed" for the new node */
           child_path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &child_iter);
@@ -1320,8 +1318,7 @@ thunar_tree_model_item_files_added (ThunarTreeModelItem *item,
           child_node = g_node_append_data (node, child_item);
 
           /* determine the tree iter for the child */
-          child_iter.stamp = model->stamp;
-          child_iter.user_data = child_node;
+          GTK_TREE_ITER_INIT (child_iter, model->stamp, child_node);
 
           /* emit a "row-inserted" for the new node */
           child_path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &child_iter);
@@ -1333,8 +1330,7 @@ thunar_tree_model_item_files_added (ThunarTreeModelItem *item,
       child_node = g_node_append_data (child_node, NULL);
 
       /* determine the tree iter for the dummy */
-      child_iter.stamp = model->stamp;
-      child_iter.user_data = child_node;
+      GTK_TREE_ITER_INIT (child_iter, model->stamp, child_node);
 
       /* emit a "row-inserted" for the dummy node */
       child_path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &child_iter);
@@ -1387,8 +1383,7 @@ thunar_tree_model_item_files_removed (ThunarTreeModelItem *item,
       if (G_UNLIKELY (node->children == NULL))
         {
           /* determine the iterator for the folder node */
-          iter.stamp = model->stamp;
-          iter.user_data = node;
+          GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
           /* emit "row-has-child-toggled" for the folder node */
           path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
@@ -1489,8 +1484,7 @@ thunar_tree_model_node_drop_dummy (GNode           *node,
   if (g_node_n_children (node) == 1 && node->children->data == NULL)
     {
       /* determine the iterator for the dummy */
-      iter.stamp = model->stamp;
-      iter.user_data = node->children;
+      GTK_TREE_ITER_INIT (iter, model->stamp, node->children);
 
       /* determine the path for the iterator */
       path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
@@ -1503,8 +1497,7 @@ thunar_tree_model_node_drop_dummy (GNode           *node,
           g_node_destroy (node->children);
 
           /* determine the iter to the parent node */
-          iter.stamp = model->stamp;
-          iter.user_data = node;
+          GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
           /* determine the path to the parent node */
           gtk_tree_path_up (path);
@@ -1536,8 +1529,7 @@ thunar_tree_model_node_traverse_changed (GNode   *node,
       model = THUNAR_TREE_MODEL_ITEM (node->data)->model;
 
       /* determine the iterator for the node */
-      iter.stamp = model->stamp;
-      iter.user_data = node;
+      GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
       /* check if the changed node is not one of the root nodes */
       if (G_LIKELY (node->parent != model->root))
@@ -1570,8 +1562,7 @@ thunar_tree_model_node_traverse_remove (GNode   *node,
   GtkTreePath     *path;
 
   /* determine the iterator for the node */
-  iter.stamp = model->stamp;
-  iter.user_data = node;
+  GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
   /* determine the path for the node */
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);