 +
 +  if (db_error != DB_NOTFOUND)
 +  {
-+    g_warning ("dbc->c_get failed: %s", db_strerror (db_error));
++    g_warning (G_STRLOC ": dbc->c_get failed: %s", db_strerror (db_error));
 +    db_error = dbc->c_close (dbc);
 +    return;
 +  }

+      /* return the value of whether we can actually use the index */
+      res = sexp_result->value.bool;
+    } else {
+      g_warning ("Unexpected result type");
+    }
+
+    e_sexp_result_free (sexp, sexp_result);

+      argv[0]->type == ESEXP_RES_STRING &&
+      argv[1]->type == ESEXP_RES_STRING)
+  {
+    /* we need the index database too */
+    query_term = argv[0]->value.string;
+    db = g_hash_table_lookup (priv->sdbs, query_term);
+
+    /* populate a dbt for looking up in the index */
+    query_key = g_utf8_casefold (argv[1]->value.string, -1);
+    dbt_fill_with_string (&index_dbt, query_key);
+
+    /* we want bdb to use g_malloc this memory for us */
+    memset (&id_dbt, 0, sizeof (id_dbt));
+    id_dbt.flags = DB_DBT_MALLOC;
+
+    /* cursor */
+    db_error = db->cursor (db, NULL, &dbc, 0);
+
+    if (db_error != 0)
+    {
+      g_warning (G_STRLOC ": db->cursor failed: %s", db_strerror (db_error)); 
+      goto out;
+    } else {
+      db_error = dbc->c_get (dbc, &index_dbt, &id_dbt, DB_SET);
+
+      while (db_error == 0)
+      {
+        g_debug (G_STRLOC ": index query found: %s", id_dbt.data);
+        g_ptr_array_add (ids, id_dbt.data);
+
+        /* we add it to the list of strings to be freed */
+        priv->ids_to_free = g_list_append (priv->ids_to_free, id_dbt.data);
+
+        /* clear the index dbt since this time bdb will push memory into it */
+        memset (&index_dbt, 0, sizeof (index_dbt));
+        db_error = dbc->c_get (dbc, &index_dbt, &id_dbt, DB_NEXT_DUP);
+      }
+
+      if (db_error != DB_NOTFOUND)
+      {
+        g_warning (G_STRLOC ": dbc->c_get failed: %s", db_strerror (db_error));
+        goto out;
+      }
+
+      db_error = dbc->c_close (dbc);
+
+      if (db_error != 0)
+      {
+        g_warning (G_STRLOC ": dbc->c_close failed: %s", db_strerror (db_error));
+        goto out;
+      }
+    }
+  } else {
+    g_warning (G_STRLOC ": Unexpected query structure");
+  }
+
+out:
+
+  g_free (query_key);
+  result = e_sexp_result_new (sexp, ESEXP_RES_ARRAY_PTR);
+  result->value.ptrarray = ids;
+
+  return result;
+}
+
+static ESExpResult *
+beginswith_query (ESExp *sexp, gint argc, ESExpResult **argv, gpointer userdata)
+{
+  EBookBackendFileIndex *index = (EBookBackendFileIndex *)userdata;
+  EBookBackendFileIndexPrivate *priv = GET_PRIVATE (index);
+  
+  ESExpResult *result = NULL;
+  DBT index_dbt, id_dbt;
+  DB *db = NULL;
+  gint db_error = 0;
+  gchar *query_term = NULL, *query_key = NULL;
+  GPtrArray *ids = NULL;
+  DBC *dbc = NULL;
+
+  ids = g_ptr_array_new ();
+
+  /* we must have two arguments and they must both be strings */
+  if (argc == 2 &&
+      argv[0]->type == ESEXP_RES_STRING &&
+      argv[1]->type == ESEXP_RES_STRING)
+  {
+    /* we need the index database too */
+    query_term = argv[0]->value.string;
+    db = g_hash_table_lookup (priv->sdbs, query_term);
+
+    /* populate a dbt for looking up in the index */
+    query_key = g_utf8_casefold (argv[1]->value.string, -1);
+    dbt_fill_with_string (&index_dbt, query_key);
+
+    /* we want bdb to use g_malloc this memory for us */
+    memset (&id_dbt, 0, sizeof (id_dbt));
+    id_dbt.flags = DB_DBT_MALLOC;
+
+    /* we want bdb to actually manage chunk of memory for returning the
+     * actual key to us
+     */
+    index_dbt.flags = 0;
+
+    /* cursor */
+    db_error = db->cursor (db, NULL, &dbc, 0);
+
+    if (db_error != 0)
+    {
+      g_warning (G_STRLOC ": db->cursor failed: %s", db_strerror (db_error)); 
+      goto out;
+    } else {
+      db_error = dbc->c_get (dbc, &index_dbt, &id_dbt, DB_SET_RANGE);
+
+      while (db_error == 0)
+      {
+        if (g_str_has_prefix (index_dbt.data, query_key))
+        {
+          g_debug (G_STRLOC ": index query found: %s for %s for %s", id_dbt.data, query_key, index_dbt.data);
+          g_ptr_array_add (ids, id_dbt.data);
+
+          /* we add it to the list of strings to be freed */
+          priv->ids_to_free = g_list_append (priv->ids_to_free, id_dbt.data);
+          memset (&index_dbt, 0, sizeof (index_dbt));
+          db_error = dbc->c_get (dbc, &index_dbt, &id_dbt, DB_NEXT);
+        } else {
+          break;
+        }
+      }
+
+      if (db_error != 0 && db_error != DB_NOTFOUND)
+      {
+        g_warning (G_STRLOC ": dbc->c_get failed: %s", db_strerror (db_error));
+        goto out;
+      }
+
+      db_error = dbc->c_close (dbc);
+
+      if (db_error != 0)
+      {
+        g_warning (G_STRLOC ": dbc->c_close failed: %s", db_strerror (db_error));
+        goto out;
+      }
+    }
+  } else {
+    g_warning (G_STRLOC ": Unexpected query structure");
+  }
+
+out:
+  g_free (query_key);
+
+  result = e_sexp_result_new (sexp, ESEXP_RES_ARRAY_PTR);
+  result->value.ptrarray = ids;
+
+  return result;
+}
+
+static gboolean
+index_close_db_func (gpointer key, gpointer value, gpointer userdata)
+{
