static xmlNodePtr
billterm_dom_tree_create (GncBillTerm *term)
{
    xmlNodePtr ret, data, kvpnode;

    ret = xmlNewNode(NULL, BAD_CAST gnc_billterm_string);
    xmlSetProp(ret, BAD_CAST "version", BAD_CAST billterm_version_string);

    maybe_add_guid(ret, billterm_guid_string, QOF_INSTANCE(term));
    xmlAddChild(ret, text_to_dom_tree (billterm_name_string,
                                       gncBillTermGetName (term)));
    xmlAddChild(ret, text_to_dom_tree (billterm_desc_string,
                                       gncBillTermGetDescription (term)));

    xmlAddChild(ret, int_to_dom_tree (billterm_refcount_string,
                                      gncBillTermGetRefcount (term)));
    xmlAddChild(ret, int_to_dom_tree (billterm_invisible_string,
                                      gncBillTermGetInvisible (term)));

    kvpnode = kvp_frame_to_dom_tree (billterm_slots_string,
                                     qof_instance_get_slots (QOF_INSTANCE(term)));
    if (kvpnode) xmlAddChild (ret, kvpnode);


    /* We should not be our own child */
    if (gncBillTermGetChild(term) != term)
        maybe_add_guid(ret, billterm_child_string,
                       QOF_INSTANCE(gncBillTermGetChild (term)));

    maybe_add_guid(ret, billterm_parent_string,
                   QOF_INSTANCE(gncBillTermGetParent (term)));

    switch (gncBillTermGetType (term))
    {
    case GNC_TERM_TYPE_DAYS:
        data = xmlNewChild (ret, NULL, BAD_CAST gnc_daystype_string, NULL);
        maybe_add_int (data, days_duedays_string, gncBillTermGetDueDays (term));
        maybe_add_int (data, days_discdays_string,
                       gncBillTermGetDiscountDays (term));
        maybe_add_numeric (data, days_discount_string,
                           gncBillTermGetDiscount (term));
        break;

    case GNC_TERM_TYPE_PROXIMO:
        data = xmlNewChild (ret, NULL, BAD_CAST gnc_proximotype_string, NULL);
        maybe_add_int (data, prox_dueday_string, gncBillTermGetDueDays (term));
        maybe_add_int (data, prox_discday_string,
                       gncBillTermGetDiscountDays (term));
        maybe_add_numeric (data, prox_discount_string,
                           gncBillTermGetDiscount (term));
        maybe_add_int (data, prox_cutoff_string, gncBillTermGetCutoff (term));
        break;
    }

    return ret;
}
/* build a list of bill terms that are grandchildren or bogus (empty entry list). */
static void
billterm_scrub_cb (QofInstance *term_p, gpointer list_p)
{
    GncBillTerm *term = GNC_BILLTERM(term_p);
    GList **list = list_p;

    if (billterm_is_grandchild(term))
    {
        *list = g_list_prepend(*list, term);

    }
    else if (!gncBillTermGetType(term))
    {
        GncBillTerm *t = gncBillTermGetParent(term);
        if (t)
        {
            /* Fix up the broken "copy" function */
            gchar guidstr[GUID_ENCODING_LENGTH+1];
            guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),guidstr);
            PWARN("Fixing broken child billterm: %s", guidstr);

            gncBillTermBeginEdit(term);
            gncBillTermSetType(term, gncBillTermGetType(t));
            gncBillTermSetDueDays (term, gncBillTermGetDueDays(t));
            gncBillTermSetDiscountDays (term, gncBillTermGetDiscountDays(t));
            gncBillTermSetDiscount (term, gncBillTermGetDiscount(t));
            gncBillTermSetCutoff (term, gncBillTermGetCutoff(t));
            gncBillTermCommitEdit(term);

        }
        else
        {
            /* No parent?  Must be a standalone */
            *list = g_list_prepend(*list, term);
        }
    }
}