static CachedDir *
cached_dir_add_subdir (CachedDir  *dir,
                       const char *basename,
                       const char *path)
{
  CachedDir *subdir;

  subdir = find_subdir (dir, basename);

  if (subdir != NULL)
    {
      subdir->deleted = FALSE;
      return subdir;
    }

  subdir = cached_dir_new (basename);

  if (path != NULL && !cached_dir_load_entries_recursive (subdir, path))
    {
      cached_dir_free (subdir);
      return NULL;
    }

  menu_verbose ("Caching dir \"%s\"\n", basename);

  subdir->parent = dir;
  dir->subdirs = g_slist_prepend (dir->subdirs, cached_dir_ref (subdir));

  return subdir;
}
static CachedDir *
cached_dir_lookup (const char *canonical)
{
  CachedDir  *dir;
  char      **split;
  int         i;

  if (dir_cache == NULL)
    dir_cache = cached_dir_new ("/");
  dir = dir_cache;

  g_assert (canonical != NULL && canonical[0] == G_DIR_SEPARATOR);

  menu_verbose ("Looking up cached dir \"%s\"\n", canonical);

  split = g_strsplit (canonical + 1, "/", -1);

  i = 0;
  while (split[i] != NULL)
    {
      CachedDir *subdir;

      if ((subdir = find_subdir (dir, split[i])) == NULL)
        {
          subdir = cached_dir_new (split[i]);
          dir->subdirs = g_slist_prepend (dir->subdirs, subdir);
          subdir->parent = dir;
        }

      dir = subdir;

      ++i;
    }

  g_strfreev (split);

  g_assert (dir != NULL);

  return dir;
}
static CachedDir *
cached_dir_new_full (const char *name,
                     GFunc       notify,
                     gpointer    notify_data)
{
  CachedDir *dir;

  dir = cached_dir_new (name);

  dir->notify = notify;
  dir->notify_data = notify_data;

  return dir;
}