static gpointer
book_view_thread (gpointer data)
{
	EDataBookView *book_view = data;
	VCFBackendSearchClosure *closure = get_closure (book_view);
	const gchar *query;
	GList *l;

	/* ref the book view because it'll be removed and unrefed
	   when/if it's stopped */
	e_data_book_view_ref (book_view);

	query = e_data_book_view_get_card_query (book_view);

	if ( !strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
		e_data_book_view_notify_status_message (book_view, _("Loading..."));
	else
		e_data_book_view_notify_status_message (book_view, _("Searching..."));

	d(printf ("signalling parent thread\n"));
	e_flag_set (closure->running);

	for (l = closure->bvcf->priv->contact_list; l; l = l->next) {
		gchar *vcard_string = l->data;
		EContact *contact = e_contact_new_from_vcard (vcard_string);
		e_data_book_view_notify_update (closure->view, contact);
		g_object_unref (contact);

		if (!e_flag_is_set (closure->running))
			break;
	}

	if (e_flag_is_set (closure->running))
		e_data_book_view_notify_complete (closure->view, NULL /* Success */);

	/* unref the book view */
	e_data_book_view_unref (book_view);

	d(printf ("finished initial population of book view\n"));

	return NULL;
}
static void
e_book_backend_webdav_start_view (EBookBackend *backend,
                                  EDataBookView *book_view)
{
	EBookBackendWebdav        *webdav = E_BOOK_BACKEND_WEBDAV (backend);
	EBookBackendWebdavPrivate *priv   = webdav->priv;
	EBookBackendSExp *sexp;
	const gchar *query;
	GList *contacts;
	GList *l;

	sexp = e_data_book_view_get_sexp (book_view);
	query = e_book_backend_sexp_text (sexp);

	g_mutex_lock (&priv->cache_lock);
	contacts = e_book_backend_cache_get_contacts (priv->cache, query);
	g_mutex_unlock (&priv->cache_lock);

	for (l = contacts; l != NULL; l = g_list_next (l)) {
		EContact *contact = l->data;
		e_data_book_view_notify_update (book_view, contact);
		g_object_unref (contact);
	}
	g_list_free (contacts);

	/* this way the UI is notified about cached contacts immediately,
	 * and the update thread notifies about possible changes only */
	e_data_book_view_notify_complete (book_view, NULL /* Success */);

	if (e_backend_get_online (E_BACKEND (backend))) {
		WebdavBackendSearchClosure *closure
			= init_closure (book_view, E_BOOK_BACKEND_WEBDAV (backend));

		closure->thread
			= g_thread_new (NULL, book_view_thread, book_view);

		e_flag_wait (closure->running);
	}
}
static gpointer
book_view_thread (gpointer data)
{
    EBookBackendScalix *bs;
    gboolean stopped;
    const char *query;
    EDataBookView *book_view;
    EBookBackendScalixPrivate *priv;
    ScalixBackendSearchClosure *closure;
    GList *iter;
    ScanContext context;
    gboolean res;

    book_view = data;
    closure = closure_get (book_view);
    bs = closure->bs;
    priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs);
    stopped = FALSE;

    bonobo_object_ref (book_view);

    if (priv->container == NULL) {
        e_data_book_view_notify_complete (book_view,
                                          GNOME_Evolution_Addressbook_AuthenticationRequired);

        bonobo_object_unref (book_view);
        return NULL;
    }

    query = e_data_book_view_get_card_query (book_view);
    context.sexp = e_book_backend_sexp_new (query);
    context.backend = E_BOOK_BACKEND (bs);
    context.obj_list = NULL;
    context.return_objects = TRUE;

    if (!(context.search_needed = query_is_search (query))) {
        e_data_book_view_notify_status_message (book_view, _("Loading..."));
    } else {
        e_data_book_view_notify_status_message (book_view, _("Searching..."));
    }

    g_mutex_lock (closure->mutex);
    g_cond_signal (closure->cond);
    g_mutex_unlock (closure->mutex);

    res = scalix_container_foreach (priv->container, scan_objects, &context);

    if (res == FALSE) {
        e_data_book_view_notify_complete (book_view,
                                          GNOME_Evolution_Addressbook_OtherError);
        bonobo_object_unref (book_view);
        return NULL;
    }

    for (iter = context.obj_list; iter; iter = iter->next) {

        g_mutex_lock (closure->mutex);
        stopped = closure->stopped;
        g_mutex_unlock (closure->mutex);

        if (stopped) {
            break;
        }

        e_data_book_view_notify_update (book_view, iter->data);
        g_object_unref (iter->data);
    }

    /*FIXME: we leek objects if stopped */
    g_list_free (context.obj_list);

    if (!stopped) {
        e_data_book_view_notify_complete (book_view,
                                          GNOME_Evolution_Addressbook_Success);
    }

    bonobo_object_unref (book_view);

    return NULL;
}