+ AtkObject *current, *tmp;
+ GQueue *stack;
+ GList *uplist = NULL;
+ guint i, ref;
+ gboolean recurse;
+
+ stack = g_queue_new ();
+
+ current = g_object_ref (accessible);
+ ref = export (&uplist, current);
+ g_queue_push_head (stack, GINT_TO_POINTER (0));
+
+ /*
+ * The index held on the stack is the next child node
+ * that needs processing at the corresponding level in the tree.
+ */
+ while (!g_queue_is_empty (stack))
+ {
+ /* This while loop finds the next node that needs processing,
+ * if one exists.
+ */
+ i = GPOINTER_TO_INT(g_queue_peek_head (stack));
+ recurse = FALSE;
+ while (i < atk_object_get_n_accessible_children (current) &&
+ recurse == FALSE)
+ {
+ tmp = atk_object_ref_accessible_child (current, i);
+ if (!atk_dbus_object_to_ref (tmp))
+ {
+ recurse = TRUE;
+ }
+ else
+ {
+ i++;
+ g_object_unref (G_OBJECT (tmp));
+ }
+ }
+ if (recurse)
+ {
+ /* Still children to process */
+ current = tmp;
+ export (&uplist, current);
+ /* Update parent nodes next child index */
+ g_queue_peek_head_link (stack)->data = GINT_TO_POINTER (i+1);
+ /* Push a new child index for the current node */
+ g_queue_push_head (stack, GINT_TO_POINTER (0));
+ }
+ else
+ {
+ /* No more children, move to parent */
+ tmp = current;
+ current = atk_object_get_parent (current);
+ g_object_unref (G_OBJECT (tmp));
+ g_queue_pop_head (stack);
+ }
+ }
+ spi_emit_cache_update (uplist, atk_adaptor_app_data->bus);
+ g_list_free (uplist);
+ return ref;