static void
e_book_backend_vcf_stop_book_view (EBookBackend  *backend,
				   EDataBookView *book_view)
{
	VCFBackendSearchClosure *closure = get_closure (book_view);
	gboolean need_join;

	d(printf ("stopping query\n"));
	need_join = e_flag_is_set (closure->running);
	e_flag_clear (closure->running);

	if (need_join)
		g_thread_join (closure->thread);
}
mclMatrix* mclInterpret
(  mclMatrix* dag
)
   {  mclv* v_attr = mclvCopy(NULL, dag->dom_cols)
   ;  mclx* m_attr = NULL, *m_cls = NULL, *m_clst = NULL
   ;  dim d

   ;  mclvMakeCharacteristic(v_attr)

   ;  for (d=0;d<N_COLS(dag);d++)
      {  mclv* col = dag->cols+d
      ;  if (mclvGetIvp(col, col->vid, NULL))   /* deemed attractor */
         mclvInsertIdx(v_attr, col->vid, 2.0)
   ;  }

      mclvSelectGqBar(v_attr, 1.5)

   ;  m_attr = mclxSub(dag, v_attr, v_attr)
   ;  mclxAddTranspose(m_attr, 1.0)

   ;  m_cls = clmUGraphComponents(m_attr, NULL) /* attractor systems as clusters */
   ;  mclvCopy(m_cls->dom_rows, dag->dom_cols)  /* add all nodes to this cluster matrix */
   ;  m_clst = mclxTranspose(m_cls)             /* nodes(columns) with zero neighbours need to be classified */
   ;  mclgUnionvReset(dag)                      /* make mx->dom-rows characteristic */
   ;  mclxFree(&m_cls)

   ;  for (d=0;d<N_COLS(dag);d++)
      {  mclv* closure, *clsids
      ;  if (mclvGetIvp(v_attr, dag->cols[d].vid, NULL))
         continue                               /* attractor already classified */

      ;  closure =   get_closure(dag, dag->cols+d)  /* take all [neighbours of [neighbours of [..]]] */
      ;  clsids  =   mclgUnionv(m_clst, closure, NULL, SCRATCH_READY, NULL)

      ;  mclvAdd(m_clst->cols+d, clsids, m_clst->cols+d)
      ;  mclvFree(&clsids)
      ;  mclvFree(&closure)
   ;  }

      m_cls = mclxTranspose(m_clst)
   ;  mclxFree(&m_attr)
   ;  mclxFree(&m_clst)
   ;  mclvFree(&v_attr)
   ;  return m_cls
;  }
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_stop_view (EBookBackend *backend,
                                 EDataBookView *book_view)
{
	WebdavBackendSearchClosure *closure;
	gboolean                    need_join;

	if (!e_backend_get_online (E_BACKEND (backend)))
		return;

	closure = get_closure (book_view);
	if (closure == NULL)
		return;

	need_join = e_flag_is_set (closure->running);
	e_flag_clear (closure->running);

	if (need_join) {
		g_thread_join (closure->thread);
		closure->thread = NULL;
	}
}
static gpointer
book_view_thread (gpointer data)
{
	EDataBookView                          *book_view = data;
	WebdavBackendSearchClosure             *closure   = get_closure (book_view);
	EBookBackendWebdav                     *webdav    = closure->webdav;
	GError *error;

	e_flag_set (closure->running);

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

	error = download_contacts (webdav, closure->running, book_view, NULL);

	g_object_unref (book_view);

	if (error)
		g_error_free (error);

	return NULL;
}