static void 
verve_env_finalize (GObject *object)
{
  VerveEnv *env = VERVE_ENV (object);

  /* Cancel and join the loading thread */
  env->load_thread_cancelled = TRUE;
  g_thread_join (env->load_thread);

  /* Free path list */
  if (G_LIKELY (env->paths != NULL))
    g_strfreev (env->paths);

  /* Free binaries list */
  if (G_LIKELY (env->binaries != NULL))
    {
      g_list_foreach (env->binaries, (GFunc) g_free, NULL);
#if 0
      GList *iter = g_list_first (env->binaries);
      while (iter != NULL)
        {
          g_free ((gchar *)iter->data);
          iter = g_list_next (iter);
        }
#endif
      g_list_free (env->binaries);
      env->binaries = NULL;
    }
}
static void 
verve_env_finalize (GObject *object)
{
  VerveEnv *env = VERVE_ENV (object);

  /* Free path list */
  if (G_LIKELY (env->paths != NULL))
    g_strfreev (env->paths);

  /* Free binaries list */
  if (G_LIKELY (env->binaries != NULL))
    {
      GList *iter = g_list_first (env->binaries);
      while (iter != NULL)
        {
          g_free ((gchar *)iter->data);
          iter = g_list_next (iter);
        }
      g_list_free (env->binaries);
    }
}
static gpointer
verve_env_load_thread (gpointer user_data)
{
  VerveEnv *env = VERVE_ENV (user_data);
  gchar   **paths;
  int       i;
  
  /* Get $PATH directories */
  paths = verve_env_get_path (env);
  
  /* Iterate over paths list */
  for (i=0; !env->load_thread_cancelled && i<g_strv_length (paths); i++)
  {
    const gchar *current;
    gchar       *filename;
    GList       *lp;
    /* Try opening the directory */
    GDir *dir = g_dir_open (paths[i], 0, NULL);

    /* Continue with next directory if this one cant' be opened */
    if (G_UNLIKELY (dir == NULL)) 
      continue;

    /* Iterate over files in this directory */
    while (!env->load_thread_cancelled && (current = g_dir_read_name (dir)) != NULL)
      {
        /* Convert to valid UTF-8 */
        filename = g_filename_display_name (current);

        /* Avoid duplicates */
        for (lp = g_list_first (env->binaries); lp != NULL; lp = lp->next)
          if (g_ascii_strcasecmp (lp->data, filename) == 0)
            break;
       
        /* Check details of file if it's not in the list already */
        if (G_LIKELY (lp == NULL))
          {
            /* Determine the absolute path to the file */
            gchar *path = g_build_filename (paths[i], current, NULL);

            /* Check if the path refers to an executable */
            if (g_file_test (path, G_FILE_TEST_IS_EXECUTABLE) &&
                !g_file_test (path, G_FILE_TEST_IS_DIR))
              {
                /* Add file filename to the list */
                env->binaries = g_list_prepend (env->binaries, filename);

                /* No need to free the filename later in this function */
                filename = NULL;
              }

            /* Free absolute path */
            g_free (path);
          }

        /* Release filename if necessary */
        g_free (filename);
      }

    /* Close directory */
    g_dir_close (dir);
  }

  /* Sort binaries */
  env->binaries = g_list_sort (env->binaries, (GCompareFunc) g_utf8_collate);

  /* Emit 'load-binaries' signal */
  g_signal_emit_by_name (env, "load-binaries");

  return env->binaries;
}