static gboolean
cached_dir_update_entry (CachedDir  *dir,
                         const char *basename,
                         const char *path)
{
  GSList *tmp;

  tmp = dir->entries;
  while (tmp != NULL)
    {
      const char *entry_basename;
      entry_basename = desktop_entry_get_basename (tmp->data);
      if (strcmp (entry_basename, basename) == 0)
        {
          if (!desktop_entry_reload (tmp->data))
	    {
	      dir->entries = g_slist_delete_link (dir->entries, tmp);
	    }

          return TRUE;
        }

      tmp = tmp->next;
    }

  return cached_dir_add_entry (dir, basename, path);
}
static DesktopEntry *
find_entry (CachedDir  *dir,
            const char *basename)
{
  GSList *tmp;

  tmp = dir->entries;
  while (tmp != NULL)
    {
      if (strcmp (desktop_entry_get_basename (tmp->data), basename) == 0)
        return tmp->data;

      tmp = tmp->next;
    }

  return NULL;
}
static gboolean
cached_dir_remove_entry (CachedDir  *dir,
                         const char *basename)
{
  GSList *tmp;

  tmp = dir->entries;
  while (tmp != NULL)
    {
      if (strcmp (desktop_entry_get_basename (tmp->data), basename) == 0)
        {
          desktop_entry_unref (tmp->data);
          dir->entries = g_slist_delete_link (dir->entries, tmp);
          return TRUE;
        }

      tmp = tmp->next;
    }

  return FALSE;
}
static gboolean
entry_directory_foreach_recursive (EntryDirectory            *ed,
                                   CachedDir                 *cd,
                                   GString                   *relative_path,
                                   EntryDirectoryForeachFunc  func,
                                   DesktopEntrySet           *set,
                                   gpointer                   user_data)
{
  GSList *tmp;
  int     relative_path_len;

  if (cd->deleted)
    return TRUE;

  relative_path_len = relative_path->len;

  tmp = cd->entries;
  while (tmp != NULL)
    {
      DesktopEntry *entry = tmp->data;

      if (desktop_entry_get_type (entry) == ed->entry_type)
        {
          gboolean    ret;
          char       *file_id;
          const char *basename;

          basename = desktop_entry_get_basename (entry);
          g_string_append (relative_path, basename);

	  file_id = get_desktop_file_id_from_path (ed,
						   ed->entry_type,
						   relative_path->str);

          ret = func (ed, entry, file_id, set, user_data);

          g_free (file_id);

          g_string_truncate (relative_path, relative_path_len);

          if (!ret)
            return FALSE;
        }

      tmp = tmp->next;
    }

  tmp = cd->subdirs;
  while (tmp != NULL)
    {
      CachedDir *subdir = tmp->data;

      g_string_append (relative_path, subdir->name);
      g_string_append_c (relative_path, G_DIR_SEPARATOR);

      if (!entry_directory_foreach_recursive (ed,
                                              subdir,
                                              relative_path,
                                              func,
                                              set,
                                              user_data))
        return FALSE;

      g_string_truncate (relative_path, relative_path_len);

      tmp = tmp->next;
    }

  return TRUE;
}
void
entry_directory_get_flat_contents (EntryDirectory   *ed,
                                   DesktopEntrySet  *desktop_entries,
                                   DesktopEntrySet  *directory_entries,
                                   GSList          **subdirs)
{
  GSList *tmp;

  if (subdirs)
    *subdirs = NULL;

  tmp = ed->dir->entries;
  while (tmp != NULL)
    {
      DesktopEntry *entry = tmp->data;
      const char   *basename;

      basename = desktop_entry_get_basename (entry);

      if (desktop_entries &&
          desktop_entry_get_type (entry) == DESKTOP_ENTRY_DESKTOP)
        {
          char *file_id;

          file_id = get_desktop_file_id_from_path (ed,
						   DESKTOP_ENTRY_DESKTOP,
						   basename);

          desktop_entry_set_add_entry (desktop_entries,
                                       entry,
                                       file_id);

          g_free (file_id);
        }

      if (directory_entries &&
          desktop_entry_get_type (entry) == DESKTOP_ENTRY_DIRECTORY)
        {
          desktop_entry_set_add_entry (directory_entries,
				       entry,
				       basename);
        }

      tmp = tmp->next;
    }

  if (subdirs)
    {
      tmp = ed->dir->subdirs;
      while (tmp != NULL)
        {
          CachedDir *cd = tmp->data;

	  if (!cd->deleted)
	    {
	      *subdirs = g_slist_prepend (*subdirs, g_strdup (cd->name));
	    }

          tmp = tmp->next;
        }
    }

  if (subdirs)
    *subdirs = g_slist_reverse (*subdirs);
}