gnucash master: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Wed May 7 12:34:54 EDT 2014


Updated	 via  https://github.com/Gnucash/gnucash/commit/4115c439 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1d76256f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/49a5909f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/45cb5504 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ae98012d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/9d405123 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ec9bd763 (commit)
	from  https://github.com/Gnucash/gnucash/commit/e818c21a (commit)



commit 4115c439204eeda72f00fffd771afbc953533e97
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Wed May 7 18:18:24 2014 +0200

    Reapply "Fix bad qof_instance crash in dialog-payments"
    
    This reverts commit b81289acc66340c74a4b7ed32d0dfffef4a87c16.

diff --git a/src/business/business-gnome/dialog-payment.c b/src/business/business-gnome/dialog-payment.c
index 151f678..ae6e0a7 100644
--- a/src/business/business-gnome/dialog-payment.c
+++ b/src/business/business-gnome/dialog-payment.c
@@ -458,7 +458,7 @@ gnc_payment_dialog_owner_changed (PaymentWindow *pw)
     pw->invoice = NULL;
 
     /* Now handle the account tree */
-    qof_instance_get (QOF_INSTANCE (owner),
+    qof_instance_get (qofOwnerGetOwner (owner),
 		      "payment-last-account", &guid,
 		      NULL);
 
@@ -506,17 +506,17 @@ gnc_payment_dialog_post_to_changed (PaymentWindow *pw)
 static void
 gnc_payment_dialog_remember_account (PaymentWindow *pw, Account *acc)
 {
-    GncOwner *owner = &pw->owner;
+     QofInstance *owner = qofOwnerGetOwner (&pw->owner);
     const GncGUID *guid;
 
     if (!acc) return;
 
     guid = xaccAccountGetGUID(acc);
-    qof_begin_edit (QOF_INSTANCE (owner));
-    qof_instance_set (QOF_INSTANCE (owner),
+    qof_begin_edit (owner);
+    qof_instance_set (owner,
 		      "payment-last-account", guid,
 		      NULL);
-    qof_commit_edit (QOF_INSTANCE (owner));
+    qof_commit_edit (owner);
 }
 
 

commit 1d76256f92138aefe24f224cb0bd0ee266805413
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Wed May 7 18:18:14 2014 +0200

    Reapply "Fix typo in test-engine-kvp-properties."
    
    This reverts commit c475b9f8c7545e1f4dc3b1e0a3b9b6b217a30719.

diff --git a/src/engine/test/test-engine-kvp-properties.c b/src/engine/test/test-engine-kvp-properties.c
index 8b95526..97b0efe 100644
--- a/src/engine/test/test-engine-kvp-properties.c
+++ b/src/engine/test/test-engine-kvp-properties.c
@@ -35,7 +35,7 @@
 #include "../Transaction.h"
 #include "../Split.h"
 #include "../Account.h"
-#include "../SchedXAction.h"
+#include "../SchedXaction.h"
 #include "../gncCustomer.h"
 #include "../gncEmployee.h"
 #include "../gncJob.h"

commit 49a5909ff243e1cd776993b9bb4d570b832776f2
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Wed May 7 17:55:42 2014 +0200

    Fixes necessary to marry private-kvp branch with c++ work

diff --git a/src/app-utils/test/Makefile.am b/src/app-utils/test/Makefile.am
index ca5ec09..75d0ab8 100644
--- a/src/app-utils/test/Makefile.am
+++ b/src/app-utils/test/Makefile.am
@@ -54,7 +54,7 @@ check_PROGRAMS = \
   test-print-queries \
   test-sx
 
-EXTRA_DIST = \
+EXTRA_DIST += \
   test-load-module
 
 AM_CPPFLAGS = \
diff --git a/src/backend/xml/gnc-address-xml-v2.c b/src/backend/xml/gnc-address-xml-v2.c
index 2e84319..1815e0b 100644
--- a/src/backend/xml/gnc-address-xml-v2.c
+++ b/src/backend/xml/gnc-address-xml-v2.c
@@ -58,6 +58,9 @@ const gchar *address_version_string = "2.0.0";
 #define addr_email_string	"addr:email"
 #define addr_slots_string	"addr:slots"
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance*);
+
 static void
 maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
 {
@@ -189,7 +192,7 @@ address_slots_handler (xmlNodePtr node, gpointer addr_pdata)
     struct address_pdata *pdata = addr_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, xaccAccountGetSlots (pdata->address));
+        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->address)));
 }
 
 static struct dom_tree_handler address_handlers_v2[] =
diff --git a/src/backend/xml/gnc-entry-xml-v2.c b/src/backend/xml/gnc-entry-xml-v2.c
index 713bef9..96d0e3b 100644
--- a/src/backend/xml/gnc-entry-xml-v2.c
+++ b/src/backend/xml/gnc-entry-xml-v2.c
@@ -92,6 +92,9 @@ const gchar *entry_version_string = "2.0.0";
 #define entry_bill_string "entry:bill"
 #define entry_slots_string "entry:slots"
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance*);
+
 static void
 maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
 {
@@ -675,7 +678,7 @@ entry_slots_handler (xmlNodePtr node, gpointer entry_pdata)
     struct entry_pdata *pdata = entry_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, xaccAccountGetSlots (pdata->entry));
+        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->entry)));
 }
 
 static struct dom_tree_handler entry_handlers_v2[] =
diff --git a/src/backend/xml/gnc-job-xml-v2.c b/src/backend/xml/gnc-job-xml-v2.c
index 1ed84df..6a6f513 100644
--- a/src/backend/xml/gnc-job-xml-v2.c
+++ b/src/backend/xml/gnc-job-xml-v2.c
@@ -62,6 +62,9 @@ const gchar *job_version_string = "2.0.0";
 #define job_active_string "job:active"
 #define job_slots_string "job:slots"
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance*);
+
 static xmlNodePtr
 job_dom_tree_create (GncJob *job)
 {
@@ -207,7 +210,7 @@ job_slots_handler (xmlNodePtr node, gpointer job_pdata)
     struct job_pdata *pdata = job_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, xaccAccountGetSlots (pdata->job));
+        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->job)));
 }
 
 static struct dom_tree_handler job_handlers_v2[] =
diff --git a/src/backend/xml/gnc-order-xml-v2.c b/src/backend/xml/gnc-order-xml-v2.c
index c393182..cb5fdfb 100644
--- a/src/backend/xml/gnc-order-xml-v2.c
+++ b/src/backend/xml/gnc-order-xml-v2.c
@@ -46,7 +46,7 @@
 #include "gnc-order-xml-v2.h"
 #include "gnc-owner-xml-v2.h"
 
-#define _GNC_MOD_NAME	GNC_ID_ORDER
+#define _GNC_MOD_NAME   GNC_ID_ORDER
 
 static QofLogModule log_module = GNC_MOD_IO;
 
@@ -64,6 +64,9 @@ const gchar *order_version_string = "2.0.0";
 #define order_active_string "order:active"
 #define order_slots_string "order:slots"
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance*);
+
 static void
 maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
 {
@@ -248,7 +251,7 @@ order_slots_handler (xmlNodePtr node, gpointer order_pdata)
     struct order_pdata *pdata = order_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, xaccAccountGetSlots (pdata->order));
+        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->order)));
 }
 
 static struct dom_tree_handler order_handlers_v2[] =
diff --git a/src/backend/xml/gnc-tax-table-xml-v2.c b/src/backend/xml/gnc-tax-table-xml-v2.c
index aeff781..0990e4b 100644
--- a/src/backend/xml/gnc-tax-table-xml-v2.c
+++ b/src/backend/xml/gnc-tax-table-xml-v2.c
@@ -67,6 +67,9 @@ const gchar *taxtable_version_string = "2.0.0";
 #define ttentry_type_string "tte:type"
 #define ttentry_amount_string "tte:amount"
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance*);
+
 static void
 maybe_add_guid (xmlNodePtr ptr, const char *tag, GncTaxTable *table)
 {
@@ -382,7 +385,7 @@ taxtable_slots_handler (xmlNodePtr node, gpointer taxtable_pdata)
     struct taxtable_pdata *pdata = taxtable_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, xaccAccountGetSlots (pdata->table));
+        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->table)));
 }
 
 static struct dom_tree_handler taxtable_handlers_v2[] =
diff --git a/src/core-utils/gnc-features.c b/src/core-utils/gnc-features.c
index f4846f4..5b341c9 100644
--- a/src/core-utils/gnc-features.c
+++ b/src/core-utils/gnc-features.c
@@ -96,12 +96,12 @@ static void gnc_features_test_one(gpointer pkey, gpointer value,
 gchar *gnc_features_test_unknown (QofBook *book)
 {
 
-    /* Setup the known_features hash table */
-    gnc_features_init();
-
     GList* features_list = NULL;
     GHashTable *features_used = qof_book_get_features (book);
 
+    /* Setup the known_features hash table */
+    gnc_features_init();
+
     /* Iterate over the members of this frame for unknown features */
     g_hash_table_foreach (features_used, &gnc_features_test_one,
 			  &features_list);
diff --git a/src/import-export/ofx/gnc-ofx-kvp.c b/src/import-export/ofx/gnc-ofx-kvp.c
index e4e5d6f..8b6f670 100644
--- a/src/import-export/ofx/gnc-ofx-kvp.c
+++ b/src/import-export/ofx/gnc-ofx-kvp.c
@@ -26,8 +26,7 @@
 #include "config.h"
 #include "gnc-ofx-kvp.h"
 
-static void force_account_dirty(Account *acct);
-/* OUTSIDE SLOT ACCESS */
+static const char *KEY_ASSOC_INCOME_ACCOUNT = "ofx/associated-income-account";
 
 
 Account *gnc_ofx_kvp_get_assoc_account(const Account* investment_account)
@@ -36,7 +35,7 @@ Account *gnc_ofx_kvp_get_assoc_account(const Account* investment_account)
     GncGUID *income_guid= NULL;
     g_assert(investment_account);
     qof_instance_get (QOF_INSTANCE (investment_account),
-		      "ofx-income-account", &income_guid,
+		      KEY_ASSOC_INCOME_ACCOUNT, &income_guid,
 		      NULL);
     return xaccAccountLookup(income_guid,
 			       gnc_account_get_book(investment_account));
@@ -53,7 +52,7 @@ void gnc_ofx_kvp_set_assoc_account(Account* investment_account,
     income_acc_guid = xaccAccountGetGUID(income_account);
     xaccAccountBeginEdit(investment_account);
     qof_instance_set (QOF_INSTANCE (investment_account),
-		      "ofx-income-account", income_acc_guid,
+		      KEY_ASSOC_INCOME_ACCOUNT, income_acc_guid,
 		      NULL);
     xaccAccountCommitEdit(investment_account);
 }
diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp
index a21d04b..fc107df 100644
--- a/src/libqof/qof/qofbook.cpp
+++ b/src/libqof/qof/qofbook.cpp
@@ -80,7 +80,8 @@ QOF_GOBJECT_DISPOSE(qof_book);
 QOF_GOBJECT_FINALIZE(qof_book);
 
 static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
-
+#undef G_PARAM_READWRITE
+#define G_PARAM_READWRITE static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE)
 /* ====================================================================== */
 /* constructor / destructor */
 
@@ -151,11 +152,11 @@ qof_book_get_property (GObject* object,
 	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
 	g_free (key);
     case PROP_OPT_FY_END:
-	key = "fy_end";
+	key = const_cast<char*>("fy_end");
 	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
 	break;
     case PROP_AB_TEMPLATES:
-	key = AB_KEY "/" AB_TEMPLATES;
+	key = const_cast<char*>(AB_KEY "/" AB_TEMPLATES);
 	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
 	break;
     default:
@@ -208,11 +209,11 @@ qof_book_set_property (GObject      *object,
 	g_free (key);
 	break;
     case PROP_OPT_FY_END:
-	key = "fy_end";
+	key = const_cast<char*>("fy_end");
 	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
 	break;
     case PROP_AB_TEMPLATES:
-	key = AB_KEY "/" AB_TEMPLATES;
+	key = const_cast<char*>(AB_KEY "/" AB_TEMPLATES);
 	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
 	break;
     default:
diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h
index 5be89b3..751b3f0 100644
--- a/src/libqof/qof/qofinstance-p.h
+++ b/src/libqof/qof/qofinstance-p.h
@@ -113,4 +113,5 @@ void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value);
 }
 #endif
 
+
 #endif /* QOF_INSTANCE_P_H */
diff --git a/src/libqof/qof/qoflog.cpp b/src/libqof/qof/qoflog.cpp
index bd0f7d5..73dec72 100644
--- a/src/libqof/qof/qoflog.cpp
+++ b/src/libqof/qof/qoflog.cpp
@@ -268,6 +268,8 @@ qof_log_prettify (const char *name)
     begin = g_strrstr (buffer, "*");
     if (begin == NULL)
 	begin = g_strrstr (buffer, " ");
+    else if (* (begin + 1) == ' ')
+        ++ begin;
     if (begin != NULL)
 	p = begin + 1;
     else
diff --git a/src/register/ledger-core/split-register-model-save.c b/src/register/ledger-core/split-register-model-save.c
index e95816f..60582d4 100644
--- a/src/register/ledger-core/split-register-model-save.c
+++ b/src/register/ledger-core/split-register-model-save.c
@@ -682,7 +682,6 @@ gnc_template_register_save_xfrm_cell (BasicCell * cell,
 
     /* set the actual account to the fake account for these templates */
     xaccAccountInsertSplit (template_acc, sd->split);
-    qof_instance_set_dirty (QOF_INSTANCE (sd->split));
 }
 
 static void

commit 45cb5504f3c7c0a8c9fa8917866e0addd349abbd
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Wed May 7 15:37:14 2014 +0200

    Merge branch 'private-kvp' into master again
    
    This was done by branching right before the original merge
    and redoing a clean merge of the private-kvp branch again.
    
    This result was then cherry-picked onto master with
    git cherry-pick <merge-commit> -m 1
    
    It was done like this because git merge would consider
    the private-kvp branch already merged even after a revert
    (see git-revert man page) and won't allow to merge a
    second time on the same branch.
    
    Resolved conflicts:
    	README.dependencies
    	src/app-utils/gnc-sx-instance-model.c
    	src/engine/cap-gains.c
    	src/engine/test/Makefile.am
    	src/gnome/assistant-hierarchy.c
    	src/import-export/import-match-map.c
    	src/import-export/import-utilities.c
    	src/import-export/ofx/gnc-ofx-kvp.c
    	src/libqof/qof/qofbook.cpp
    	src/libqof/qof/qofinstance-p.h
    	src/libqof/qof/qofinstance.cpp
    	src/libqof/qof/test/test-kvp_frame.c
    	src/report/report-gnome/gnc-plugin-page-report.c

diff --git a/po/POTFILES.in b/po/POTFILES.in
index f4d0905..4fd491b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -404,7 +404,6 @@ src/import-export/import-backend.c
 src/import-export/import-commodity-matcher.c
 src/import-export/import-format-dialog.c
 src/import-export/import-main-matcher.c
-src/import-export/import-match-map.c
 src/import-export/import-match-picker.c
 src/import-export/import-parse.c
 src/import-export/import-settings.c
diff --git a/src/app-utils/business-helpers.c b/src/app-utils/business-helpers.c
index f4c75fa..618e01e 100644
--- a/src/app-utils/business-helpers.c
+++ b/src/app-utils/business-helpers.c
@@ -33,7 +33,7 @@ GncTaxTable* gnc_business_get_default_tax_table (QofBook *book, GncOwnerType own
     GNCOptionDB *odb;
 
     odb = gnc_option_db_new_for_type (GNC_ID_BOOK);
-    gnc_option_db_load_from_kvp (odb, qof_book_get_slots (book));
+    qof_book_load_options (book, gnc_option_db_load_from_kvp, odb);
 
     switch (ownertype)
     {
diff --git a/src/app-utils/gnc-accounting-period.c b/src/app-utils/gnc-accounting-period.c
index 3c17ac9..e7dd8e7 100644
--- a/src/app-utils/gnc-accounting-period.c
+++ b/src/app-utils/gnc-accounting-period.c
@@ -102,15 +102,13 @@ get_fy_end(void)
 {
     QofBook *book;
     KvpFrame *book_frame;
-    gint64 month, day;
+    GDate *date = NULL;
 
     book = gnc_get_current_book();
-    book_frame = qof_book_get_slots(book);
-    month = kvp_frame_get_gint64(book_frame, "/book/fyear_end/month");
-    day = kvp_frame_get_gint64(book_frame, "/book/fyear_end/day");
-    if (g_date_valid_dmy(day, month, 2005 /* not leap year */))
-        return g_date_new_dmy(day, month, G_DATE_BAD_YEAR);
-    return NULL;
+    qof_instance_get (QOF_INSTANCE (book),
+		      "fy-end", &date,
+		      NULL);
+    return date;
 }
 
 time64
diff --git a/src/app-utils/gnc-sx-instance-model.c b/src/app-utils/gnc-sx-instance-model.c
index 744c274..bfe2701 100644
--- a/src/app-utils/gnc-sx-instance-model.c
+++ b/src/app-utils/gnc-sx-instance-model.c
@@ -176,10 +176,9 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
 {
     GHashTable *var_hash = (GHashTable*)var_hash_data;
     GList *split_list;
-    kvp_frame *kvpf;
-    kvp_value *kvp_val;
     Split *s;
-    char *str;
+    gchar *credit_formula = NULL;
+    gchar *debit_formula = NULL;
     gnc_commodity *first_cmdty = NULL;
 
     split_list = xaccTransGetSplitList(txn);
@@ -191,16 +190,16 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
     for ( ; split_list; split_list = split_list->next)
     {
         gnc_commodity *split_cmdty = NULL;
-        GncGUID *acct_guid;
+        GncGUID *acct_guid = NULL;
         Account *acct;
 
         s = (Split*)split_list->data;
-        kvpf = xaccSplitGetSlots(s);
-        kvp_val = kvp_frame_get_slot_path(kvpf,
-                                          GNC_SX_ID,
-                                          GNC_SX_ACCOUNT,
-                                          NULL);
-        acct_guid = kvp_value_get_guid(kvp_val);
+
+        qof_instance_get (QOF_INSTANCE (s),
+			  "sx-account", &acct_guid,
+			  "sx-credit-formula", &credit_formula,
+			  "sx-debit-formula", &debit_formula,
+			  NULL);
         acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
         split_cmdty = xaccAccountGetCommodity(acct);
         if (first_cmdty == NULL)
@@ -226,31 +225,16 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
         }
 
         // existing... ------------------------------------------
-        kvp_val = kvp_frame_get_slot_path(kvpf,
-                                          GNC_SX_ID,
-                                          GNC_SX_CREDIT_FORMULA,
-                                          NULL);
-        if (kvp_val != NULL)
-        {
-            str = kvp_value_get_string(kvp_val);
-            if (str && strlen(str) != 0)
-            {
-                gnc_sx_parse_vars_from_formula(str, var_hash, NULL);
-            }
-        }
-
-        kvp_val = kvp_frame_get_slot_path(kvpf,
-                                          GNC_SX_ID,
-                                          GNC_SX_DEBIT_FORMULA,
-                                          NULL);
-        if (kvp_val != NULL)
-        {
-            str = kvp_value_get_string(kvp_val);
-            if (str && strlen(str) != 0)
-            {
-                gnc_sx_parse_vars_from_formula(str, var_hash, NULL);
-            }
-        }
+	if (credit_formula && strlen(credit_formula) != 0)
+	{
+	    gnc_sx_parse_vars_from_formula(credit_formula, var_hash, NULL);
+	}
+	if (debit_formula && strlen(debit_formula) != 0)
+	{
+	    gnc_sx_parse_vars_from_formula(debit_formula, var_hash, NULL);
+	}
+	g_free (credit_formula);
+	g_free (debit_formula);
     }
 
     return 0;
@@ -900,31 +884,15 @@ typedef struct _SxTxnCreationData
 } SxTxnCreationData;
 
 static gboolean
-_get_template_split_account(const SchedXaction* sx, const Split *template_split, Account **split_acct, GList **creation_errors)
+_get_template_split_account(const SchedXaction* sx,
+			    const Split *template_split,
+			    Account **split_acct,
+			    GList **creation_errors)
 {
-    GncGUID *acct_guid;
-    kvp_frame *split_kvpf;
-    kvp_value *kvp_val;
-
-    split_kvpf = xaccSplitGetSlots(template_split);
-    /* contains the guid of the split's actual account. */
-    kvp_val = kvp_frame_get_slot_path(split_kvpf,
-                                      GNC_SX_ID,
-                                      GNC_SX_ACCOUNT,
-                                      NULL);
-    if (kvp_val == NULL)
-    {
-        GString *err = g_string_new("");
-        g_string_printf(err, "Null account kvp value for SX [%s], cancelling creation.",
-                        xaccSchedXactionGetName(sx));
-        g_critical("%s", err->str);
-        if (creation_errors != NULL)
-            *creation_errors = g_list_append(*creation_errors, err);
-        else
-            g_string_free(err, TRUE);
-        return FALSE;
-    }
-    acct_guid = kvp_value_get_guid( kvp_val );
+    GncGUID *acct_guid = NULL;
+    qof_instance_get (QOF_INSTANCE (template_split),
+		      "sx-account", &acct_guid,
+		      NULL);
     *split_acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
     if (*split_acct == NULL)
     {
@@ -946,34 +914,34 @@ _get_template_split_account(const SchedXaction* sx, const Split *template_split,
 }
 
 static void
-_get_sx_formula_value(const SchedXaction* sx, const Split *template_split, gnc_numeric *numeric, GList **creation_errors, const char *formula_key, const char* numeric_key, GHashTable *variable_bindings)
+_get_sx_formula_value(const SchedXaction* sx,
+		      const Split *template_split,
+		      gnc_numeric *numeric,
+		      GList **creation_errors,
+		      const char *formula_key,
+		      const char* numeric_key,
+		      GHashTable *variable_bindings)
 {
-    kvp_frame *split_kvpf;
-    kvp_value *kvp_val;
-    char *formula_str, *parseErrorLoc;
-
-    split_kvpf = xaccSplitGetSlots(template_split);
-
-    /* First look up the gnc_numeric value in the template split */
-    kvp_val = kvp_frame_get_slot_path(split_kvpf,
-                                      GNC_SX_ID,
-                                      numeric_key,
-                                      NULL);
-    *numeric = kvp_value_get_numeric(kvp_val);
-    if ((gnc_numeric_check(*numeric) == GNC_ERROR_OK)
-            && !gnc_numeric_zero_p(*numeric))
+
+    char *formula_str = NULL, *parseErrorLoc = NULL;
+    gnc_numeric *numeric_val = NULL;
+    qof_instance_get (QOF_INSTANCE (template_split),
+		      formula_key, &formula_str,
+		      numeric_key, &numeric_val,
+		      NULL);
+
+    if (numeric_val != NULL &&
+	gnc_numeric_check(*numeric_val) == GNC_ERROR_OK &&
+	!gnc_numeric_zero_p(*numeric_val))
     {
         /* Already a valid non-zero result? Then return and don't
          * parse the string. Luckily we avoid any locale problems with
          * decimal points here! Phew. */
+	numeric->num = numeric_val->num;
+	numeric->denom = numeric_val->denom;
         return;
     }
 
-    kvp_val = kvp_frame_get_slot_path(split_kvpf,
-                                      GNC_SX_ID,
-                                      formula_key,
-                                      NULL);
-    formula_str = kvp_value_get_string(kvp_val);
     if (formula_str != NULL && strlen(formula_str) != 0)
     {
         GHashTable *parser_vars = NULL;
@@ -1010,13 +978,17 @@ _get_sx_formula_value(const SchedXaction* sx, const Split *template_split, gnc_n
 static void
 _get_credit_formula_value(GncSxInstance *instance, const Split *template_split, gnc_numeric *credit_num, GList **creation_errors)
 {
-    _get_sx_formula_value(instance->parent->sx, template_split, credit_num, creation_errors, GNC_SX_CREDIT_FORMULA, GNC_SX_CREDIT_NUMERIC, instance->variable_bindings);
+    _get_sx_formula_value(instance->parent->sx, template_split, credit_num,
+			  creation_errors, "sx-credit-formula",
+			  "sx-credit-numeric", instance->variable_bindings);
 }
 
 static void
 _get_debit_formula_value(GncSxInstance *instance, const Split *template_split, gnc_numeric *debit_num, GList **creation_errors)
 {
-    _get_sx_formula_value(instance->parent->sx, template_split, debit_num, creation_errors, GNC_SX_DEBIT_FORMULA, GNC_SX_DEBIT_NUMERIC, instance->variable_bindings);
+    _get_sx_formula_value(instance->parent->sx, template_split, debit_num,
+			  creation_errors, "sx-debit-formula",
+			  "sx-debit-numeric", instance->variable_bindings);
 }
 
 static gboolean
@@ -1035,7 +1007,7 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
        as not finding the approrpiate Accounts and not being able to
        parse the formula|credit/debit strings. */
 
-    new_txn = xaccTransClone(template_txn);
+    new_txn = xaccTransCloneNoKvp(template_txn);
     xaccTransBeginEdit(new_txn);
 
     g_debug("creating template txn desc [%s] for sx [%s]",
@@ -1044,9 +1016,6 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
 
     g_debug("template txn currency is %s", gnc_commodity_get_mnemonic(xaccTransGetCurrency (template_txn)));
 
-    /* clear any copied KVP data */
-    qof_instance_set_slots(QOF_INSTANCE(new_txn), kvp_frame_new());
-
     /* Bug#500427: copy the notes, if any */
     if (xaccTransGetNotes(template_txn) != NULL)
     {
@@ -1090,9 +1059,6 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
             break;
         }
 
-        /* clear out any copied Split frame data. */
-        qof_instance_set_slots(QOF_INSTANCE(copying_split), kvp_frame_new());
-
         split_cmdty = xaccAccountGetCommodity(split_acct);
         if (first_cmdty == NULL)
         {
@@ -1215,13 +1181,10 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
     }
 
     {
-        kvp_frame *txn_frame;
-        txn_frame = xaccTransGetSlots(new_txn);
-        kvp_frame_set_guid(txn_frame, "from-sched-xaction",
-		  xaccSchedXactionGetGUID(creation_data->instance->parent->sx));
-/* The transaction was probably marked dirty by xaccTransSetCurrency,
- * but just in case: */
-	qof_instance_set_dirty (QOF_INSTANCE (new_txn));
+	qof_instance_set (QOF_INSTANCE (new_txn),
+			  "from-sched-xaction",
+			  xaccSchedXactionGetGUID(creation_data->instance->parent->sx),
+			  NULL);
     }
 
     xaccTransCommitEdit(new_txn);
@@ -1631,9 +1594,14 @@ create_cashflow_helper(Transaction *template_txn, void *user_data)
             gint gncn_error;
 
             /* Credit value */
-            _get_sx_formula_value(creation_data->sx, template_split, &credit_num, creation_data->creation_errors, GNC_SX_CREDIT_FORMULA, GNC_SX_CREDIT_NUMERIC, NULL);
+            _get_sx_formula_value(creation_data->sx, template_split,
+				  &credit_num, creation_data->creation_errors,
+				  "sx-credit-formula", "sx-credit-numeric",
+				  NULL);
             /* Debit value */
-            _get_sx_formula_value(creation_data->sx, template_split, &debit_num, creation_data->creation_errors, GNC_SX_DEBIT_FORMULA, GNC_SX_DEBIT_NUMERIC, NULL);
+            _get_sx_formula_value(creation_data->sx, template_split,
+				  &debit_num, creation_data->creation_errors,
+				  "sx-debit-formula", "sx-debit-numeric", NULL);
 
             /* The resulting cash flow number: debit minus credit,
              * multiplied with the count factor. */
diff --git a/src/app-utils/option-util.h b/src/app-utils/option-util.h
index a37fccb..5ad66e2 100644
--- a/src/app-utils/option-util.h
+++ b/src/app-utils/option-util.h
@@ -33,7 +33,7 @@
 
 typedef struct gnc_option GNCOption;
 typedef struct gnc_option_section GNCOptionSection;
-typedef struct gnc_option_db GNCOptionDB;
+/* typedef struct gnc_option_db GNCOptionDB is in qof-book.h */
 
 typedef int GNCOptionDBHandle;
 
diff --git a/src/app-utils/test/Makefile.am b/src/app-utils/test/Makefile.am
index 3a00263..ca5ec09 100644
--- a/src/app-utils/test/Makefile.am
+++ b/src/app-utils/test/Makefile.am
@@ -1,3 +1,5 @@
+include $(top_srcdir)/test-templates/Makefile.decl
+
 TESTS = \
   test-link-module \
   test-load-module \
@@ -66,3 +68,17 @@ AM_CPPFLAGS = \
   -I${top_srcdir}/src/libqof/qof \
   ${GUILE_CFLAGS} \
   ${GLIB_CFLAGS}
+
+TEST_PROGS += test-app-utils
+
+noinst_PROGRAMS = ${TEST_PROGS} ${CHECK_PROGS}
+
+test_app_utils_SOURCES = \
+	test-app-utils.c \
+	test-option-util.c
+
+test_app_utils_CFLAGS = \
+	${DEFAULT_INCLUDES} \
+	-I${top_srcdir}/${MODULEPATH}/ \
+	-DTESTPROG=test_app_utils \
+	${GLIB_CFLAGS}
diff --git a/src/engine/test/test-engine.c b/src/app-utils/test/test-app-utils.c
similarity index 66%
copy from src/engine/test/test-engine.c
copy to src/app-utils/test/test-app-utils.c
index 508856e..ee0f274 100644
--- a/src/engine/test/test-engine.c
+++ b/src/app-utils/test/test-app-utils.c
@@ -1,6 +1,6 @@
 /********************************************************************
- * testmain.c: GLib g_test test execution file.			    *
- * Copyright 2011 John Ralls <jralls at ceridwen.us>		    *
+ * test-app-utils.c: GLib g_test test execution file.		    *
+ * Copyright 2013 John Ralls <jralls at ceridwen.us>		    *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -20,35 +20,37 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
-
 #include <config.h>
 #include <glib.h>
 #include <qof.h>
-#include <TransLog.h>
+#include <libguile.h>
+#include <gnc-module.h>
+
+extern void test_suite_option_util (void);
+
+static void
+guile_main (void *closure, int argc, char **argv)
+{
+    GNCModule mod;
+    int retval;
+    gnc_module_system_init ();
+    mod = gnc_module_load ("gnucash/app-utils", 0);
 
-extern void test_suite_account();
-extern void test_suite_budget();
-extern void test_suite_gncInvoice();
-extern void test_suite_transaction();
-extern void test_suite_split();
+    test_suite_option_util ();
+    retval = g_test_run ();
+
+    exit (retval);
+}
 
 int
-main (int   argc,
-      char *argv[])
+main (int argc, char *argv[])
 {
-    qof_init(); 			/* Initialize the GObject system */
-    qof_log_init_filename_special("stderr"); /* Init the log system */
-    g_test_init ( &argc, &argv, NULL ); 	/* initialize test program */
+    qof_init (); 			/* Initialize the GObject system */
+    qof_log_init_filename_special ("stderr"); /* Init the log system */
+    g_test_init (&argc, &argv, NULL); 	/* initialize test program */
     //qof_log_set_level("gnc", G_LOG_LEVEL_DEBUG);
     g_test_bug_base("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */
-    /* Disable the transaction log */
-    xaccLogDisable();
-
-    test_suite_account();
-    test_suite_budget();
-    test_suite_gncInvoice();
-    test_suite_transaction();
-    test_suite_split();
+    g_setenv ("GNC_UNINSTALLED", "1", TRUE);
+    scm_boot_guile (argc, argv, guile_main, NULL);
 
-    return g_test_run( );
 }
diff --git a/src/app-utils/test/test-option-util.c b/src/app-utils/test/test-option-util.c
new file mode 100644
index 0000000..dc99f32
--- /dev/null
+++ b/src/app-utils/test/test-option-util.c
@@ -0,0 +1,126 @@
+/********************************************************************
+ * test-option-util.c: GLib g_test test suite for Split.c.	    *
+ * Copyright 2013 John Ralls <jralls at ceridwen.us>		    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, you can retrieve it from        *
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html            *
+ * or contact:                                                      *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ ********************************************************************/
+
+#include <config.h>
+#include <glib.h>
+#include <unittest-support.h>
+#include <qofbookslots.h>
+
+#include "../option-util.h"
+
+static const gchar *suitename = "/app-utils/option-util";
+void test_suite_option_util (void);
+
+typedef struct
+{
+    QofBook *book;
+    GSList *hdlrs;
+} Fixture;
+
+/* Expose a mostly-private QofInstance function to load options into
+ * the Book.
+ */
+extern KvpFrame *qof_instance_get_slots (QofInstance*);
+
+static void
+setup (Fixture *fixture, gconstpointer pData)
+{
+    fixture->book = qof_book_new ();
+    fixture->hdlrs = NULL;
+}
+
+static void
+setup_kvp (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book;
+    KvpFrame *slots;
+    setup (fixture, pData);
+    book = fixture->book;
+    slots = qof_instance_get_slots (QOF_INSTANCE (book));
+    qof_begin_edit (QOF_INSTANCE (book));
+    qof_instance_set (QOF_INSTANCE (book),
+		      "trading-accts", "t",
+		      "split-action-num-field", "t",
+		      "autoreadonly-days", (double)21,
+		      NULL);
+
+    kvp_frame_set_string (slots, "options/Business/Company Name",
+			  "Bogus Company");
+    qof_commit_edit (QOF_INSTANCE (book));
+}
+
+static void
+teardown (Fixture *fixture, gconstpointer pData)
+{
+    qof_book_destroy (fixture->book);
+    g_slist_free_full (fixture->hdlrs, test_free_log_handler);
+    test_clear_error_list();
+}
+
+static void
+test_option_load_from_kvp (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = fixture->book;
+    GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK);
+
+    qof_book_load_options (book, gnc_option_db_load_from_kvp, odb);
+    g_assert (gnc_option_db_lookup_boolean_option (odb, OPTION_SECTION_ACCOUNTS,
+ OPTION_NAME_TRADING_ACCOUNTS, FALSE));
+    g_assert_cmpstr (gnc_option_db_lookup_string_option (odb, "Business", "Company Name", FALSE), ==, "Bogus Company");
+    g_assert_cmpfloat (gnc_option_db_lookup_number_option (odb, OPTION_SECTION_ACCOUNTS, OPTION_NAME_AUTO_READONLY_DAYS, FALSE), ==, 21);
+
+    gnc_option_db_destroy (odb);
+}
+
+static void
+test_option_save_to_kvp (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = fixture->book;
+    GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK);
+    KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book));
+
+    g_assert (gnc_option_db_set_boolean_option (odb, OPTION_SECTION_ACCOUNTS,
+						OPTION_NAME_TRADING_ACCOUNTS,
+						TRUE));
+    g_assert (gnc_option_db_set_string_option (odb, "Business", "Company Name",
+					       "Bogus Company"));
+    g_assert (gnc_option_db_set_number_option (odb, OPTION_SECTION_ACCOUNTS,
+					       OPTION_NAME_AUTO_READONLY_DAYS,
+					       17));
+    qof_book_save_options (book, gnc_option_db_save_to_kvp, odb, TRUE);
+    g_assert_cmpstr (kvp_frame_get_string (slots,  "options/Accounts/Use Trading Accounts"), == , "t");
+    g_assert_cmpstr (kvp_frame_get_string (slots, "options/Business/Company Name"), ==, "Bogus Company");
+    g_assert_cmpfloat (kvp_frame_get_double (slots, "options/Accounts/Day Threshold for Read-Only Transactions (red line)"), ==, 17);
+
+    gnc_option_db_destroy (odb);
+}
+
+
+void
+test_suite_option_util (void)
+{
+    GNC_TEST_ADD (suitename, "Option DB Load from KVP", Fixture, NULL, setup_kvp, test_option_load_from_kvp, teardown);
+    GNC_TEST_ADD (suitename, "Option DB Save to KVP", Fixture, NULL, setup, test_option_save_to_kvp, teardown);
+
+}
diff --git a/src/backend/dbi/test/test-dbi-stuff.c b/src/backend/dbi/test/test-dbi-stuff.c
index 4ac96ae..c0e1d1e 100644
--- a/src/backend/dbi/test/test-dbi-stuff.c
+++ b/src/backend/dbi/test/test-dbi-stuff.c
@@ -168,6 +168,9 @@ compare_sxs( QofBook* book_1, QofBook* book_2 )
                 compare_single_sx, "Scheduled transaction lists match" );
 }
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance *);
+
 static void
 compare_single_lot( QofInstance* inst, gpointer user_data )
 {
@@ -181,8 +184,8 @@ compare_single_lot( QofInstance* inst, gpointer user_data )
                                 gnc_lot_get_account (lot_2), FALSE ));
     g_assert_cmpint (gnc_lot_is_closed (lot_1), ==, gnc_lot_is_closed (lot_2));
 
-    g_assert (kvp_frame_compare (gnc_lot_get_slots (lot_1),
-                                 gnc_lot_get_slots (lot_2)) == 0);
+    g_assert (kvp_frame_compare (qof_instance_get_slots (QOF_INSTANCE (lot_1)),
+                                 qof_instance_get_slots (QOF_INSTANCE (lot_2))) == 0);
     splits1 = gnc_lot_get_split_list (lot_1);
     splits2 = gnc_lot_get_split_list (lot_2);
     g_assert_cmpint (g_list_length (splits1), ==, g_list_length (splits2));
diff --git a/src/backend/sql/gnc-account-sql.c b/src/backend/sql/gnc-account-sql.c
index fb1ce98..7d6b3a3 100644
--- a/src/backend/sql/gnc-account-sql.c
+++ b/src/backend/sql/gnc-account-sql.c
@@ -294,12 +294,14 @@ load_all_accounts( GncSqlBackend* be )
         {
             acct_balances_t* balances = (acct_balances_t*)bal->data;
 
+	    qof_instance_increase_editlevel (balances->acct);
             g_object_set( balances->acct,
                           "start-balance", &balances->balance,
                           "start-cleared-balance", &balances->cleared_balance,
                           "start-reconciled-balance", &balances->reconciled_balance,
                           NULL);
 
+	    qof_instance_decrease_editlevel (balances->acct);
         }
         if ( bal_slist != NULL )
         {
@@ -418,7 +420,9 @@ load_account_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, account, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-address-sql.c b/src/backend/sql/gnc-address-sql.c
index a29d4aa..a3f3994 100644
--- a/src/backend/sql/gnc-address-sql.c
+++ b/src/backend/sql/gnc-address-sql.c
@@ -115,7 +115,9 @@ load_address( const GncSqlBackend* be, GncSqlRow* row,
     }
     if ( table_row->gobj_param_name != NULL )
     {
+	qof_instance_increase_editlevel (pObject);
         g_object_set( pObject, table_row->gobj_param_name, addr, NULL );
+	qof_instance_decrease_editlevel (pObject);
     }
     else
     {
diff --git a/src/backend/sql/gnc-backend-sql.c b/src/backend/sql/gnc-backend-sql.c
index 6169388..85f2daa 100644
--- a/src/backend/sql/gnc-backend-sql.c
+++ b/src/backend/sql/gnc-backend-sql.c
@@ -1204,7 +1204,11 @@ const GncSqlColumnTableEntry* table_row )
     s = g_value_get_string( val );
     if ( table_row->gobj_param_name != NULL )
     {
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         g_object_set( pObject, table_row->gobj_param_name, s, NULL );
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
     }
     else
     {
@@ -1308,7 +1312,11 @@ load_int( const GncSqlBackend* be, GncSqlRow* row,
     }
     if ( table_row->gobj_param_name != NULL )
     {
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         g_object_set( pObject, table_row->gobj_param_name, int_value, NULL );
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
     }
     else
     {
@@ -1406,7 +1414,11 @@ load_boolean( const GncSqlBackend* be, GncSqlRow* row,
     }
     if ( table_row->gobj_param_name != NULL )
     {
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         g_object_set( pObject, table_row->gobj_param_name, int_value, NULL );
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
     }
     else
     {
@@ -1499,7 +1511,11 @@ load_int64( const GncSqlBackend* be, GncSqlRow* row,
     }
     if ( table_row->gobj_param_name != NULL )
     {
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         g_object_set( pObject, table_row->gobj_param_name, i64_value, NULL );
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
     }
     else
     {
@@ -1606,7 +1622,11 @@ load_double( const GncSqlBackend* be, GncSqlRow* row,
         }
         if ( table_row->gobj_param_name != NULL )
         {
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
             g_object_set( pObject, table_row->gobj_param_name, d_value, NULL );
+	    if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
         }
         else
         {
@@ -1705,7 +1725,11 @@ load_guid( const GncSqlBackend* be, GncSqlRow* row,
     {
         if ( table_row->gobj_param_name != NULL )
         {
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
             g_object_set( pObject, table_row->gobj_param_name, pGuid, NULL );
+	    if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
         }
         else
         {
@@ -1912,7 +1936,11 @@ load_timespec( const GncSqlBackend* be, GncSqlRow* row,
     {
         if (table_row->gobj_param_name != NULL)
         {
+	if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
             g_object_set( pObject, table_row->gobj_param_name, &ts, NULL );
+	    if (QOF_IS_INSTANCE (pObject))
+	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
         }
         else
         {
@@ -2014,7 +2042,11 @@ load_date( const GncSqlBackend* be, GncSqlRow* row,
 	    g_date_time_unref (gdt);
 	    if ( table_row->gobj_param_name != NULL )
 	    {
+		if (QOF_IS_INSTANCE (pObject))
+		    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
 		g_object_set( pObject, table_row->gobj_param_name, date, NULL );
+		if (QOF_IS_INSTANCE (pObject))
+		    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
 	    }
 	    else
 	    {
@@ -2048,7 +2080,12 @@ load_date( const GncSqlBackend* be, GncSqlRow* row,
                     date = g_date_new_dmy( day, month, year );
                     if ( table_row->gobj_param_name != NULL )
                     {
-                        g_object_set( pObject, table_row->gobj_param_name, date, NULL );
+			if (QOF_IS_INSTANCE (pObject))
+			    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
+                        g_object_set (pObject, table_row->gobj_param_name,
+				      date, NULL);
+			if (QOF_IS_INSTANCE (pObject))
+			    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
                     }
                     else
                     {
@@ -2187,7 +2224,11 @@ load_numeric( const GncSqlBackend* be, GncSqlRow* row,
     {
         if ( table_row->gobj_param_name != NULL )
         {
+	    if (QOF_IS_INSTANCE (pObject))
+		qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
             g_object_set( pObject, table_row->gobj_param_name, &n, NULL );
+	    if (QOF_IS_INSTANCE (pObject))
+		qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         }
         else
         {
diff --git a/src/backend/sql/gnc-bill-term-sql.c b/src/backend/sql/gnc-bill-term-sql.c
index 4846b0f..eaf7243 100644
--- a/src/backend/sql/gnc-bill-term-sql.c
+++ b/src/backend/sql/gnc-bill-term-sql.c
@@ -363,7 +363,9 @@ load_billterm_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, term, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-budget-sql.c b/src/backend/sql/gnc-budget-sql.c
index 59a7efb..4c697c9 100644
--- a/src/backend/sql/gnc-budget-sql.c
+++ b/src/backend/sql/gnc-budget-sql.c
@@ -500,7 +500,9 @@ load_budget_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, budget, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-commodity-sql.c b/src/backend/sql/gnc-commodity-sql.c
index 2389946..1f8f556 100644
--- a/src/backend/sql/gnc-commodity-sql.c
+++ b/src/backend/sql/gnc-commodity-sql.c
@@ -283,7 +283,9 @@ load_commodity_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, commodity, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else if ( setter != NULL )
             {
diff --git a/src/backend/sql/gnc-invoice-sql.c b/src/backend/sql/gnc-invoice-sql.c
index 8788960..72c1cd2 100644
--- a/src/backend/sql/gnc-invoice-sql.c
+++ b/src/backend/sql/gnc-invoice-sql.c
@@ -303,7 +303,9 @@ load_invoice_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, invoice, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-lots-sql.c b/src/backend/sql/gnc-lots-sql.c
index a6ee240..22c4a70 100644
--- a/src/backend/sql/gnc-lots-sql.c
+++ b/src/backend/sql/gnc-lots-sql.c
@@ -235,7 +235,9 @@ load_lot_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, lot, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-order-sql.c b/src/backend/sql/gnc-order-sql.c
index 46b0ae0..a7bc177 100644
--- a/src/backend/sql/gnc-order-sql.c
+++ b/src/backend/sql/gnc-order-sql.c
@@ -220,7 +220,9 @@ load_order_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, order, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-owner-sql.c b/src/backend/sql/gnc-owner-sql.c
index 4b89c54..2e779f0 100644
--- a/src/backend/sql/gnc-owner-sql.c
+++ b/src/backend/sql/gnc-owner-sql.c
@@ -156,7 +156,9 @@ load_owner( const GncSqlBackend* be, GncSqlRow* row,
 
     if ( table_row->gobj_param_name != NULL )
     {
+	qof_instance_increase_editlevel (pObject);
         g_object_set( pObject, table_row->gobj_param_name, &owner, NULL );
+	qof_instance_decrease_editlevel (pObject);
     }
     else
     {
diff --git a/src/backend/sql/gnc-tax-table-sql.c b/src/backend/sql/gnc-tax-table-sql.c
index 21466d4..fbf5d37 100644
--- a/src/backend/sql/gnc-tax-table-sql.c
+++ b/src/backend/sql/gnc-tax-table-sql.c
@@ -523,7 +523,9 @@ load_taxtable_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, taxtable, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-transaction-sql.c b/src/backend/sql/gnc-transaction-sql.c
index 0ea2189..46fc3d9 100644
--- a/src/backend/sql/gnc-transaction-sql.c
+++ b/src/backend/sql/gnc-transaction-sql.c
@@ -415,6 +415,7 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
                           "end-reconciled-balance", &pnew_end_r_bal,
                           NULL );
 
+	    qof_instance_increase_editlevel (balns-acc);
             if ( !gnc_numeric_eq( *pnew_end_bal, balns->end_bal ) )
             {
                 adj = gnc_numeric_sub( balns->end_bal, *pnew_end_bal,
@@ -422,6 +423,7 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
                 balns->start_bal = gnc_numeric_add( balns->start_bal, adj,
                                                     GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                 g_object_set( balns->acc, "start-balance", &balns->start_bal, NULL );
+		qof_instance_decrease_editlevel (balns-acc);
             }
             if ( !gnc_numeric_eq( *pnew_end_c_bal, balns->end_cleared_bal ) )
             {
@@ -439,6 +441,7 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
                                               GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                 g_object_set( balns->acc, "start-reconciled-balance", &balns->start_reconciled_bal, NULL );
             }
+	    qof_instance_decrease_editlevel (balns-acc);
             xaccAccountRecomputeBalance( balns->acc );
             g_free( pnew_end_bal );
             g_free( pnew_end_c_bal );
@@ -1461,7 +1464,9 @@ load_tx_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
+		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, tx, NULL );
+		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/xml/gnc-account-xml-v2.c b/src/backend/xml/gnc-account-xml-v2.c
index 8137147..85d475e 100644
--- a/src/backend/xml/gnc-account-xml-v2.c
+++ b/src/backend/xml/gnc-account-xml-v2.c
@@ -71,6 +71,9 @@ const gchar *account_version_string = "2.0.0";
 #define act_hidden_string "act:hidden"
 #define act_placeholder_string "act:placeholder"
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance *);
+
 xmlNodePtr
 gnc_account_dom_tree_create(Account *act,
                             gboolean exporting,
@@ -134,7 +137,7 @@ gnc_account_dom_tree_create(Account *act,
         xmlAddChild(ret, text_to_dom_tree(act_description_string, str));
     }
 
-    kf = xaccAccountGetSlots(act);
+    kf = qof_instance_get_slots (QOF_INSTANCE (act));
     if (kf)
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree(act_slots_string, kf);
@@ -370,7 +373,7 @@ account_slots_handler (xmlNodePtr node, gpointer act_pdata)
     struct account_pdata *pdata = act_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, xaccAccountGetSlots (pdata->account));
+           (node, qof_instance_get_slots (QOF_INSTANCE (pdata->account)));
 }
 
 static gboolean
diff --git a/src/backend/xml/gnc-book-xml-v2.c b/src/backend/xml/gnc-book-xml-v2.c
index aa7a14f..6fcae46 100644
--- a/src/backend/xml/gnc-book-xml-v2.c
+++ b/src/backend/xml/gnc-book-xml-v2.c
@@ -109,10 +109,10 @@ gnc_book_dom_tree_create(QofBook *book)
     xmlAddChild(ret, guid_to_dom_tree(book_id_string,
                                       qof_book_get_guid(book)));
 
-    if (qof_book_get_slots(book))
+    if (qof_instance_get_slots (QOF_INSTANCE (book)))
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string,
-                             qof_book_get_slots(book));
+                             qof_instance_get_slots (QOF_INSTANCE (book)));
         if (kvpnode)
             xmlAddChild(ret, kvpnode);
     }
@@ -162,10 +162,10 @@ write_book_parts(FILE *out, QofBook *book)
     if (ferror(out) || fprintf(out, "\n") < 0)
         return FALSE;
 
-    if (qof_book_get_slots(book))
+    if (qof_instance_get_slots (QOF_INSTANCE (book)))
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string,
-                             qof_book_get_slots(book));
+                             qof_instance_get_slots (QOF_INSTANCE (book)));
         if (kvpnode)
         {
             xmlElemDump(out, NULL, kvpnode);
@@ -203,7 +203,7 @@ book_slots_handler (xmlNodePtr node, gpointer book_pdata)
 
     /* the below works only because the get is gaurenteed to return
      * a frame, even if its empty */
-    success = dom_tree_to_kvp_frame_given (node, qof_book_get_slots (book));
+    success = dom_tree_to_kvp_frame_given (node, qof_instance_get_slots (QOF_INSTANCE (book)));
 
     g_return_val_if_fail(success, FALSE);
 
diff --git a/src/backend/xml/gnc-invoice-xml-v2.c b/src/backend/xml/gnc-invoice-xml-v2.c
index 2a9c769..901a733 100644
--- a/src/backend/xml/gnc-invoice-xml-v2.c
+++ b/src/backend/xml/gnc-invoice-xml-v2.c
@@ -72,6 +72,9 @@ const gchar *invoice_version_string = "2.0.0";
 #define invoice_tochargeamt_string "invoice:charge-amt"
 #define invoice_slots_string "invoice:slots"
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance *);
+
 static void
 maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
 {
@@ -410,7 +413,7 @@ invoice_slots_handler (xmlNodePtr node, gpointer invoice_pdata)
     struct invoice_pdata *pdata = invoice_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, xaccAccountGetSlots (pdata->invoice));
+           (node, qof_instance_get_slots (QOF_INSTANCE (pdata->invoice)));
 }
 
 static struct dom_tree_handler invoice_handlers_v2[] =
diff --git a/src/backend/xml/gnc-lot-xml-v2.c b/src/backend/xml/gnc-lot-xml-v2.c
index f24001a..503e981 100644
--- a/src/backend/xml/gnc-lot-xml-v2.c
+++ b/src/backend/xml/gnc-lot-xml-v2.c
@@ -53,6 +53,8 @@ const gchar *lot_version_string = "2.0.0";
 #define gnc_lot_string "gnc:lot"
 #define lot_id_string "lot:id"
 #define lot_slots_string "lot:slots"
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance *);
 
 xmlNodePtr
 gnc_lot_dom_tree_create(GNCLot *lot)
@@ -66,7 +68,7 @@ gnc_lot_dom_tree_create(GNCLot *lot)
 
     xmlAddChild(ret, guid_to_dom_tree(lot_id_string, gnc_lot_get_guid(lot)));
 
-    kf = gnc_lot_get_slots (lot);
+    kf = qof_instance_get_slots (QOF_INSTANCE (lot));
     if (kf)
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree(lot_slots_string, kf);
@@ -112,7 +114,7 @@ lot_slots_handler (xmlNodePtr node, gpointer p)
 
     ENTER("(lot=%p)", pdata->lot);
     success = dom_tree_to_kvp_frame_given
-              (node, gnc_lot_get_slots (pdata->lot));
+	(node, qof_instance_get_slots (QOF_INSTANCE (pdata->lot)));
 
     LEAVE("");
     g_return_val_if_fail(success, FALSE);
diff --git a/src/backend/xml/gnc-transaction-xml-v2.c b/src/backend/xml/gnc-transaction-xml-v2.c
index 2ccd67a..a2a3513 100644
--- a/src/backend/xml/gnc-transaction-xml-v2.c
+++ b/src/backend/xml/gnc-transaction-xml-v2.c
@@ -49,6 +49,9 @@
 
 const gchar *transaction_version_string = "2.0.0";
 
+/* EFFECTIVE FRIEND FUNCTION */
+extern KvpFrame *qof_instance_get_slots (const QofInstance *);
+
 static void
 add_gnc_num(xmlNodePtr node, const gchar *tag, gnc_numeric num)
 {
@@ -129,7 +132,7 @@ split_to_dom_tree(const gchar *tag, Split *spl)
     }
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree("split:slots",
-                             xaccSplitGetSlots(spl));
+                             qof_instance_get_slots (QOF_INSTANCE (spl)));
         if (kvpnode)
         {
             xmlAddChild(ret, kvpnode);
@@ -192,7 +195,7 @@ gnc_transaction_dom_tree_create(Transaction *trn)
 
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree("trn:slots",
-                             xaccTransGetSlots(trn));
+                             qof_instance_get_slots (QOF_INSTANCE (trn)));
         if (kvpnode)
         {
             xmlAddChild(ret, kvpnode);
@@ -368,7 +371,7 @@ spl_slots_handler(xmlNodePtr node, gpointer data)
     gboolean successful;
 
     successful = dom_tree_to_kvp_frame_given(node,
-                 xaccSplitGetSlots (pdata->split));
+                 qof_instance_get_slots (QOF_INSTANCE (pdata->split)));
     g_return_val_if_fail(successful, FALSE);
 
     return TRUE;
@@ -527,7 +530,7 @@ trn_slots_handler(xmlNodePtr node, gpointer trans_pdata)
     Transaction *trn = pdata->trans;
     gboolean successful;
 
-    successful = dom_tree_to_kvp_frame_given(node, xaccTransGetSlots(trn));
+    successful = dom_tree_to_kvp_frame_given(node, qof_instance_get_slots (QOF_INSTANCE (trn)));
 
     g_return_val_if_fail(successful, FALSE);
 
diff --git a/src/backend/xml/io-gncxml-v2.c b/src/backend/xml/io-gncxml-v2.c
index 908bff1..43e9590 100644
--- a/src/backend/xml/io-gncxml-v2.c
+++ b/src/backend/xml/io-gncxml-v2.c
@@ -2182,7 +2182,7 @@ gnc_xml2_parse_with_subst (FileBackend *fbe, QofBook *book, GHashTable *subst)
                   push_data, GNC_BOOK_XML2_FILE);
 
     if (success)
-        qof_book_kvp_changed(book);
+	qof_instance_set_dirty (QOF_INSTANCE (book));
 
     return success;
 }
diff --git a/src/backend/xml/test/test-xml-account.c b/src/backend/xml/test/test-xml-account.c
index b6838e8..8055489 100644
--- a/src/backend/xml/test/test-xml-account.c
+++ b/src/backend/xml/test/test-xml-account.c
@@ -144,7 +144,7 @@ node_and_account_equal(xmlNodePtr node, Account *act)
         {
             /* xaccAccountDeleteOldData (act); */
 
-            if (!equals_node_val_vs_kvp_frame(mark, xaccAccountGetSlots(act)))
+            if (!equals_node_val_vs_kvp_frame(mark, qof_instance_get_slots(QOF_INSTANCE (act))))
             {
                 return g_strdup("slots differ");
             }
diff --git a/src/backend/xml/test/test-xml-transaction.c b/src/backend/xml/test/test-xml-transaction.c
index c194397..14edc79 100644
--- a/src/backend/xml/test/test-xml-transaction.c
+++ b/src/backend/xml/test/test-xml-transaction.c
@@ -306,7 +306,7 @@ node_and_transaction_equal(xmlNodePtr node, Transaction *trn)
         }
         else if (g_strcmp0((char*)mark->name, "trn:slots") == 0)
         {
-            if (!equals_node_val_vs_kvp_frame(mark, xaccTransGetSlots(trn)))
+            if (!equals_node_val_vs_kvp_frame(mark, qof_instance_get_slots (QOF_INSTANCE (trn))))
             {
                 return "slots differ";
             }
diff --git a/src/business/business-gnome/dialog-invoice.c b/src/business/business-gnome/dialog-invoice.c
index 5acee72..c00a5e4 100644
--- a/src/business/business-gnome/dialog-invoice.c
+++ b/src/business/business-gnome/dialog-invoice.c
@@ -90,8 +90,6 @@
 #define GNC_PREF_ACCUM_SPLITS    "accumulate-splits"
 #define GNC_PREF_DAYS_IN_ADVANCE "days-in-advance"
 
-#define LAST_POSTED_TO_ACCT "last-posted-to-acct"
-
 void gnc_invoice_window_ok_cb (GtkWidget *widget, gpointer data);
 void gnc_invoice_window_cancel_cb (GtkWidget *widget, gpointer data);
 void gnc_invoice_window_help_cb (GtkWidget *widget, gpointer data);
@@ -681,7 +679,6 @@ gnc_dialog_post_invoice(InvoiceWindow *iw, char *message,
     GList * acct_types = NULL;
     GList * acct_commodities = NULL;
     QofInstance *owner_inst;
-    KvpFrame *kvpf;
     EntryList *entries, *entries_iter;
 
     invoice = iw_get_invoice (iw);
@@ -726,12 +723,14 @@ gnc_dialog_post_invoice(InvoiceWindow *iw, char *message,
     /* Get the due date and posted account */
     *ddue = *postdate;
     *memo = NULL;
-
-    owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
-    kvpf = qof_instance_get_slots (owner_inst);
-    *acc = xaccAccountLookup (kvp_frame_get_guid (kvpf, LAST_POSTED_TO_ACCT),
-                              iw->book);
-
+    {
+	GncGUID *guid = NULL;
+	owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
+	qof_instance_get (owner_inst,
+			  "invoice-last-posted-account", &guid,
+			  NULL);
+	*acc = xaccAccountLookup (guid, iw->book);
+    }
     /* Get the default for the accumulate option */
     *accumulate = gnc_prefs_get_bool(GNC_PREFS_GROUP_INVOICE, GNC_PREF_ACCUM_SPLITS);
 
@@ -762,8 +761,6 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
     Timespec ddue, postdate;
     gboolean accumulate;
     QofInstance *owner_inst;
-    KvpFrame *kvpf;
-    KvpValue *kvp_val;
     const char *text;
     GHashTable *foreign_currs;
     GHashTableIter foreign_currs_iter;
@@ -911,14 +908,18 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
     }
 
 
-    /* Save account as last used account in the kvp frame of the invoice owner */
+    /* Save account as last used account in the owner's
+     * invoice-last-posted-account property.
+     */
     owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
-    kvpf = qof_instance_get_slots (owner_inst);
-    kvp_val = kvp_value_new_guid (qof_instance_get_guid (QOF_INSTANCE (acc)));;
-    qof_begin_edit (owner_inst);
-    kvp_frame_set_slot_nc (kvpf, LAST_POSTED_TO_ACCT, kvp_val);
-    qof_instance_set_dirty (owner_inst);
-    qof_commit_edit (owner_inst);
+    {
+	const GncGUID *guid = qof_instance_get_guid (QOF_INSTANCE (acc));
+	qof_begin_edit (owner_inst);
+	qof_instance_set (owner_inst,
+			  "invoice-last-posted-account", guid,
+			  NULL);
+	qof_commit_edit (owner_inst);
+    }
 
     /* ... post it ... */
     if (is_cust_doc)
diff --git a/src/business/business-gnome/dialog-payment.c b/src/business/business-gnome/dialog-payment.c
index b380f3c..151f678 100644
--- a/src/business/business-gnome/dialog-payment.c
+++ b/src/business/business-gnome/dialog-payment.c
@@ -452,23 +452,15 @@ gnc_payment_dialog_owner_changed (PaymentWindow *pw)
 {
     Account *last_acct = NULL;
     GncGUID *guid = NULL;
-    KvpValue* value;
-    KvpFrame* slots;
     GncOwner *owner = &pw->owner;
 
     /* If the owner changed, the initial invoice is no longer valid */
     pw->invoice = NULL;
 
     /* Now handle the account tree */
-    slots = gncOwnerGetSlots(owner);
-    if (slots)
-    {
-        value = kvp_frame_get_slot_path(slots, "payment", "last_acct", NULL);
-        if (value)
-        {
-            guid = kvp_value_get_guid(value);
-        }
-    }
+    qof_instance_get (QOF_INSTANCE (owner),
+		      "payment-last-account", &guid,
+		      NULL);
 
     /* refresh the post and acc available accounts, but cleanup first */
     if (pw->acct_types)
@@ -514,20 +506,17 @@ gnc_payment_dialog_post_to_changed (PaymentWindow *pw)
 static void
 gnc_payment_dialog_remember_account (PaymentWindow *pw, Account *acc)
 {
-    KvpValue* value;
-    KvpFrame* slots = gncOwnerGetSlots(&pw->owner);
+    GncOwner *owner = &pw->owner;
+    const GncGUID *guid;
 
     if (!acc) return;
-    if (!slots) return;
-
-    value = kvp_value_new_guid(xaccAccountGetGUID(acc));
-    if (!value) return;
 
-    xaccAccountBeginEdit (acc);
-    kvp_frame_set_slot_path(slots, value, "payment", "last_acct", NULL);
-    qof_instance_set_dirty (QOF_INSTANCE (acc));
-    xaccAccountCommitEdit (acc);
-    kvp_value_delete(value);
+    guid = xaccAccountGetGUID(acc);
+    qof_begin_edit (QOF_INSTANCE (owner));
+    qof_instance_set (QOF_INSTANCE (owner),
+		      "payment-last-account", guid,
+		      NULL);
+    qof_commit_edit (QOF_INSTANCE (owner));
 }
 
 
diff --git a/src/core-utils/gnc-features.c b/src/core-utils/gnc-features.c
index 0336fe2..f4846f4 100644
--- a/src/core-utils/gnc-features.c
+++ b/src/core-utils/gnc-features.c
@@ -67,10 +67,12 @@ static void gnc_features_init ()
                              g_strdup (known_features[i].desc));
 }
 
-static void gnc_features_test_one(const gchar *key, KvpValue *value, gpointer data)
+static void gnc_features_test_one(gpointer pkey, gpointer value,
+				  gpointer data)
 {
+    const gchar *key = (const gchar*)pkey;
+    const gchar *feature_desc = (const gchar*)value;
     GList **unknown_features;
-    gchar *feature_desc;
 
     g_assert(data);
     unknown_features = (GList**) data;
@@ -80,54 +82,47 @@ static void gnc_features_test_one(const gchar *key, KvpValue *value, gpointer da
         return;
 
     /* It is unknown, so add the description to the unknown features list: */
-    feature_desc = kvp_value_get_string(value);
     g_assert(feature_desc);
 
-    *unknown_features = g_list_prepend(*unknown_features, feature_desc);
+    *unknown_features = g_list_prepend(*unknown_features,
+				       (gpointer)feature_desc);
 }
 
 /* Check if the session requires features unknown to this version of GnuCash.
  *
- * Returns a message to display if we found unknown features, NULL if we're okay.
+ * Returns a message to display if we found unknown features, NULL if
+ * we're okay.
  */
 gchar *gnc_features_test_unknown (QofBook *book)
 {
-    KvpFrame *frame = qof_book_get_slots (book);
-    KvpValue *value;
 
     /* Setup the known_features hash table */
     gnc_features_init();
 
-    g_assert(frame);
-    value = kvp_frame_get_value(frame, "features");
+    GList* features_list = NULL;
+    GHashTable *features_used = qof_book_get_features (book);
 
-    if (value)
+    /* Iterate over the members of this frame for unknown features */
+    g_hash_table_foreach (features_used, &gnc_features_test_one,
+			  &features_list);
+    if (features_list)
     {
-        GList* features_list = NULL;
-        frame = kvp_value_get_frame(value);
-        g_assert(frame);
-
-        /* Iterate over the members of this frame for unknown features */
-        kvp_frame_for_each_slot(frame, &gnc_features_test_one, &features_list);
-        if (features_list)
-        {
-            GList *i;
-            char* msg = g_strdup(
-                            _("This Dataset contains features not supported by this "
-                              "version of GnuCash. You must use a newer version of "
-                              "GnuCash in order to support the following features:"
+	GList *i;
+	char* msg = g_strdup(_("This Dataset contains features not supported "
+			       "by this version of GnuCash. You must use a "
+			       "newer version of GnuCash in order to support "
+			       "the following features:"
                              ));
 
-            for (i = features_list; i; i = i->next)
-            {
-                char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
-                g_free (msg);
-                msg = tmp;
-            }
+	for (i = features_list; i; i = i->next)
+	{
+	    char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
+	    g_free (msg);
+	    msg = tmp;
+	}
 
-            g_list_free(features_list);
-            return msg;
-        }
+	g_list_free(features_list);
+	return msg;
     }
 
     return NULL;
@@ -135,9 +130,7 @@ gchar *gnc_features_test_unknown (QofBook *book)
 
 void gnc_features_set_used (QofBook *book, const gchar *feature)
 {
-    KvpFrame *frame;
     const gchar *description;
-    gchar *kvp_path;
 
     g_return_if_fail (book);
     g_return_if_fail (feature);
@@ -152,10 +145,7 @@ void gnc_features_set_used (QofBook *book, const gchar *feature)
         return;
     }
 
-    frame = qof_book_get_slots (book);
-    kvp_path = g_strconcat ("/features/", feature, NULL);
-    kvp_frame_set_string (frame, kvp_path, description);
-    qof_book_kvp_changed (book);
+    qof_book_set_feature (book, feature, description);
 
 
 }
diff --git a/src/engine/Account.c b/src/engine/Account.c
index 4b30953..9bc7dda 100644
--- a/src/engine/Account.c
+++ b/src/engine/Account.c
@@ -38,12 +38,20 @@
 #include "gnc-glib-utils.h"
 #include "gnc-lot.h"
 #include "gnc-pricedb.h"
+#include "qofinstance-p.h"
 
 static QofLogModule log_module = GNC_MOD_ACCOUNT;
 
 /* The Canonical Account Separator.  Pre-Initialized. */
 static gchar account_separator[8] = ".";
 static gunichar account_uc_separator = ':';
+/* Predefined KVP paths */
+static const char *KEY_ASSOC_INCOME_ACCOUNT = "ofx/associated-income-account";
+#define AB_KEY "hbci"
+#define AB_ACCOUNT_ID "account-id"
+#define AB_ACCOUNT_UID "account-uid"
+#define AB_BANK_CODE "bank-code"
+#define AB_TRANS_RETRIEVAL "trans-retrieval"
 
 enum
 {
@@ -53,37 +61,48 @@ enum
 enum
 {
     PROP_0,
-    PROP_NAME,
-    PROP_FULL_NAME,
-    PROP_CODE,
-    PROP_DESCRIPTION,
-    PROP_COLOR,
-    PROP_NOTES,
-    PROP_TYPE,
-
-    PROP_COMMODITY,
-    PROP_COMMODITY_SCU,
-    PROP_NON_STD_SCU,
-    PROP_SORT_DIRTY,
-    PROP_BALANCE_DIRTY,
-    PROP_START_BALANCE,
-    PROP_START_CLEARED_BALANCE,
-    PROP_START_RECONCILED_BALANCE,
-    PROP_END_BALANCE,
-    PROP_END_CLEARED_BALANCE,
-    PROP_END_RECONCILED_BALANCE,
-
-    PROP_POLICY,
-    PROP_MARK,
-    PROP_TAX_RELATED,
-    PROP_TAX_CODE,
-    PROP_TAX_SOURCE,
-    PROP_TAX_COPY_NUMBER,
-
-    PROP_HIDDEN,
-    PROP_PLACEHOLDER,
-    PROP_FILTER,
-    PROP_SORT_ORDER,
+    PROP_NAME,				/* Table */
+    PROP_FULL_NAME,			/* Constructed */
+    PROP_CODE,				/* Table */
+    PROP_DESCRIPTION,			/* Table */
+    PROP_COLOR,				/* KVP */
+    PROP_NOTES,				/* KVP */
+    PROP_TYPE,				/* Table */
+
+//    PROP_PARENT,			/* Table, Not a property */
+    PROP_COMMODITY,			/* Table */
+    PROP_COMMODITY_SCU,			/* Table */
+    PROP_NON_STD_SCU,			/* Table */
+    PROP_END_BALANCE,			/* Constructed */
+    PROP_END_CLEARED_BALANCE,		/* Constructed */
+    PROP_END_RECONCILED_BALANCE,	/* Constructed */
+
+    PROP_TAX_RELATED,			/* KVP */
+    PROP_TAX_CODE,			/* KVP */
+    PROP_TAX_SOURCE,			/* KVP */
+    PROP_TAX_COPY_NUMBER,		/* KVP */
+
+    PROP_HIDDEN,			/* Table slot exists, but in KVP in memory & xml */
+    PROP_PLACEHOLDER,			/* Table slot exists, but in KVP in memory & xml */
+    PROP_FILTER,			/* KVP */
+    PROP_SORT_ORDER,			/* KVP */
+
+    PROP_LOT_NEXT_ID,			/* KVP */
+    PROP_ONLINE_ACCOUNT,		/* KVP */
+    PROP_OFX_INCOME_ACCOUNT,		/* KVP */
+    PROP_AB_ACCOUNT_ID,			/* KVP */
+    PROP_AB_ACCOUNT_UID,		/* KVP */
+    PROP_AB_BANK_CODE,			/* KVP */
+    PROP_AB_TRANS_RETRIEVAL,		/* KVP */
+
+    PROP_RUNTIME_0,
+    PROP_POLICY,			/* Cached Value */
+    PROP_MARK,				/* Runtime Value */
+    PROP_SORT_DIRTY,			/* Runtime Value */
+    PROP_BALANCE_DIRTY,			/* Runtime Value */
+    PROP_START_BALANCE,			/* Runtime Value */
+    PROP_START_CLEARED_BALANCE,		/* Runtime Value */
+    PROP_START_RECONCILED_BALANCE,	/* Runtime Value */
 };
 
 #define GET_PRIVATE(o)  \
@@ -282,6 +301,8 @@ gnc_account_get_property (GObject         *object,
 {
     Account *account;
     AccountPrivate *priv;
+    const gchar *key;
+    GValue *temp;
 
     g_return_if_fail(GNC_IS_ACCOUNT(object));
 
@@ -377,6 +398,36 @@ gnc_account_get_property (GObject         *object,
     case PROP_SORT_ORDER:
         g_value_set_string(value, xaccAccountGetSortOrder(account));
         break;
+    case PROP_LOT_NEXT_ID:
+	key = "lot-mgmt/next-id";
+        /* Pre-set the value in case the frame is empty */
+	g_value_set_int64 (value, 0);
+	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_ONLINE_ACCOUNT:
+	key = "online_id";
+	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_OFX_INCOME_ACCOUNT:
+	key = KEY_ASSOC_INCOME_ACCOUNT;
+	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_AB_ACCOUNT_ID:
+	key = AB_KEY "/" AB_ACCOUNT_ID;
+	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_AB_ACCOUNT_UID:
+	key = AB_KEY "/" AB_ACCOUNT_UID;
+	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_AB_BANK_CODE:
+	key = AB_KEY "/" AB_BANK_CODE;
+	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_AB_TRANS_RETRIEVAL:
+	key = AB_KEY "/" AB_TRANS_RETRIEVAL;
+	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -391,10 +442,13 @@ gnc_account_set_property (GObject         *object,
 {
     Account *account;
     gnc_numeric *number;
+    const gchar *key = NULL;
 
     g_return_if_fail(GNC_IS_ACCOUNT(object));
 
     account = GNC_ACCOUNT(object);
+    if (prop_id < PROP_RUNTIME_0)
+	g_assert (qof_instance_get_editlevel(account));
 
     switch (prop_id)
     {
@@ -476,6 +530,34 @@ gnc_account_set_property (GObject         *object,
     case PROP_SORT_ORDER:
         xaccAccountSetSortOrder(account, g_value_get_string(value));
         break;
+    case PROP_LOT_NEXT_ID:
+	key = "lot-mgmt/next-id";
+	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_ONLINE_ACCOUNT:
+	key = "online_id";
+	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_OFX_INCOME_ACCOUNT:
+	key = KEY_ASSOC_INCOME_ACCOUNT;
+	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_AB_ACCOUNT_ID:
+	key = AB_KEY "/" AB_ACCOUNT_ID;
+	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_AB_ACCOUNT_UID:
+	key = AB_KEY "/" AB_ACCOUNT_UID;
+	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_AB_BANK_CODE:
+	key = AB_KEY "/" AB_BANK_CODE;
+	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
+	break;
+    case PROP_AB_TRANS_RETRIEVAL:
+	key = AB_KEY "/" AB_TRANS_RETRIEVAL;
+	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -833,6 +915,77 @@ gnc_account_class_init (AccountClass *klass)
                           "the sort order to be recalled.",
                           NULL,
                           G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_LOT_NEXT_ID,
+     g_param_spec_int64 ("lot-next-id",
+                         "Lot Next ID",
+                         "Tracks the next id to use in gnc_lot_make_default.",
+                         (gint64)1,
+                         G_MAXINT64,
+                         (gint64)1,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_ONLINE_ACCOUNT,
+     g_param_spec_string ("online-id",
+                          "Online Account ID",
+                          "The online account which corresponds to this "
+			  "account for OFX import",
+                          NULL,
+                          G_PARAM_READWRITE));
+
+     g_object_class_install_property(
+       gobject_class,
+       PROP_OFX_INCOME_ACCOUNT,
+        g_param_spec_boxed("ofx-income-account",
+			   "Associated income account",
+			   "Used by the OFX importer.",
+			   GNC_TYPE_GUID,
+			   G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_AB_ACCOUNT_ID,
+     g_param_spec_string ("ab-account-id",
+                          "AQBanking Account ID",
+                          "The AqBanking account which corresponds to this "
+			  "account for AQBanking import",
+                          NULL,
+                          G_PARAM_READWRITE));
+    g_object_class_install_property
+    (gobject_class,
+     PROP_AB_BANK_CODE,
+     g_param_spec_string ("ab-bank-code",
+                          "AQBanking Bank Code",
+                          "The online account which corresponds to this "
+			  "account for AQBanking import",
+                          NULL,
+                          G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_AB_ACCOUNT_UID,
+     g_param_spec_int64 ("ab-account-uid",
+                         "AQBanking Account UID",
+                         "Tracks the next id to use in gnc_lot_make_default.",
+                         (gint64)1,
+                         G_MAXINT64,
+                         (gint64)1,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_AB_TRANS_RETRIEVAL,
+     g_param_spec_boxed("ab-trans-retrieval",
+                        "AQBanking Last Transaction Retrieval",
+                        "The time of the last transaction retrieval for this "
+			"account.",
+                        GNC_TYPE_TIMESPEC,
+                        G_PARAM_READWRITE));
+
 }
 
 static void
@@ -4279,6 +4432,80 @@ xaccAccountSetLastNum (Account *acc, const char *num)
     xaccAccountCommitEdit (acc);
 }
 
+static Account *
+GetOrMakeOrphanAccount (Account *root, gnc_commodity * currency)
+{
+    char * accname;
+    Account * acc;
+
+    g_return_val_if_fail (root, NULL);
+
+    /* build the account name */
+    if (!currency)
+    {
+        PERR ("No currency specified!");
+        return NULL;
+    }
+
+    accname = g_strconcat (_("Orphaned Gains"), "-",
+                           gnc_commodity_get_mnemonic (currency), NULL);
+
+    /* See if we've got one of these going already ... */
+    acc = gnc_account_lookup_by_name(root, accname);
+
+    if (acc == NULL)
+    {
+        /* Guess not. We'll have to build one. */
+        acc = xaccMallocAccount (gnc_account_get_book(root));
+        xaccAccountBeginEdit (acc);
+        xaccAccountSetName (acc, accname);
+        xaccAccountSetCommodity (acc, currency);
+        xaccAccountSetType (acc, ACCT_TYPE_INCOME);
+        xaccAccountSetDescription (acc, _("Realized Gain/Loss"));
+        xaccAccountSetNotes (acc,
+                             _("Realized Gains or Losses from "
+                               "Commodity or Trading Accounts "
+                               "that haven't been recorded elsewhere."));
+
+        /* Hang the account off the root. */
+        gnc_account_append_child (root, acc);
+        xaccAccountCommitEdit (acc);
+    }
+
+    g_free (accname);
+
+    return acc;
+}
+
+Account *
+xaccAccountGainsAccount (Account *acc, gnc_commodity *curr)
+{
+    KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (acc));
+    const gchar *curr_name = gnc_commodity_get_unique_name (curr);
+    GncGUID *guid;
+    Account *gains_account;
+
+    frame = kvp_frame_get_frame_slash (frame, "/lot-mgmt/gains-act/");
+    guid = kvp_frame_get_guid (frame, curr_name);
+    if (guid == NULL) /* No gains account for this currency */
+    {
+	gains_account = GetOrMakeOrphanAccount (gnc_account_get_root (acc),
+						curr);
+	guid = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (gains_account));
+	xaccAccountBeginEdit (acc);
+	{
+	    kvp_frame_set_guid (frame, curr_name, guid);
+	    qof_instance_set_dirty (QOF_INSTANCE (acc));
+	}
+	xaccAccountCommitEdit (acc);
+    }
+    else
+	gains_account = xaccAccountLookup (guid,
+					   qof_instance_get_book(acc));
+
+    return gains_account;
+}
+
 /********************************************************************\
 \********************************************************************/
 
@@ -4719,6 +4946,508 @@ xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc,
 }
 
 /* ================================================================ */
+/* The following functions are used by
+ * src/import-export/import-backend.c to manipulate the contra-account
+ * matching data. See src/import-export/import-backend.c for explanations.
+ */
+/* FIXME: These data are stored per-account in KVP and the functions
+ * work directly on KVP data structures. This prevents moving KVP to a
+ * backend-only abstraction.
+ */
+
+
+typedef struct _GncImportMatchMap
+{
+    kvp_frame *	frame;
+    Account *	acc;
+    QofBook *	book;
+} GncImportMatchMap;
+
+#define IMAP_FRAME		"import-map"
+#define IMAP_FRAME_BAYES	"import-map-bayes"
+GncImportMatchMap * gnc_account_create_imap (Account *acc);
+Account* gnc_imap_find_account(GncImportMatchMap *imap, const char* category,
+                               const char *key);
+void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
+                           const char *key, Account *acc);
+Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList* tokens);
+void gnc_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
+                                 Account *acc);
+
+/* Obtain an ImportMatchMap object from an Account or a Book */
+GncImportMatchMap *
+gnc_account_create_imap (Account *acc)
+{
+    GncImportMatchMap *imap;
+    kvp_frame *frame;
+
+    if (!acc) return NULL;
+    frame = qof_instance_get_slots (QOF_INSTANCE (acc));
+    g_return_val_if_fail (frame != NULL, NULL);
+    g_return_val_if_fail (frame != NULL, NULL);
+
+    imap = g_new0(GncImportMatchMap, 1);
+    imap->frame = frame;
+
+    /* Cache the book for easy lookups; store the account/book for
+     * marking dirtiness
+     */
+    imap->acc = acc;
+    imap->book = gnc_account_get_book (acc);
+
+    return imap;
+}
+
+/* Look up an Account in the map */
+Account*
+gnc_imap_find_account (GncImportMatchMap *imap,
+		       const char *category,
+		       const char *key)
+{
+    kvp_value *value;
+    GncGUID * guid;
+
+    if (!imap || !key) return NULL;
+    if (!category)
+    {
+        category = key;
+        key = NULL;
+    }
+
+    value = kvp_frame_get_slot_path (imap->frame, IMAP_FRAME,
+				     category, key, NULL);
+    if (!value) return NULL;
+
+    guid = kvp_value_get_guid (value);
+    return xaccAccountLookup (guid, imap->book);
+}
+
+/* Store an Account in the map */
+void
+gnc_imap_add_account (GncImportMatchMap *imap,
+		      const char *category,
+		      const char *key,
+		      Account *acc)
+{
+    kvp_value *value;
+
+    if (!imap || !key || !acc || (strlen (key) == 0)) return;
+    if (!category)
+    {
+        category = key;
+        key = NULL;
+    }
+    g_return_if_fail (acc != NULL);
+
+    value = kvp_value_new_guid (xaccAccountGetGUID (acc));
+    g_return_if_fail (value != NULL);
+    xaccAccountBeginEdit (imap->acc);
+    kvp_frame_set_slot_path (imap->frame, value, IMAP_FRAME, category, key, NULL);
+    qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
+    xaccAccountCommitEdit (imap->acc);
+    kvp_value_delete (value);
+
+    /* XXX Mark the account (or book) as dirty! */
+}
+
+
+
+
+/*--------------------------------------------------------------------------
+ Below here is the bayes transaction to account matching system
+--------------------------------------------------------------------------*/
+
+
+struct account_token_count
+{
+    char* account_name;
+    gint64 token_count; /**< occurances of a given token for this account_name */
+};
+
+/** total_count and the token_count for a given account let us calculate the
+ * probability of a given account with any single token
+ */
+struct token_accounts_info
+{
+    GList *accounts; /**< array of struct account_token_count */
+    gint64 total_count;
+};
+
+/** gpointer is a pointer to a struct token_accounts_info
+ * \note Can always assume that keys are unique, reduces code in this function
+ */
+static void
+buildTokenInfo(const char *key, kvp_value *value, gpointer data)
+{
+    struct token_accounts_info *tokenInfo = (struct token_accounts_info*)data;
+    struct account_token_count* this_account;
+
+    //  PINFO("buildTokenInfo: account '%s', token_count: '%ld'\n", (char*)key,
+    //			(long)kvp_value_get_gint64(value));
+
+    /* add the count to the total_count */
+    tokenInfo->total_count += kvp_value_get_gint64(value);
+
+    /* allocate a new structure for this account and it's token count */
+    this_account = (struct account_token_count*)
+                   g_new0(struct account_token_count, 1);
+
+    /* fill in the account name and number of tokens found for this account name */
+    this_account->account_name = (char*)key;
+    this_account->token_count = kvp_value_get_gint64(value);
+
+    /* append onto the glist a pointer to the new account_token_count structure */
+    tokenInfo->accounts = g_list_prepend(tokenInfo->accounts, this_account);
+}
+
+/** intermediate values used to calculate the bayes probability of a given account
+  where p(AB) = (a*b)/[a*b + (1-a)(1-b)], product is (a*b),
+  product_difference is (1-a) * (1-b)
+ */
+struct account_probability
+{
+    double product; /* product of probabilities */
+    double product_difference; /* product of (1-probabilities) */
+};
+
+/** convert a hash table of account names and (struct account_probability*)
+  into a hash table of 100000x the percentage match value, ie. 10% would be
+  0.10 * 100000 = 10000
+ */
+#define PROBABILITY_FACTOR 100000
+static void
+buildProbabilities(gpointer key, gpointer value, gpointer data)
+{
+    GHashTable *final_probabilities = (GHashTable*)data;
+    struct account_probability *account_p = (struct account_probability*)value;
+
+    /* P(AB) = A*B / [A*B + (1-A)*(1-B)]
+     * NOTE: so we only keep track of a running product(A*B*C...)
+     * and product difference ((1-A)(1-B)...)
+     */
+    gint32 probability =
+        (account_p->product /
+         (account_p->product + account_p->product_difference))
+        * PROBABILITY_FACTOR;
+
+    PINFO("P('%s') = '%d'\n", (char*)key, probability);
+
+    g_hash_table_insert(final_probabilities, key, GINT_TO_POINTER(probability));
+}
+
+/** Frees an array of the same time that buildProperties built */
+static void
+freeProbabilities(gpointer key, gpointer value, gpointer data)
+{
+    /* free up the struct account_probability that was allocated
+     * in gnc_account_find_account_bayes()
+     */
+    g_free(value);
+}
+
+/** holds an account name and its corresponding integer probability
+  the integer probability is some factor of 10
+ */
+struct account_info
+{
+    char* account_name;
+    gint32 probability;
+};
+
+/** Find the highest probability and the corresponding account name
+    store in data, a (struct account_info*)
+    NOTE: this is a g_hash_table_foreach() function for a hash table of entries
+    key is a  pointer to the account name, value is a gint32, 100000x
+    the probability for this account
+*/
+static void
+highestProbability(gpointer key, gpointer value, gpointer data)
+{
+    struct account_info *account_i = (struct account_info*)data;
+
+    /* if the current probability is greater than the stored, store the current */
+    if (GPOINTER_TO_INT(value) > account_i->probability)
+    {
+        /* Save the new highest probability and the assoaciated account name */
+        account_i->probability = GPOINTER_TO_INT(value);
+        account_i->account_name = key;
+    }
+}
+
+
+#define threshold (.90 * PROBABILITY_FACTOR) /* 90% */
+
+/** Look up an Account in the map */
+Account*
+gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens)
+{
+    struct token_accounts_info tokenInfo; /**< holds the accounts and total
+					   * token count for a single token */
+    GList *current_token;		  /**< pointer to the current
+					   * token from the input GList
+					   * tokens */
+    GList *current_account_token;	  /**< pointer to the struct
+					   * account_token_count */
+    struct account_token_count *account_c; /**< an account name and the number
+					    * of times a token has appeared
+					    * for the account */
+    struct account_probability *account_p; /**< intermediate storage of values
+					    * to compute the bayes probability
+					    * of an account */
+    GHashTable *running_probabilities = g_hash_table_new(g_str_hash,
+							 g_str_equal);
+    GHashTable *final_probabilities = g_hash_table_new(g_str_hash,
+						       g_str_equal);
+    struct account_info account_i;
+    kvp_value* value;
+    kvp_frame* token_frame;
+
+    ENTER(" ");
+
+    /* check to see if the imap is NULL */
+    if (!imap)
+    {
+        PINFO("imap is null, returning null");
+        LEAVE(" ");
+        return NULL;
+    }
+
+    /* find the probability for each account that contains any of the tokens
+     * in the input tokens list
+     */
+    for (current_token = tokens; current_token;
+	 current_token = current_token->next)
+    {
+        /* zero out the token_accounts_info structure */
+        memset(&tokenInfo, 0, sizeof(struct token_accounts_info));
+
+        PINFO("token: '%s'", (char*)current_token->data);
+
+        /* find the slot for the given token off of the source account
+         * for these tokens, search off of the IMAP_FRAME_BAYES path so
+         * we aren't looking from the parent of the entire kvp tree
+         */
+        value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
+                                        (char*)current_token->data, NULL);
+
+        /* if value is null we should skip over this token */
+        if (!value)
+            continue;
+
+        /* convert the slot(value) into a the frame that contains the
+         * list of accounts
+         */
+        token_frame = kvp_value_get_frame(value);
+
+        /* token_frame should NEVER be null */
+        if (!token_frame)
+        {
+            PERR("token '%s' has no accounts", (char*)current_token->data);
+            continue; /* skip over this token */
+        }
+
+        /* process the accounts for this token, adding the account if it
+         * doesn't already exist or adding to the existing accounts token
+         * count if it does
+         */
+        kvp_frame_for_each_slot(token_frame, buildTokenInfo, &tokenInfo);
+
+        /* for each account we have just found, see if the account
+         * already exists in the list of account probabilities, if not
+         * add it
+         */
+        for (current_account_token = tokenInfo.accounts; current_account_token;
+                current_account_token = current_account_token->next)
+        {
+            /* get the account name and corresponding token count */
+            account_c = (struct account_token_count*)current_account_token->data;
+
+            PINFO("account_c->account_name('%s'), "
+                  "account_c->token_count('%ld')/total_count('%ld')",
+                  account_c->account_name, (long)account_c->token_count,
+                  (long)tokenInfo.total_count);
+
+            account_p = g_hash_table_lookup(running_probabilities,
+                                            account_c->account_name);
+
+            /* if the account exists in the list then continue
+             * the running probablities
+             */
+            if (account_p)
+            {
+                account_p->product = (((double)account_c->token_count /
+				      (double)tokenInfo.total_count)
+				      * account_p->product);
+                account_p->product_difference =
+                    ((double)1 - ((double)account_c->token_count /
+                                  (double)tokenInfo.total_count))
+                    * account_p->product_difference;
+                PINFO("product == %f, product_difference == %f",
+                      account_p->product, account_p->product_difference);
+            }
+            else
+            {
+                /* add a new entry */
+                PINFO("adding a new entry for this account");
+                account_p = (struct account_probability*)
+                            g_new0(struct account_probability, 1);
+
+                /* set the product and product difference values */
+                account_p->product = ((double)account_c->token_count /
+                                      (double)tokenInfo.total_count);
+                account_p->product_difference =
+                    (double)1 - ((double)account_c->token_count /
+                                 (double)tokenInfo.total_count);
+
+                PINFO("product == %f, product_difference == %f",
+                      account_p->product, account_p->product_difference);
+
+                /* add the account name and (struct account_probability*)
+                 * to the hash table */
+                g_hash_table_insert(running_probabilities,
+                                    account_c->account_name, account_p);
+            }
+        } /* for all accounts in tokenInfo */
+
+        /* free the data in tokenInfo */
+        for (current_account_token = tokenInfo.accounts; current_account_token;
+                current_account_token = current_account_token->next)
+        {
+            /* free up each struct account_token_count we allocated */
+            g_free((struct account_token_count*)current_account_token->data);
+        }
+
+        g_list_free(tokenInfo.accounts); /* free the accounts GList */
+    }
+
+    /* build a hash table of account names and their final probabilities
+     * from each entry in the running_probabilties hash table
+     */
+    g_hash_table_foreach(running_probabilities, buildProbabilities,
+                         final_probabilities);
+
+    /* find the highest probabilty and the corresponding account */
+    memset(&account_i, 0, sizeof(struct account_info));
+    g_hash_table_foreach(final_probabilities, highestProbability, &account_i);
+
+    /* free each element of the running_probabilities hash */
+    g_hash_table_foreach(running_probabilities, freeProbabilities, NULL);
+
+    /* free the hash tables */
+    g_hash_table_destroy(running_probabilities);
+    g_hash_table_destroy(final_probabilities);
+
+    PINFO("highest P('%s') = '%d'",
+          account_i.account_name ? account_i.account_name : "(null)",
+          account_i.probability);
+
+    /* has this probability met our threshold? */
+    if (account_i.probability >= threshold)
+    {
+        PINFO("found match");
+        LEAVE(" ");
+        return gnc_account_lookup_by_full_name(gnc_book_get_root_account(imap->book),
+                                               account_i.account_name);
+    }
+
+    PINFO("no match");
+    LEAVE(" ");
+
+    return NULL; /* we didn't meet our threshold, return NULL for an account */
+}
+
+
+/** Updates the imap for a given account using a list of tokens */
+void
+gnc_imap_add_account_bayes(GncImportMatchMap *imap,
+			   GList *tokens,
+			   Account *acc)
+{
+    GList *current_token;
+    kvp_value *value;
+    gint64 token_count;
+    char* account_fullname;
+    kvp_value *new_value; /* the value that will be added back into
+			   * the kvp tree */
+
+    ENTER(" ");
+
+    /* if imap is null return */
+    if (!imap)
+    {
+        LEAVE(" ");
+        return;
+    }
+
+    g_return_if_fail (acc != NULL);
+    account_fullname = gnc_account_get_full_name(acc);
+    xaccAccountBeginEdit (imap->acc);
+
+    PINFO("account name: '%s'\n", account_fullname);
+
+    /* process each token in the list */
+    for (current_token = g_list_first(tokens); current_token;
+            current_token = current_token->next)
+    {
+        /* Jump to next iteration if the pointer is not valid or if the
+        	 string is empty. In HBCI import we almost always get an empty
+        	 string, which doesn't work in the kvp loopkup later. So we
+        	 skip this case here. */
+        if (!current_token->data || (*((char*)current_token->data) == '\0'))
+            continue;
+
+        /* start off with no tokens for this account */
+        token_count = 0;
+
+        PINFO("adding token '%s'\n", (char*)current_token->data);
+
+        /* is this token/account_name already in the kvp tree? */
+        value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
+                                        (char*)current_token->data,
+					account_fullname,
+                                        NULL);
+
+        /* if the token/account is already in the tree, read the current
+         * value from the tree and use this for the basis of the value we
+         * are putting back
+         */
+        if (value)
+        {
+            PINFO("found existing value of '%ld'\n",
+                  (long)kvp_value_get_gint64(value));
+
+            /* convert this value back into an integer */
+            token_count += kvp_value_get_gint64(value);
+        }
+
+        /* increment the token count */
+        token_count++;
+
+        /* create a new value */
+        new_value = kvp_value_new_gint64(token_count);
+
+        /* insert the value into the kvp tree at
+         * /imap->frame/IMAP_FRAME/token_string/account_name_string
+         */
+        kvp_frame_set_slot_path(imap->frame, new_value,
+				IMAP_FRAME_BAYES,
+                                (char*)current_token->data,
+				account_fullname,
+				NULL);
+        /* kvp_frame_set_slot_path() copied the value so we
+         * need to delete this one ;-) */
+        kvp_value_delete(new_value);
+    }
+
+    /* free up the account fullname string */
+    qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
+    xaccAccountCommitEdit (imap->acc);
+    g_free(account_fullname);
+
+    LEAVE(" ");
+}
+
+/* ================================================================ */
 /* QofObject function implementation and registration */
 
 static void
diff --git a/src/engine/Account.h b/src/engine/Account.h
index 3098043..0e57ac7 100644
--- a/src/engine/Account.h
+++ b/src/engine/Account.h
@@ -417,6 +417,17 @@ void xaccAccountSortSplits (Account *acc, gboolean force);
  */
 gchar * gnc_account_get_full_name (const Account *account);
 
+/** Retrieve the gains account used by this account for the indicated
+ * currency, creating and recording a new one if necessary.
+ *
+ * FIXME: There is at present no interface to designate an existing
+ * account, and the new account name is hard coded to
+ * "Orphaned Gains -- CUR"
+ *
+ * FIXME: There is no provision for creating separate accounts for
+ * anything other than currency, e.g. holding period of a security.
+ */
+Account * xaccAccountGainsAccount (Account *acc, gnc_commodity *curr);
 /** Set a string that identifies the Finance::Quote backend that
  *  should be used to retrieve online prices.  See price-quotes.scm
  *  for more information
@@ -860,8 +871,6 @@ gboolean xaccAccountGetReconcileChildrenStatus(const Account *account);
  */
 gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor);
 
-#define xaccAccountGetSlots(X) qof_instance_get_slots(QOF_INSTANCE(X))
-
 /** @} */
 
 /** @name Lookup Accounts and Subaccounts by name or code
diff --git a/src/engine/SX-book.c b/src/engine/SX-book.c
index 57ee618..7440442 100644
--- a/src/engine/SX-book.c
+++ b/src/engine/SX-book.c
@@ -150,6 +150,9 @@ sxtg_is_dirty(const QofCollection *col)
     return dirty;
 }
 
+/* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
+extern void qof_instance_mark_clean (QofInstance *);
+
 static void
 sxtg_mark_clean(QofCollection *col)
 {
@@ -372,9 +375,9 @@ gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct)
         for (; splits != NULL; splits = splits->next)
         {
             Split *s = (Split*)splits->data;
-            KvpFrame *frame = kvp_frame_get_frame(xaccSplitGetSlots(s), GNC_SX_ID);
-            GncGUID *sx_split_acct_guid = kvp_frame_get_guid(frame, GNC_SX_ACCOUNT);
-            if (guid_equal(acct_guid, sx_split_acct_guid))
+            GncGUID *guid = NULL;
+            qof_instance_get (QOF_INSTANCE (s), "sx-account", &guid, NULL);
+            if (guid_equal(acct_guid, guid))
             {
                 rtn = g_list_append(rtn, sx);
             }
diff --git a/src/engine/SchedXaction.c b/src/engine/SchedXaction.c
index ceb30b0..c794bac 100644
--- a/src/engine/SchedXaction.c
+++ b/src/engine/SchedXaction.c
@@ -36,6 +36,7 @@
 #include "Transaction.h"
 #include "gnc-engine.h"
 #include "engine-helpers.h"
+#include "qofinstance-p.h"
 
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "gnc.engine.sx"
@@ -43,19 +44,19 @@
 enum
 {
     PROP_0,
-    PROP_NAME,
-    PROP_ENABLED,
-    PROP_NUM_OCCURANCE,
-    PROP_REM_OCCURANCE,
-    PROP_AUTO_CREATE,
-    PROP_AUTO_CREATE_NOTIFY,
-    PROP_ADVANCE_CREATION_DAYS,
-    PROP_ADVANCE_REMINDER_DAYS,
-    PROP_START_DATE,
-    PROP_END_DATE,
-    PROP_LAST_OCCURANCE_DATE,
-    PROP_INSTANCE_COUNT,
-    PROP_TEMPLATE_ACCOUNT
+    PROP_NAME,				/* Table */
+    PROP_ENABLED,			/* Table */
+    PROP_START_DATE,			/* Table */
+    PROP_END_DATE,			/* Table */
+    PROP_LAST_OCCURANCE_DATE,		/* Table */
+    PROP_NUM_OCCURANCE,			/* Table */
+    PROP_REM_OCCURANCE,			/* Table */
+    PROP_AUTO_CREATE,			/* Table */
+    PROP_AUTO_CREATE_NOTIFY,		/* Table */
+    PROP_ADVANCE_CREATION_DAYS,		/* Table */
+    PROP_ADVANCE_REMINDER_DAYS,		/* Table */
+    PROP_INSTANCE_COUNT,		/* Table */
+    PROP_TEMPLATE_ACCOUNT		/* Table */
 };
 
 /* GObject initialization */
@@ -173,6 +174,8 @@ gnc_schedxaction_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_SCHEDXACTION(object));
 
     sx = GNC_SCHEDXACTION(object);
+    g_assert (qof_instance_get_editlevel(sx));
+
     switch (prop_id)
     {
     case PROP_NAME:
@@ -1042,8 +1045,8 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
                  Transaction *parent_trans, QofBook *book)
 {
     Split *split;
-    KvpFrame *split_frame;
-    KvpValue *tmp_value;
+    const gchar *credit_formula;
+    const gchar *debit_formula;
     const GncGUID *acc_guid;
 
     split = xaccMallocSplit(book);
@@ -1059,40 +1062,14 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
     xaccAccountInsertSplit(parent_acct,
                            split);
 
-    split_frame = xaccSplitGetSlots(split);
-
-    tmp_value
-    = kvp_value_new_string(gnc_ttsplitinfo_get_credit_formula(s_info));
-
-    kvp_frame_set_slot_path(split_frame,
-                            tmp_value,
-                            GNC_SX_ID,
-                            GNC_SX_CREDIT_FORMULA,
-                            NULL);
-    kvp_value_delete(tmp_value);
-
-    tmp_value
-    = kvp_value_new_string(gnc_ttsplitinfo_get_debit_formula(s_info));
-
-    kvp_frame_set_slot_path(split_frame,
-                            tmp_value,
-                            GNC_SX_ID,
-                            GNC_SX_DEBIT_FORMULA,
-                            NULL);
-
-    kvp_value_delete(tmp_value);
-
+    credit_formula = gnc_ttsplitinfo_get_credit_formula(s_info);
+    debit_formula = gnc_ttsplitinfo_get_debit_formula(s_info);
     acc_guid = qof_entity_get_guid(QOF_INSTANCE(gnc_ttsplitinfo_get_account(s_info)));
-
-    tmp_value = kvp_value_new_guid(acc_guid);
-
-    kvp_frame_set_slot_path(split_frame,
-                            tmp_value,
-                            GNC_SX_ID,
-                            GNC_SX_ACCOUNT,
-                            NULL);
-
-    kvp_value_delete(tmp_value);
+    qof_instance_set (QOF_INSTANCE (split),
+		      "sx-credit-formula", credit_formula,
+		      "sx-debit-formula", debit_formula,
+		      "sx-account", acc_guid,
+		      NULL);
 
     return split;
 }
diff --git a/src/engine/SchedXaction.h b/src/engine/SchedXaction.h
index 08031e1..c02183e 100644
--- a/src/engine/SchedXaction.h
+++ b/src/engine/SchedXaction.h
@@ -304,15 +304,7 @@ void gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData );
 GList *gnc_sx_get_defer_instances( SchedXaction *sx );
 
 /* #defines for KvpFrame strings and QOF */
-#define GNC_SX_ID                    "sched-xaction"
-#define GNC_SX_ACCOUNT               "account"
-#define GNC_SX_CREDIT_FORMULA        "credit-formula"
-#define GNC_SX_DEBIT_FORMULA         "debit-formula"
-#define GNC_SX_CREDIT_NUMERIC        "credit-numeric"
-#define GNC_SX_DEBIT_NUMERIC         "debit-numeric"
 #define GNC_SX_SHARES                "shares"
-#define GNC_SX_AMOUNT                "amnt"
-#define GNC_SX_FROM_SCHED_XACTION    "from-sched-xaction"
 #define GNC_SX_FREQ_SPEC             "scheduled-frequency"
 #define GNC_SX_NAME                  "sched-xname"
 #define GNC_SX_START_DATE            "sched-start-date"
diff --git a/src/engine/Scrub.c b/src/engine/Scrub.c
index 055e95a..70d1e6c 100644
--- a/src/engine/Scrub.c
+++ b/src/engine/Scrub.c
@@ -1133,6 +1133,9 @@ xaccAccountScrubCommodity (Account *account)
 
 /* ================================================================ */
 
+/* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
+extern void qof_instance_set_dirty (QofInstance*);
+
 static void
 xaccAccountDeleteOldData (Account *account)
 {
diff --git a/src/engine/Scrub2.c b/src/engine/Scrub2.c
index 8c041f5..d938cae 100644
--- a/src/engine/Scrub2.c
+++ b/src/engine/Scrub2.c
@@ -157,7 +157,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
 
     if (!lot) return;
 
-    ENTER ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
+    ENTER ("lot=%s", gnc_lot_get_title(lot));
 
     for (snode = gnc_lot_get_split_list(lot); snode; snode = snode->next)
     {
@@ -216,7 +216,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
         }
     }
 
-    LEAVE ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
+    LEAVE ("lot=%s", gnc_lot_get_title(lot));
 }
 
 /* ================================================================= */
diff --git a/src/engine/Split.c b/src/engine/Split.c
index b49389f..53fa590 100644
--- a/src/engine/Split.c
+++ b/src/engine/Split.c
@@ -51,6 +51,7 @@
 #include "gnc-engine.h"
 #include "gnc-lot.h"
 #include "gnc-event.h"
+#include "qofinstance-p.h"
 
 const char *void_former_amt_str = "void-former-amount";
 const char *void_former_val_str = "void-former-value";
@@ -60,17 +61,40 @@ const char *void_former_val_str = "void-former-value";
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = GNC_MOD_ENGINE;
 
+/* KVP key values used for SX info stored Split's slots. */
+#define GNC_SX_ID                    "sched-xaction"
+#define GNC_SX_ACCOUNT               "account"
+#define GNC_SX_CREDIT_FORMULA        "credit-formula"
+#define GNC_SX_DEBIT_FORMULA         "debit-formula"
+#define GNC_SX_CREDIT_NUMERIC        "credit-numeric"
+#define GNC_SX_DEBIT_NUMERIC         "debit-numeric"
+#define GNC_SX_SHARES                "shares"
+
 enum
 {
     PROP_0,
-    PROP_ACTION,
-    PROP_MEMO,
-    PROP_VALUE,
-    PROP_AMOUNT,
-    PROP_RECONCILE_DATE,
-    PROP_TX,
-    PROP_ACCOUNT,
-    PROP_LOT
+    PROP_TX,                    /* Table */
+    PROP_ACCOUNT,               /* Table */
+    PROP_MEMO,                  /* Table */
+    PROP_ACTION,                /* Table */
+//    PROP_RECONCILE_STATE,     /* Table */
+    PROP_RECONCILE_DATE,        /* Table */
+    PROP_VALUE,                 /* Table, in 2 fields */
+    PROP_SX_ACCOUNT,            /* KVP */
+    PROP_SX_CREDIT_FORMULA,     /* KVP */
+    PROP_SX_CREDIT_NUMERIC,     /* KVP */
+    PROP_SX_DEBIT_FORMULA,      /* KVP */
+    PROP_SX_DEBIT_NUMERIC,      /* KVP */
+    PROP_SX_SHARES,             /* KVP */
+    PROP_LOT,                   /* KVP */
+    PROP_ONLINE_ACCOUNT,        /* KVP */
+    PROP_LOT_SPLIT,             /* KVP */
+    PROP_PEER_GUID,             /* KVP */
+    PROP_GAINS_SPLIT,           /* KVP */
+    PROP_GAINS_SOURCE,          /* KVP */
+    PROP_RUNTIME_0,
+    PROP_AMOUNT,                /* Runtime */
+
 };
 
 /* GObject Initialization */
@@ -126,6 +150,7 @@ gnc_split_get_property(GObject         *object,
                        GParamSpec      *pspec)
 {
     Split *split;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_SPLIT(object));
 
@@ -156,6 +181,50 @@ gnc_split_get_property(GObject         *object,
     case PROP_LOT:
         g_value_take_object(value, split->lot);
         break;
+    case PROP_SX_CREDIT_FORMULA:
+        key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA;
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_CREDIT_NUMERIC:
+        key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC;
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_DEBIT_FORMULA:
+        key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA;
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_DEBIT_NUMERIC:
+        key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC;
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_ACCOUNT:
+        key = GNC_SX_ID "/" GNC_SX_ACCOUNT;
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_SHARES:
+        key = GNC_SX_ID "/" GNC_SX_SHARES;
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_ONLINE_ACCOUNT:
+        key = "online_id";
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_LOT_SPLIT:
+        key = "lot-split";
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_PEER_GUID:
+        key = "peer_guid";
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_GAINS_SPLIT:
+        key = "gains-split";
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_GAINS_SOURCE:
+        key = "gains-source";
+        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -170,10 +239,14 @@ gnc_split_set_property(GObject         *object,
 {
     Split *split;
     gnc_numeric* number;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_SPLIT(object));
 
     split = GNC_SPLIT(object);
+    if (prop_id < PROP_RUNTIME_0 && split->parent != NULL)
+        g_assert (qof_instance_get_editlevel(split->parent));
+
     switch (prop_id)
     {
     case PROP_ACTION:
@@ -202,6 +275,50 @@ gnc_split_set_property(GObject         *object,
     case PROP_LOT:
         xaccSplitSetLot(split, g_value_get_object(value));
         break;
+    case PROP_SX_CREDIT_FORMULA:
+        key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA;
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_CREDIT_NUMERIC:
+        key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC;
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_DEBIT_FORMULA:
+        key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA;
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_DEBIT_NUMERIC:
+        key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC;
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_ACCOUNT:
+        key = GNC_SX_ID "/" GNC_SX_ACCOUNT;
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_SX_SHARES:
+        key = GNC_SX_ID "/" GNC_SX_SHARES;
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_ONLINE_ACCOUNT:
+        key = "online_id";
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_LOT_SPLIT:
+        key = "lot-split";
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_PEER_GUID:
+        key = "peer_guid";
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_GAINS_SPLIT:
+        key = "gains-split";
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
+    case PROP_GAINS_SOURCE:
+        key = "gains-source";
+        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -299,6 +416,122 @@ gnc_split_class_init(SplitClass* klass)
                           "The lot that this split belongs to.",
                           GNC_TYPE_LOT,
                           G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_SX_DEBIT_FORMULA,
+     g_param_spec_string("sx-debit-formula",
+                         "Schedule Transaction Debit Formula",
+                         "The formula used to calculate the actual debit "
+                         "amount when a real split is generated from this "
+                         "SX split.",
+                         NULL,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_SX_DEBIT_NUMERIC,
+     g_param_spec_boxed("sx-debit-numeric",
+                        "Scheduled Transaction Debit Numeric",
+                        "Numeric value to plug into the Debit Formula when a "
+                        "real split is generated from this SX split.",
+                        GNC_TYPE_NUMERIC,
+                        G_PARAM_READWRITE));
+
+     g_object_class_install_property
+    (gobject_class,
+     PROP_SX_CREDIT_FORMULA,
+     g_param_spec_string("sx-credit-formula",
+                         "Schedule Transaction Credit Formula",
+                         "The formula used to calculate the actual credit "
+                         "amount when a real split is generated from this "
+                         "SX split.",
+                         NULL,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_SX_CREDIT_NUMERIC,
+     g_param_spec_boxed("sx-credit-numeric",
+                        "Scheduled Transaction Credit Numeric",
+                        "Numeric value to plug into the Credit Formula when a "
+                        "real split is generated from this SX split.",
+                        GNC_TYPE_NUMERIC,
+                        G_PARAM_READWRITE));
+/* FIXME: PROP_SX_SHARES should be stored as a gnc_numeric, but the function
+ * which uses it, gnc_template_register_save_shares_cell, stores a
+ * phony string. This is maintained until backwards compatibility can
+ * be established.
+ */
+    g_object_class_install_property
+    (gobject_class,
+     PROP_SX_SHARES,
+     g_param_spec_string("sx-shares",
+                        "Scheduled Transaction Shares",
+                        "Numeric value of shares to insert in a new split when "
+                        "it's generated from this SX split.",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+     g_object_class_install_property
+    (gobject_class,
+     PROP_SX_ACCOUNT,
+     g_param_spec_boxed("sx-account",
+                        "Scheduled Transaction Account",
+                        "The target account for a scheduled transaction split.",
+                        GNC_TYPE_GUID,
+                        G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_ONLINE_ACCOUNT,
+     g_param_spec_string ("online-id",
+                          "Online Account ID",
+                          "The online account which corresponds to this "
+                          "account for OFX/HCBI import",
+                          NULL,
+                          G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_LOT_SPLIT,
+     g_param_spec_int64 ("lot-split",
+                         "Lot Split",
+                         "Indicates that the split was divided into two "
+                         "splits in order to balance a lot capital gains "
+                         "transaction. Contains a timestamp of the action.",
+                         G_MININT64, G_MAXINT64, 0,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_PEER_GUID,
+     g_param_spec_boxed ("peer-guid",
+                          "Peer GUID",
+                          "The other split in the division.",
+                          GNC_TYPE_GUID,
+                          G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_GAINS_SPLIT,
+     g_param_spec_boxed ("gains-split",
+                          "Gains Split",
+                          "The capital gains split associated with this "
+                          "split when this split represents the proceeds "
+                          "from the sale of a commodity inside a Lot.",
+                          GNC_TYPE_GUID,
+                          G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_GAINS_SOURCE,
+     g_param_spec_boxed ("gains-source",
+                          "Gains Source",
+                          "The source split for which this split this is "
+                          "the gains split. ",
+                          GNC_TYPE_GUID,
+                          G_PARAM_READWRITE));
 }
 
 /********************************************************************\
@@ -406,7 +639,7 @@ xaccDupeSplit (const Split *s)
 }
 
 Split *
-xaccSplitClone (const Split *s)
+xaccSplitCloneNoKvp (const Split *s)
 {
     Split *split = g_object_new (GNC_TYPE_SPLIT, NULL);
 
@@ -424,10 +657,8 @@ xaccSplitClone (const Split *s)
     split->gains = GAINS_STATUS_UNKNOWN;
     split->gains_split = NULL;
 
-    qof_instance_init_data(&split->inst, GNC_ID_SPLIT, qof_instance_get_book(s));
-    kvp_frame_delete(split->inst.kvp_data);
-    split->inst.kvp_data = kvp_frame_copy(s->inst.kvp_data);
-
+    qof_instance_init_data(&split->inst, GNC_ID_SPLIT,
+                           qof_instance_get_book(s));
     xaccAccountInsertSplit(s->acc, split);
     if (s->lot)
     {
@@ -437,6 +668,11 @@ xaccSplitClone (const Split *s)
     return split;
 }
 
+void
+xaccSplitCopyKvp (const Split *from, Split *to)
+{
+    to->inst.kvp_data = kvp_frame_copy(from->inst.kvp_data);
+}
 
 /*################## Added for Reg2 #################*/
 
@@ -954,26 +1190,6 @@ get_commodity_denom(const Split * s)
     }
 }
 
-/********************************************************************
- * xaccSplitGetSlots
- ********************************************************************/
-
-KvpFrame *
-xaccSplitGetSlots (const Split * s)
-{
-    return qof_instance_get_slots(QOF_INSTANCE(s));
-}
-/* Used for testing only: _get_random_split in test-engine-stuff.c */
-void
-xaccSplitSetSlots_nc(Split *s, KvpFrame *frm)
-{
-    if (!s || !frm) return;
-    xaccTransBeginEdit(s->parent);
-    qof_instance_set_slots(QOF_INSTANCE(s), frm);
-    xaccTransCommitEdit(s->parent);
-
-}
-
 /********************************************************************\
 \********************************************************************/
 
@@ -2115,7 +2331,7 @@ gboolean xaccSplitRegister (void)
         { SPLIT_ACCT_FULLNAME, SPLIT_ACCT_FULLNAME, no_op, NULL },
         { SPLIT_CORR_ACCT_NAME, SPLIT_CORR_ACCT_NAME, no_op, NULL },
         { SPLIT_CORR_ACCT_CODE, SPLIT_CORR_ACCT_CODE, no_op, NULL },
-        { SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)xaccSplitGetSlots, NULL },
+        { SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL },
         { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)xaccSplitGetBook, NULL },
         {
             QOF_PARAM_GUID, QOF_TYPE_GUID,
diff --git a/src/engine/Split.h b/src/engine/Split.h
index d240bd8..cc512d1 100644
--- a/src/engine/Split.h
+++ b/src/engine/Split.h
@@ -144,20 +144,6 @@ GNCLot *      xaccSplitGetLot (const Split *split);
 /** Assigns the split to a specific Lot */
 void xaccSplitSetLot(Split* split, GNCLot* lot);
 
-
-/** Returns the KvpFrame slots of this split for direct editing.
- *
- * Split slots are used to store arbitrary strings, numbers, and
- * structures which aren't members of the transaction struct.  See
- * kvp_doc.txt for reserved slot names.
- */
-KvpFrame *xaccSplitGetSlots(const Split *split);
-
-/** Set the KvpFrame slots of this split to the given frm by directly
- * using the frm pointer (i.e. non-copying). */
-void xaccSplitSetSlots_nc(Split *s, KvpFrame *frm);
-
-
 /** The memo is an arbitrary string associated with a split.  It is
  * intended to hold a short (zero to forty character) string that is
  * displayed by the GUI along with this split.  Users typically type
diff --git a/src/engine/SplitP.h b/src/engine/SplitP.h
index 93f0ed5..2832dc8 100644
--- a/src/engine/SplitP.h
+++ b/src/engine/SplitP.h
@@ -146,7 +146,8 @@ struct _SplitClass
  */
 void  xaccFreeSplit (Split *split);    /* frees memory */
 
-Split * xaccSplitClone (const Split *s);
+Split *xaccSplitCloneNoKvp (const Split *s);
+void xaccSplitCopyKvp (const Split *from, Split *to);
 
 Split *xaccDupeSplit (const Split *s);
 void mark_split (Split *s);
diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c
index 2df9f84..5146826 100644
--- a/src/engine/Transaction.c
+++ b/src/engine/Transaction.c
@@ -184,6 +184,7 @@ const char *assoc_uri_str = "assoc_uri";
 #define TRANS_TXN_TYPE_KVP       "trans-txn-type"
 #define TRANS_READ_ONLY_REASON   "trans-read-only"
 #define TRANS_REVERSED_BY        "reversed-by"
+#define GNC_SX_FROM              "from-sched-xaction"
 
 #define ISO_DATELENGTH 32 /* length of an iso 8601 date string. */
 
@@ -193,11 +194,14 @@ static QofLogModule log_module = GNC_MOD_ENGINE;
 enum
 {
     PROP_0,
-    PROP_NUM,
-    PROP_DESCRIPTION,
-    PROP_CURRENCY,
-    PROP_POST_DATE,
-    PROP_ENTER_DATE
+    PROP_CURRENCY,	/* Table */
+    PROP_NUM,		/* Table */
+    PROP_POST_DATE,	/* Table */
+    PROP_ENTER_DATE,	/* Table */
+    PROP_DESCRIPTION,	/* Table */
+    PROP_INVOICE,	/* KVP */
+    PROP_SX_TXN,	/* KVP */
+    PROP_ONLINE_ACCOUNT,/* KVP */
 };
 
 void
@@ -303,6 +307,9 @@ gnc_transaction_get_property(GObject* object,
                              GParamSpec* pspec)
 {
     Transaction* tx;
+    KvpFrame *frame;
+    gchar *key;
+    GValue *temp;
 
     g_return_if_fail(GNC_IS_TRANSACTION(object));
 
@@ -324,6 +331,18 @@ gnc_transaction_get_property(GObject* object,
     case PROP_ENTER_DATE:
         g_value_set_boxed(value, &tx->date_entered);
         break;
+    case PROP_INVOICE:
+	key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
+	qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
+	break;
+    case PROP_SX_TXN:
+	key = GNC_SX_FROM;
+	qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
+	break;
+    case PROP_ONLINE_ACCOUNT:
+	key = "online_id";
+	qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -337,10 +356,14 @@ gnc_transaction_set_property(GObject* object,
                              GParamSpec* pspec)
 {
     Transaction* tx;
+    KvpFrame *frame;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_TRANSACTION(object));
 
     tx = GNC_TRANSACTION(object);
+    g_assert (qof_instance_get_editlevel(tx));
+
     switch (prop_id)
     {
     case PROP_NUM:
@@ -358,6 +381,18 @@ gnc_transaction_set_property(GObject* object,
     case PROP_ENTER_DATE:
         xaccTransSetDateEnteredTS(tx, g_value_get_boxed(value));
         break;
+    case PROP_INVOICE:
+	key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
+	qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
+	break;
+    case PROP_SX_TXN:
+	key = GNC_SX_FROM;
+	qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
+	break;
+    case PROP_ONLINE_ACCOUNT:
+	key = "online_id";
+	qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -426,6 +461,36 @@ gnc_transaction_class_init(TransactionClass* klass)
                         "The date the transaction was entered.",
                         GNC_TYPE_TIMESPEC,
                         G_PARAM_READWRITE));
+
+     g_object_class_install_property(
+       gobject_class,
+        PROP_INVOICE,
+        g_param_spec_boxed("invoice",
+			   "Invoice attached to lot",
+			   "Used by GncInvoice",
+			   GNC_TYPE_GUID,
+			   G_PARAM_READWRITE));
+
+     g_object_class_install_property(
+       gobject_class,
+        PROP_SX_TXN,
+        g_param_spec_boxed("from-sched-xaction",
+			   "From Scheduled Transaction",
+			   "Used by Scheduled Transastions to record the "
+			   "originating template transaction for created "
+			   "transactions",
+			   GNC_TYPE_GUID,
+			   G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_ONLINE_ACCOUNT,
+     g_param_spec_string ("online-id",
+                          "Online Account ID",
+                          "The online account which corresponds to this "
+			  "account for OFX/HCBI import",
+                          NULL,
+                          G_PARAM_READWRITE));
 }
 
 /********************************************************************\
@@ -532,9 +597,8 @@ xaccTransSortSplits (Transaction *trans)
  * This routine is prone to programmer snafu if not used correctly.
  * It is used only by the edit-rollback code.
  */
-/* Actually, it *is* public, and used by Period.c */
-Transaction *
-xaccDupeTransaction (const Transaction *from)
+static Transaction *
+dupe_trans (const Transaction *from)
 {
     Transaction *to;
     GList *node;
@@ -571,10 +635,11 @@ xaccDupeTransaction (const Transaction *from)
 
 /********************************************************************\
  * Use this routine to externally duplicate a transaction.  It creates
- * a full fledged transaction with unique guid, splits, etc.
+ * a full fledged transaction with unique guid, splits, etc. and
+ * writes it to the database.
 \********************************************************************/
 Transaction *
-xaccTransClone (const Transaction *from)
+xaccTransCloneNoKvp (const Transaction *from)
 {
     Transaction *to;
     Split *split;
@@ -593,14 +658,13 @@ xaccTransClone (const Transaction *from)
 
     to->orig            = NULL;
 
-    qof_instance_init_data (&to->inst, GNC_ID_TRANS, qof_instance_get_book(from));
-    kvp_frame_delete (to->inst.kvp_data);
-    to->inst.kvp_data    = kvp_frame_copy (from->inst.kvp_data);
+    qof_instance_init_data (&to->inst, GNC_ID_TRANS,
+			    qof_instance_get_book(from));
 
     xaccTransBeginEdit(to);
     for (node = from->splits; node; node = node->next)
     {
-        split = xaccSplitClone(node->data);
+        split = xaccSplitCloneNoKvp(node->data);
         split->parent = to;
         to->splits = g_list_append (to->splits, split);
     }
@@ -611,11 +675,28 @@ xaccTransClone (const Transaction *from)
     return to;
 }
 
+Transaction *
+xaccTransClone (const Transaction *from)
+{
+    Transaction *to = xaccTransCloneNoKvp (from);
+    int i = 0;
+    int length = g_list_length (from->splits);
+
+    xaccTransBeginEdit (to);
+    to->inst.kvp_data = kvp_frame_copy (from->inst.kvp_data);
+    g_assert (g_list_length (to->splits) == length);
+    for (i = 0; i < length; ++i)
+	xaccSplitCopyKvp (g_list_nth_data (from->splits, i),
+			    g_list_nth_data (to->splits, i));
+    xaccTransCommitEdit (to);
+    return to;
+}
+
 /*################## Added for Reg2 #################*/
 
 /********************************************************************\
  * Copy a transaction to the 'clipboard' transaction using
- *  xaccDupeTransaction. The 'clipboard' transaction must never
+ *  dupe_trans. The 'clipboard' transaction must never
  *  be dereferenced.
 \********************************************************************/
 Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
@@ -625,7 +706,7 @@ Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
     if (!from_trans)
         return NULL;
 
-    to_trans = xaccDupeTransaction(from_trans);
+    to_trans = dupe_trans(from_trans);
     return to_trans;
 }
 
@@ -642,7 +723,7 @@ xaccTransCopyOnto(const Transaction *from_trans, Transaction *to_trans)
 /********************************************************************\
  * This function explicitly must robustly handle some unusual input.
  *
- *  'from_trans' may be a duped trans (see xaccDupeTransaction), so its
+ *  'from_trans' may be a duped trans (see dupe_trans), so its
  *   splits may not really belong to the accounts that they say they do.
  *
  *  'from_acc' need not be a valid account. It may be an already freed
@@ -1309,7 +1390,7 @@ xaccTransBeginEdit (Transaction *trans)
 
     /* Make a clone of the transaction; we will use this
      * in case we need to roll-back the edit. */
-    trans->orig = xaccDupeTransaction (trans);
+    trans->orig = dupe_trans (trans);
 }
 
 /********************************************************************\
@@ -2615,6 +2696,7 @@ xaccTransFindSplitByAccount(const Transaction *trans, const Account *acc)
     return NULL;
 }
 
+
 /********************************************************************\
 \********************************************************************/
 /* QofObject function implementation */
@@ -2776,6 +2858,7 @@ _utest_trans_fill_functions (void)
     func->trans_on_error = trans_on_error;
     func->trans_cleanup_commit = trans_cleanup_commit;
     func->xaccTransScrubGainsDate = xaccTransScrubGainsDate;
+    func->dupe_trans = dupe_trans;
     return func;
 }
 
diff --git a/src/engine/Transaction.h b/src/engine/Transaction.h
index 8091dba..e26ac08 100644
--- a/src/engine/Transaction.h
+++ b/src/engine/Transaction.h
@@ -156,6 +156,12 @@ void          xaccTransDestroy (Transaction *trans);
  */
 Transaction * xaccTransClone (const Transaction *t);
 
+/**
+ The xaccTransCloneNoKvp() method will create a complete copy of an
+ existing transaction except that the KVP slots will be empty.
+ */
+Transaction * xaccTransCloneNoKvp (const Transaction *t);
+
 /** Equality.
  *
  * @param ta First transaction to compare
@@ -223,7 +229,7 @@ Transaction * xaccTransLookup (const GncGUID *guid, QofBook *book);
 /*################## Added for Reg2 #################*/
 
 /** Copy a transaction to the 'clipboard' transaction using
- *  xaccDupeTransaction. The 'clipboard' transaction must never
+ *  dupe_transaction. The 'clipboard' transaction must never
  *  be dereferenced.
  */
 Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans);
@@ -749,8 +755,6 @@ void xaccTransDump (const Transaction *trans, const char *tag);
 #define xaccTransGetGUID(X)      qof_entity_get_guid(QOF_INSTANCE(X))
 /** \deprecated */
 #define xaccTransReturnGUID(X) (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
-/** \deprecated */
-#define xaccTransGetSlots(X)     qof_instance_get_slots (QOF_INSTANCE(X))
 
 #endif /* XACC_TRANSACTION_H */
 /** @} */
diff --git a/src/engine/TransactionP.h b/src/engine/TransactionP.h
index d7935e8..87b89bf 100644
--- a/src/engine/TransactionP.h
+++ b/src/engine/TransactionP.h
@@ -186,6 +186,7 @@ typedef struct
     void (*trans_on_error)(Transaction*, QofBackendError);
     void (*trans_cleanup_commit)(Transaction*);
     void (*xaccTransScrubGainsDate)(Transaction*);
+    Transaction *(*dupe_trans)(const Transaction*);
 
 } TransTestFunctions;
 
diff --git a/src/engine/cap-gains.c b/src/engine/cap-gains.c
index e73bdfc..b7ea3f1 100644
--- a/src/engine/cap-gains.c
+++ b/src/engine/cap-gains.c
@@ -216,150 +216,6 @@ xaccAccountFindLatestOpenLot (Account *acc, gnc_numeric sign,
 }
 
 /* ============================================================== */
-/* Similar to GetOrMakeAccount, but different in important ways */
-
-static Account *
-GetOrMakeLotOrphanAccount (Account *root, gnc_commodity * currency)
-{
-    char * accname;
-    Account * acc;
-
-    g_return_val_if_fail (root, NULL);
-
-    /* build the account name */
-    if (!currency)
-    {
-        PERR ("No currency specified!");
-        return NULL;
-    }
-
-    accname = g_strconcat (_("Orphaned Gains"), "-",
-                           gnc_commodity_get_mnemonic (currency), NULL);
-
-    /* See if we've got one of these going already ... */
-    acc = gnc_account_lookup_by_name(root, accname);
-
-    if (acc == NULL)
-    {
-        /* Guess not. We'll have to build one. */
-        acc = xaccMallocAccount (gnc_account_get_book(root));
-        xaccAccountBeginEdit (acc);
-        xaccAccountSetName (acc, accname);
-        xaccAccountSetCommodity (acc, currency);
-        xaccAccountSetType (acc, ACCT_TYPE_INCOME);
-        xaccAccountSetDescription (acc, _("Realized Gain/Loss"));
-        xaccAccountSetNotes (acc,
-                             _("Realized Gains or Losses from "
-                               "Commodity or Trading Accounts "
-                               "that haven't been recorded elsewhere."));
-
-        /* Hang the account off the root. */
-        gnc_account_append_child (root, acc);
-        xaccAccountCommitEdit (acc);
-    }
-
-    g_free (accname);
-
-    return acc;
-}
-
-/* ============================================================== */
-
-void
-xaccAccountSetDefaultGainAccount (Account *acc, const Account *gain_acct)
-{
-    KvpFrame *cwd;
-    KvpValue *vvv;
-    const char * cur_name;
-    gnc_commodity *acc_comm;
-
-    if (!acc || !gain_acct) return;
-
-    cwd = xaccAccountGetSlots (acc);
-    cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
-
-    /* Accounts are indexed by thier unique currency name */
-    acc_comm = xaccAccountGetCommodity(acc);
-    cur_name = gnc_commodity_get_unique_name (acc_comm);
-
-    xaccAccountBeginEdit (acc);
-    vvv = kvp_value_new_guid (xaccAccountGetGUID (gain_acct));
-    kvp_frame_set_slot_nc (cwd, cur_name, vvv);
-    qof_instance_set_slots(QOF_INSTANCE(acc), acc->inst.kvp_data);
-    xaccAccountCommitEdit (acc);
-}
-
-/* ============================================================== */
-
-Account *
-xaccAccountGetDefaultGainAccount (const Account *acc, const gnc_commodity * currency)
-{
-    Account *gain_acct = NULL;
-    KvpFrame *cwd;
-    KvpValue *vvv;
-    GncGUID * gain_acct_guid;
-    const char * cur_name;
-
-    if (!acc || !currency) return NULL;
-
-    cwd = xaccAccountGetSlots (acc);
-    cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
-
-    /* Accounts are indexed by thier unique currency name */
-    cur_name = gnc_commodity_get_unique_name (currency);
-    vvv = kvp_frame_get_slot (cwd, cur_name);
-    gain_acct_guid = kvp_value_get_guid (vvv);
-
-    gain_acct = xaccAccountLookup (gain_acct_guid, qof_instance_get_book(acc));
-    return gain_acct;
-}
-
-/* ============================================================== */
-/* Functionally identical to the following:
- *   if (!xaccAccountGetDefaultGainAccount()) {
- *               xaccAccountSetDefaultGainAccount (); }
- * except that it saves a few cycles.
- */
-
-static Account *
-GetOrMakeGainAcct (Account *acc, gnc_commodity * currency)
-{
-    Account *gain_acct = NULL;
-    KvpFrame *cwd;
-    KvpValue *vvv;
-    GncGUID * gain_acct_guid;
-    const char * cur_name;
-
-    cwd = xaccAccountGetSlots (acc);
-    cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
-
-    /* Accounts are indexed by thier unique currency name */
-    cur_name = gnc_commodity_get_unique_name (currency);
-    vvv = kvp_frame_get_slot (cwd, cur_name);
-    gain_acct_guid = kvp_value_get_guid (vvv);
-
-    gain_acct = xaccAccountLookup (gain_acct_guid, qof_instance_get_book(acc));
-
-    /* If there is no default place to put gains/losses
-     * for this account, then create such a place */
-    if (NULL == gain_acct)
-    {
-        Account *root;
-
-        xaccAccountBeginEdit (acc);
-        root = gnc_account_get_root(acc);
-        gain_acct = GetOrMakeLotOrphanAccount (root, currency);
-
-        vvv = kvp_value_new_guid (xaccAccountGetGUID (gain_acct));
-        kvp_frame_set_slot_nc (cwd, cur_name, vvv);
-        qof_instance_set_slots(QOF_INSTANCE(acc), acc->inst.kvp_data);
-        xaccAccountCommitEdit (acc);
-
-    }
-    return gain_acct;
-}
-
-/* ============================================================== */
 
 Split *
 xaccSplitAssignToLot (Split *split, GNCLot *lot)
@@ -541,22 +397,18 @@ xaccSplitAssignToLot (Split *split, GNCLot *lot)
         ts = xaccSplitRetDateReconciledTS (split);
         xaccSplitSetDateReconciledTS (new_split, &ts);
 
-        /* We do not copy the KVP tree, as it seems like a dangerous
-         * thing to do.  If the user wants to access stuff in the 'old'
-         * kvp tree from the 'new' split, they shoudl follow the
-         * 'split-lot' pointers.  Yes, this is complicated, but what
-         * else can one do ??
-         */
-        /* Add kvp markup to indicate that these two splits used
-         * to be one before being 'split'
+        /* Set the lot-split and peer_guid properties on the two
+         * splits to indicate that they're linked. 
          */
-        gnc_kvp_bag_add (split->inst.kvp_data, "lot-split", now,
-                         "peer_guid", xaccSplitGetGUID (new_split),
-                         NULL);
+        qof_instance_set (QOF_INSTANCE (split),
+                          "lot-split", now,
+                          "peer_guid", xaccSplitGetGUID (new_split),
+                          NULL);
 
-        gnc_kvp_bag_add (new_split->inst.kvp_data, "lot-split", now,
-                         "peer_guid", xaccSplitGetGUID (split),
-                         NULL);
+        qof_instance_set (QOF_INSTANCE (new_split),
+                          "lot-split", now,
+                          "peer_guid", xaccSplitGetGUID (split),
+                          NULL);
 
         xaccAccountInsertSplit (acc, new_split);
         xaccTransAppendSplit (trans, new_split);
@@ -633,15 +485,14 @@ xaccSplitAssign (Split *split)
 Split *
 xaccSplitGetCapGainsSplit (const Split *split)
 {
-    KvpValue *val;
     GncGUID *gains_guid;
     Split *gains_split;
 
     if (!split) return NULL;
 
-    val = kvp_frame_get_slot (split->inst.kvp_data, "gains-split");
-    if (!val) return NULL;
-    gains_guid = kvp_value_get_guid (val);
+    qof_instance_get (QOF_INSTANCE (split),
+                      "gains-split", &gains_guid,
+                      NULL);
     if (!gains_guid) return NULL;
 
     /* Both splits will be in the same collection, so search there. */
@@ -656,15 +507,14 @@ xaccSplitGetCapGainsSplit (const Split *split)
 Split *
 xaccSplitGetGainsSourceSplit (const Split *split)
 {
-    KvpValue *val;
     GncGUID *source_guid;
     Split *source_split;
 
     if (!split) return NULL;
 
-    val = kvp_frame_get_slot (split->inst.kvp_data, "gains-source");
-    if (!val) return NULL;
-    source_guid = kvp_value_get_guid (val);
+    qof_instance_get (QOF_INSTANCE (split),
+                      "gains-source", &source_guid,
+                      NULL);
     if (!source_guid) return NULL;
 
     /* Both splits will be in the same collection, so search there. */
@@ -697,8 +547,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
     currency = split->parent->common_currency;
 
     ENTER ("(split=%p gains=%p status=0x%x lot=%s)", split,
-           split->gains_split, split->gains,
-           kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
+           split->gains_split, split->gains, gnc_lot_get_title(lot));
 
     /* Make sure the status flags and pointers are initialized */
     xaccSplitDetermineGainStatus(split);
@@ -942,7 +791,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
                     (FALSE == gnc_commodity_equiv (currency,
                                                    xaccAccountGetCommodity(gain_acc))))
             {
-                gain_acc = GetOrMakeGainAcct (lot_acc, currency);
+                gain_acc = xaccAccountGainsAccount (lot_acc, currency);
             }
 
             xaccAccountBeginEdit (gain_acc);
@@ -965,17 +814,18 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
             xaccSplitSetMemo (lot_split, _("Realized Gain/Loss"));
             xaccSplitSetMemo (gain_split, _("Realized Gain/Loss"));
 
-            /* For the new transaction, install KVP markup indicating
+            /* For the new transaction, set the split properties indicating
              * that this is the gains transaction that corresponds
              * to the gains source.
              */
             xaccTransBeginEdit (base_txn);
-            kvp_frame_set_guid (split->inst.kvp_data, "gains-split",
-                                xaccSplitGetGUID (lot_split));
-            qof_instance_set_dirty (QOF_INSTANCE (split));
+            qof_instance_set (QOF_INSTANCE (split),
+                              "gains-split", xaccSplitGetGUID (lot_split),
+                              NULL);
             xaccTransCommitEdit (base_txn);
-            kvp_frame_set_guid (lot_split->inst.kvp_data, "gains-source",
-                                xaccSplitGetGUID (split));
+            qof_instance_set (QOF_INSTANCE (lot_split),
+                              "gains-source", xaccSplitGetGUID (split),
+                              NULL);
 
         }
         else
@@ -1031,7 +881,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
             xaccSplitSetAmount (gain_split, negvalue);
             xaccSplitSetValue (gain_split, negvalue);
 
-            /* Some short-cuts to help avoid the above kvp lookup. */
+            /* Some short-cuts to help avoid the above property lookup. */
             split->gains = GAINS_STATUS_CLEAN;
             split->gains_split = lot_split;
             lot_split->gains = GAINS_STATUS_GAINS;
diff --git a/src/engine/cap-gains.h b/src/engine/cap-gains.h
index 62c8f83..76792bd 100644
--- a/src/engine/cap-gains.h
+++ b/src/engine/cap-gains.h
@@ -124,25 +124,6 @@ GNCLot * xaccAccountFindLatestOpenLot (Account *acc,
                                        gnc_numeric sign,
                                        gnc_commodity *currency);
 
-/** The xaccAccountGetDefaultGainAccount() routine will return
- *   the account to which realized gains/losses may be posted.
- *   Because gains may be in different currencies, one must
- *   specify the currency type in which the gains will be posted.
- *   This routine does nothing more than return the value of
- *   the "/lot-mgmt/gains-act/XXX" key, where XXX is the unique
- *   currency name.  IOf there is no default account for this
- *   currency, NULL will be returned.
- */
-Account * xaccAccountGetDefaultGainAccount (const Account *acc, const gnc_commodity * currency);
-
-/** The xaccAccountSetDefaultGainAccount() routine can be used
- *   to set the account to which realized gains/losses will be
- *   posted by default. This routine does nothing more than set
- *   value of the "/lot-mgmt/gains-act/XXX" key, where XXX is the
- *   unique currency name of the currency of gains account.
- */
-void xaccAccountSetDefaultGainAccount (Account *acc, const Account *gains_acct);
-
 /** The xaccSplitGetCapGainsSplit() routine returns the split
  *  that records the cap gains for this split.  It returns NULL
  *  if not found.  This routine does nothing more than search for
diff --git a/src/engine/engine.i b/src/engine/engine.i
index 49cfc23..8fe362f 100644
--- a/src/engine/engine.i
+++ b/src/engine/engine.i
@@ -140,10 +140,18 @@ functions. */
 
 QofSession * qof_session_new (void);
 QofBook * qof_session_get_book (QofSession *session);
-
-// TODO: Maybe unroll
-void qof_book_kvp_changed (QofBook *book);
-
+/* This horror is to permit the scheme options in
+ * src/app-utils/options.scm to read and write the book's KVP (another
+ * horror) directly. It should be refactored into book functions that
+ * handle the KVP access.
+ */
+%inline {
+  KvpFrame *qof_book_get_slots (QofBook *book);
+  extern KvpFrame *qof_instance_get_slots (QofInstance*);
+  KvpFrame *qof_book_get_slots (QofBook *book) {
+       return qof_instance_get_slots (QOF_INSTANCE (book));
+  }
+}
 // TODO: Unroll/remove
 const char *qof_session_get_url (QofSession *session);
 
@@ -173,7 +181,6 @@ SplitList * qof_query_run_subquery (QofQuery *q, const QofQuery *q);
 %include <qofbookslots.h>
 %include <qofbook.h>
 
-KvpFrame* qof_book_get_slots(QofBook* book);
 %ignore GNC_DENOM_AUTO;
 %ignore GNCNumericErrorCodes;
 %ignore GNC_ERROR_OK;
diff --git a/src/engine/gnc-budget.c b/src/engine/gnc-budget.c
index ae1e2e3..7e255b7 100644
--- a/src/engine/gnc-budget.c
+++ b/src/engine/gnc-budget.c
@@ -22,29 +22,31 @@
  *                                                                  *
 \********************************************************************/
 
-#include "config.h"
+#include <config.h>
 #include <glib.h>
 #include <glib/gprintf.h>
 #include <glib/gi18n.h>
 #include <time.h>
-#include "qof.h"
-#include "qofbookslots.h"
+#include <qof.h>
+#include <qofbookslots.h>
+#include <gnc-gdate-utils.h>
+#include <qofinstance-p.h>
 
 #include "Account.h"
 
 #include "gnc-budget.h"
 #include "gnc-commodity.h"
-#include "gnc-gdate-utils.h"
 
 static QofLogModule log_module = GNC_MOD_ENGINE;
 
 enum
 {
     PROP_0,
-    PROP_NAME,
-    PROP_DESCRIPTION,
-    PROP_NUM_PERIODS,
-    PROP_RECURRENCE,
+    PROP_NAME,			/* Table */
+    PROP_DESCRIPTION,		/* Table */
+    PROP_NUM_PERIODS,		/* Table */
+    PROP_RUNTIME_0,
+    PROP_RECURRENCE,		/* Cached pointer; Recurrence table holds budget guid */
 };
 
 struct budget_s
@@ -156,6 +158,9 @@ gnc_budget_set_property( GObject* object,
     g_return_if_fail(GNC_IS_BUDGET(object));
 
     budget = GNC_BUDGET(object);
+    if (prop_id < PROP_RUNTIME_0)
+	g_assert (qof_instance_get_editlevel(budget));
+
     switch ( prop_id )
     {
     case PROP_NAME:
@@ -626,31 +631,23 @@ gnc_budget_get_default (QofBook *book)
 {
     QofCollection *col;
     GncBudget *bgt = NULL;
-    kvp_value *kvp_default_budget;
-    const GncGUID *default_budget_guid;
+    const GncGUID *default_budget_guid = NULL;
 
     g_return_val_if_fail(book, NULL);
 
     /* See if there is a budget selected in the KVP perferences */
 
-    kvp_default_budget = kvp_frame_get_slot_path(qof_book_get_slots (book),
-                         KVP_OPTION_PATH,
-                         OPTION_SECTION_BUDGETING,
-                         OPTION_NAME_DEFAULT_BUDGET,
-                         NULL);
-
-    if (kvp_default_budget != NULL )
+    qof_instance_get (QOF_INSTANCE (book),
+		      "default-budget", &default_budget_guid,
+		      NULL);
+    if (default_budget_guid != NULL)
     {
-        default_budget_guid = kvp_value_get_guid(kvp_default_budget);
-        if (default_budget_guid != NULL)
-        {
-            col = qof_book_get_collection(book, GNC_ID_BUDGET);
-            bgt = (GncBudget *) qof_collection_lookup_entity(col,
-                    default_budget_guid);
-        }
+	col = qof_book_get_collection(book, GNC_ID_BUDGET);
+	bgt = (GncBudget *) qof_collection_lookup_entity(col,
+							 default_budget_guid);
     }
 
-    /* Revert to 2.2.x behavior if there is no defined budget in KVP */
+    /* Revert to 2.2.x behavior if the book has no default budget. */
 
     if ( bgt == NULL )
     {
diff --git a/src/engine/gnc-commodity.c b/src/engine/gnc-commodity.c
index 77c643b..851bba5 100644
--- a/src/engine/gnc-commodity.c
+++ b/src/engine/gnc-commodity.c
@@ -23,7 +23,7 @@
  *                                                                  *
  *******************************************************************/
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <regex.h>
+#include <qofinstance-p.h>
 
 #include "gnc-commodity.h"
 #include "gnc-prefs.h"
@@ -47,16 +48,16 @@ static QofLogModule log_module = GNC_MOD_COMMODITY;
 enum
 {
     PROP_0,
-    PROP_NAMESPACE,
-    PROP_FULL_NAME,
-    PROP_MNEMONIC,
-    PROP_PRINTNAME,
-    PROP_CUSIP,
-    PROP_FRACTION,
-    PROP_UNIQUE_NAME,
-    PROP_QUOTE_FLAG,
-    PROP_QUOTE_SOURCE,
-    PROP_QUOTE_TZ,
+    PROP_NAMESPACE,	/* Table */
+    PROP_FULL_NAME,	/* Table */
+    PROP_MNEMONIC,	/* Table */
+    PROP_PRINTNAME,	/* Constructed */
+    PROP_CUSIP,		/* Table */
+    PROP_FRACTION,	/* Table */
+    PROP_UNIQUE_NAME,	/* Constructed */
+    PROP_QUOTE_FLAG,	/* Table */
+    PROP_QUOTE_SOURCE,	/* Table */
+    PROP_QUOTE_TZ,	/* Table */
 };
 
 struct gnc_commodity_s
@@ -698,6 +699,7 @@ gnc_commodity_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_COMMODITY(object));
 
     commodity = GNC_COMMODITY(object);
+    g_assert (qof_instance_get_editlevel(commodity));
 
     switch (prop_id)
     {
diff --git a/src/engine/gnc-engine.h b/src/engine/gnc-engine.h
index f4943fb..4522e1e 100644
--- a/src/engine/gnc-engine.h
+++ b/src/engine/gnc-engine.h
@@ -251,5 +251,16 @@ void gnc_engine_add_commit_error_callback( EngineCommitErrorCallback cb, gpointe
 
 void gnc_engine_signal_commit_error( QofBackendError errcode );
 
+/** STRING CONSTANTS **********************************************
+ * Used to declare constant KVP keys used in more than one class
+ */
+#define GNC_INVOICE_ID    "gncInvoice"
+#define GNC_INVOICE_GUID  "invoice-guid"
+#define GNC_OWNER_ID      "gncOwner"
+#define GNC_OWNER_TYPE    "owner-type"
+#define GNC_OWNER_GUID    "owner-guid"
+#define GNC_SX_ID         "sched-xaction"
+
+
 #endif
 /** @} */
diff --git a/src/engine/gnc-lot.c b/src/engine/gnc-lot.c
index 08fdef6..d86f0be 100644
--- a/src/engine/gnc-lot.c
+++ b/src/engine/gnc-lot.c
@@ -39,10 +39,11 @@
  * Copyright (c) 2002,2003 Linas Vepstas <linas at linas.org>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
+#include <qofinstance-p.h>
 
 #include "Account.h"
 #include "AccountP.h"
@@ -63,8 +64,15 @@ struct gnc_lot_s
 enum
 {
     PROP_0,
-    PROP_IS_CLOSED,
-    PROP_MARKER
+//  PROP_ACCOUNT, 	/* Table */
+    PROP_IS_CLOSED,	/* Table */
+
+    PROP_INVOICE,	/* KVP */
+    PROP_OWNER_TYPE,	/* KVP */
+    PROP_OWNER_GUID,	/* KVP */
+
+    PROP_RUNTIME_0,
+    PROP_MARKER,	/* Runtime */
 };
 
 typedef struct LotPrivate
@@ -93,6 +101,11 @@ typedef struct LotPrivate
 
 /* ============================================================= */
 
+static void gnc_lot_set_invoice (GNCLot* lot, GncGUID *guid);
+static GncGUID *gnc_lot_get_invoice (GNCLot* lot);
+
+/* ============================================================= */
+
 /* GObject Initialization */
 G_DEFINE_TYPE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE)
 
@@ -125,6 +138,9 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec*
 {
     GNCLot* lot;
     LotPrivate* priv;
+    KvpFrame *frame;
+    gchar *key;
+    GValue *temp;
 
     g_return_if_fail(GNC_IS_LOT(object));
 
@@ -138,18 +154,41 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec*
     case PROP_MARKER:
         g_value_set_int(value, priv->marker);
         break;
+    case PROP_INVOICE:
+	key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
+	qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
+	break;
+    case PROP_OWNER_TYPE:
+	key = GNC_OWNER_ID"/" GNC_OWNER_TYPE;
+	qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
+	break;
+    case PROP_OWNER_GUID:
+	key = GNC_OWNER_ID "/" GNC_OWNER_GUID;
+	qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
+	break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
     }
 }
 
 static void
-gnc_lot_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
+gnc_lot_set_property (GObject* object,
+		      guint prop_id,
+		      const GValue* value,
+		      GParamSpec* pspec)
 {
     GNCLot* lot;
     LotPrivate* priv;
+    KvpFrame *frame;
+    gchar *key = NULL;
 
     g_return_if_fail(GNC_IS_LOT(object));
 
     lot = GNC_LOT(object);
+    if (prop_id < PROP_RUNTIME_0)
+	g_assert (qof_instance_get_editlevel(lot));
+
     priv = GET_PRIVATE(lot);
     switch (prop_id)
     {
@@ -159,7 +198,22 @@ gnc_lot_set_property(GObject* object, guint prop_id, const GValue* value, GParam
     case PROP_MARKER:
         priv->marker = g_value_get_int(value);
         break;
-    }
+    case PROP_INVOICE:
+	key = GNC_INVOICE_ID"/" GNC_INVOICE_GUID;
+	qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
+	break;
+    case PROP_OWNER_TYPE:
+	key = GNC_OWNER_ID "/" GNC_OWNER_TYPE;
+	qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
+	break;
+    case PROP_OWNER_GUID:
+	key = GNC_OWNER_ID "/" GNC_OWNER_GUID;
+	qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
+	break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+     }
 }
 
 static void
@@ -193,8 +247,32 @@ gnc_lot_class_init(GNCLotClass* klass)
                          0, G_MAXINT8, 0,
                          G_PARAM_READWRITE));
 
-
-
+     g_object_class_install_property(
+       gobject_class,
+        PROP_INVOICE,
+        g_param_spec_boxed("invoice",
+			   "Invoice attached to lot",
+			   "Used by GncInvoice",
+			   GNC_TYPE_GUID,
+			   G_PARAM_READWRITE));
+
+     g_object_class_install_property(
+       gobject_class,
+        PROP_OWNER_TYPE,
+        g_param_spec_int64("owner-type",
+			   "Owning Entity Type of  lot",
+			   "Used by GncOwner",
+			   0, G_MAXINT64, 0,
+			   G_PARAM_READWRITE));
+
+     g_object_class_install_property(
+       gobject_class,
+        PROP_OWNER_GUID,
+        g_param_spec_boxed("owner-guid",
+			   "Owner attached to lot",
+			   "Used by GncOwner",
+			   GNC_TYPE_GUID,
+			   G_PARAM_READWRITE));
 }
 
 GNCLot *
@@ -333,12 +411,6 @@ gnc_lot_set_closed_unknown(GNCLot* lot)
     }
 }
 
-KvpFrame *
-gnc_lot_get_slots (const GNCLot *lot)
-{
-    return qof_instance_get_slots(QOF_INSTANCE(lot));
-}
-
 SplitList *
 gnc_lot_get_split_list (const GNCLot *lot)
 {
@@ -363,14 +435,16 @@ const char *
 gnc_lot_get_title (const GNCLot *lot)
 {
     if (!lot) return NULL;
-    return kvp_frame_get_string (gnc_lot_get_slots(lot), "/title");
+    return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
+				 "/title");
 }
 
 const char *
 gnc_lot_get_notes (const GNCLot *lot)
 {
     if (!lot) return NULL;
-    return kvp_frame_get_string (gnc_lot_get_slots(lot), "/notes");
+    return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
+				 "/notes");
 }
 
 void
@@ -379,7 +453,8 @@ gnc_lot_set_title (GNCLot *lot, const char *str)
     if (!lot) return;
     qof_begin_edit(QOF_INSTANCE(lot));
     qof_instance_set_dirty(QOF_INSTANCE(lot));
-    kvp_frame_set_str (gnc_lot_get_slots(lot), "/title", str);
+    kvp_frame_set_str (qof_instance_get_slots(QOF_INSTANCE (lot)),
+		       "/title", str);
     gnc_lot_commit_edit(lot);
 }
 
@@ -389,7 +464,8 @@ gnc_lot_set_notes (GNCLot *lot, const char *str)
     if (!lot) return;
     gnc_lot_begin_edit(lot);
     qof_instance_set_dirty(QOF_INSTANCE(lot));
-    kvp_frame_set_str (gnc_lot_get_slots(lot), "/notes", str);
+    kvp_frame_set_str (qof_instance_get_slots (QOF_INSTANCE (lot)),
+		       "/notes", str);
     gnc_lot_commit_edit(lot);
 }
 
@@ -675,20 +751,20 @@ gboolean gnc_lot_register (void)
 GNCLot * gnc_lot_make_default (Account *acc)
 {
     GNCLot * lot;
-    gint64 id;
-    char buff[200];
+    gint64 id = 0;
+    gchar *buff;
 
     lot = gnc_lot_new (qof_instance_get_book(acc));
 
     /* Provide a reasonable title for the new lot */
     xaccAccountBeginEdit (acc);
-    id = kvp_frame_get_gint64 (xaccAccountGetSlots (acc), "/lot-mgmt/next-id");
-    snprintf (buff, 200, ("%s %" G_GINT64_FORMAT), _("Lot"), id);
-    kvp_frame_set_str (gnc_lot_get_slots (lot), "/title", buff);
+    qof_instance_get (QOF_INSTANCE (acc), "lot-next-id", &id, NULL);
+    buff = g_strdup_printf ("%s %" G_GINT64_FORMAT, _("Lot"), id);
+    gnc_lot_set_title (lot, buff);
     id ++;
-    kvp_frame_set_gint64 (xaccAccountGetSlots (acc), "/lot-mgmt/next-id", id);
-    qof_instance_set_dirty (QOF_INSTANCE(acc));
+    qof_instance_set (QOF_INSTANCE (acc), "lot-next-id", id, NULL);
     xaccAccountCommitEdit (acc);
+    g_free (buff);
     return lot;
 }
 
diff --git a/src/engine/gnc-lot.h b/src/engine/gnc-lot.h
index 1e477e1..64e1dfa 100644
--- a/src/engine/gnc-lot.h
+++ b/src/engine/gnc-lot.h
@@ -165,11 +165,6 @@ const char * gnc_lot_get_notes (const GNCLot *);
 void gnc_lot_set_title (GNCLot *, const char *);
 void gnc_lot_set_notes (GNCLot *, const char *);
 
-/** Every lot has a place to hang kvp data.  This routine returns that
- *     place.
- * */
-KvpFrame * gnc_lot_get_slots (const GNCLot *);
-
 /** XXX: Document? */
 GNCLot * gnc_lot_make_default (Account * acc);
 
diff --git a/src/engine/gnc-pricedb.c b/src/engine/gnc-pricedb.c
index 54b7385..23fbae0 100644
--- a/src/engine/gnc-pricedb.c
+++ b/src/engine/gnc-pricedb.c
@@ -41,12 +41,12 @@ static GNCPrice *lookup_nearest_in_time(GNCPriceDB *db, const gnc_commodity *c,
 enum
 {
     PROP_0,
-    PROP_COMMODITY,
-    PROP_CURRENCY,
-    PROP_DATE,
-    PROP_SOURCE,
-    PROP_TYPE,
-    PROP_VALUE
+    PROP_COMMODITY,	/* Table */
+    PROP_CURRENCY,	/* Table */
+    PROP_DATE,		/* Table */
+    PROP_SOURCE,	/* Table */
+    PROP_TYPE,		/* Table */
+    PROP_VALUE,		/* Table, 2 fields (numeric) */
 };
 
 /* GObject Initialization */
@@ -123,6 +123,8 @@ gnc_price_set_property(GObject* object, guint prop_id, const GValue* value, GPar
     g_return_if_fail(GNC_IS_PRICE(object));
 
     price = GNC_PRICE(object);
+    g_assert (qof_instance_get_editlevel(price));
+
     switch (prop_id)
     {
     case PROP_SOURCE:
diff --git a/src/engine/gncAddress.c b/src/engine/gncAddress.c
index 97bbfd7..103e35a 100644
--- a/src/engine/gncAddress.c
+++ b/src/engine/gncAddress.c
@@ -25,9 +25,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
+#include <qofinstance-p.h>
 
 #include "gncAddress.h"
 #include "gncAddressP.h"
diff --git a/src/engine/gncBillTerm.c b/src/engine/gncBillTerm.c
index 835f052..9f2c7b9 100644
--- a/src/engine/gncBillTerm.c
+++ b/src/engine/gncBillTerm.c
@@ -26,9 +26,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
+#include <qofinstance-p.h>
 
 #include "gnc-engine.h"
 #include "gncBillTermP.h"
@@ -192,6 +193,8 @@ gnc_billterm_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_BILLTERM(object));
 
     bt = GNC_BILLTERM(object);
+    g_assert (qof_instance_get_editlevel(bt));
+
     switch (prop_id)
     {
     case PROP_NAME:
diff --git a/src/engine/gncBusiness.h b/src/engine/gncBusiness.h
index b9a960f..11584b7 100644
--- a/src/engine/gncBusiness.h
+++ b/src/engine/gncBusiness.h
@@ -37,6 +37,12 @@
 #include <glib.h>
 #include "qof.h"
 
+/* KVP key for report PDF directories */
+#define OWNER_EXPORT_PDF_DIRNAME "export-pdf-directory"
+#define LAST_POSTED_TO_ACCT "last-posted-to-acct"
+#define GNC_PAYMENT "payment"
+#define GNC_LAST_ACCOUNT "last_acct"
+
 /* @deprecated backwards-compat definitions */
 #define GNC_BILLTERM_MODULE_NAME GNC_ID_BILLTERM
 #define GNC_CUSTOMER_MODULE_NAME GNC_ID_CUSTOMER
diff --git a/src/engine/gncCustomer.c b/src/engine/gncCustomer.c
index 581e97a..5d3d7c5 100644
--- a/src/engine/gncCustomer.c
+++ b/src/engine/gncCustomer.c
@@ -30,6 +30,7 @@
 
 #include <glib.h>
 #include <string.h>
+#include <qofinstance-p.h>
 
 #include "gnc-commodity.h"
 
@@ -96,7 +97,10 @@ void mark_customer (GncCustomer *customer)
 enum
 {
     PROP_0,
-    PROP_NAME
+    PROP_NAME,
+    PROP_PDF_DIRNAME,
+    PROP_LAST_POSTED,
+    PROP_PAYMENT_LAST_ACCT,
 };
 
 /* GObject Initialization */
@@ -126,7 +130,7 @@ gnc_customer_get_property (GObject         *object,
                            GParamSpec      *pspec)
 {
     GncCustomer *cust;
-
+    gchar *key;
     g_return_if_fail(GNC_IS_CUSTOMER(object));
 
     cust = GNC_CUSTOMER(object);
@@ -135,6 +139,18 @@ gnc_customer_get_property (GObject         *object,
     case PROP_NAME:
         g_value_set_string(value, cust->name);
         break;
+    case PROP_PDF_DIRNAME:
+	key = OWNER_EXPORT_PDF_DIRNAME;
+	qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
+	break;
+    case PROP_LAST_POSTED:
+	key = LAST_POSTED_TO_ACCT;
+	qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
+	break;
+    case PROP_PAYMENT_LAST_ACCT:
+	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
+	qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -144,19 +160,34 @@ gnc_customer_get_property (GObject         *object,
 static void
 gnc_customer_set_property (GObject         *object,
                            guint            prop_id,
-                           const GValue          *value,
+                           const GValue    *value,
                            GParamSpec      *pspec)
 {
     GncCustomer *cust;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_CUSTOMER(object));
 
     cust = GNC_CUSTOMER(object);
+    g_assert (qof_instance_get_editlevel(cust));
+
     switch (prop_id)
     {
     case PROP_NAME:
         gncCustomerSetName(cust, g_value_get_string(value));
         break;
+    case PROP_PDF_DIRNAME:
+	key = OWNER_EXPORT_PDF_DIRNAME;
+	qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
+	break;
+    case PROP_LAST_POSTED:
+	key = LAST_POSTED_TO_ACCT;
+	qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
+	break;
+    case PROP_PAYMENT_LAST_ACCT:
+	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
+	qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -242,6 +273,39 @@ gnc_customer_class_init (GncCustomerClass *klass)
                           "customer name.",
                           NULL,
                           G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_PDF_DIRNAME,
+     g_param_spec_string ("export-pdf-dir",
+                          "Export PDF Directory Name",
+                          "A subdirectory for exporting PDF reports which is "
+			  "appended to the target directory when writing them "
+			  "out. It is retrieved from preferences and stored on "
+			  "each 'Owner' object which prints items after "
+			  "printing.",
+                          NULL,
+                          G_PARAM_READWRITE));
+
+    g_object_class_install_property(
+       gobject_class,
+       PROP_LAST_POSTED,
+       g_param_spec_boxed("invoice-last-posted-account",
+			  "Invoice Last Posted Account",
+			  "The last account to which an invoice belonging to "
+			  "this owner was posted.",
+			  GNC_TYPE_GUID,
+			  G_PARAM_READWRITE));
+
+    g_object_class_install_property(
+       gobject_class,
+       PROP_PAYMENT_LAST_ACCT,
+       g_param_spec_boxed("payment-last-account",
+			  "Payment Last Account",
+			  "The last account to which an payment belonging to "
+			  "this owner was posted.",
+			  GNC_TYPE_GUID,
+			  G_PARAM_READWRITE));
 }
 
 /* Create/Destroy Functions */
@@ -866,7 +930,6 @@ gboolean gncCustomerRegister (void)
             (QofSetterFunc)gncCustomerSetTaxTableOverride
         },
         { CUSTOMER_TERMS, GNC_ID_BILLTERM, (QofAccessFunc)gncCustomerGetTerms, (QofSetterFunc)gncCustomerSetTerms },
-        { CUSTOMER_SLOTS, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL },
         { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncCustomerGetActive, (QofSetterFunc)gncCustomerSetActive },
         { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
         { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
diff --git a/src/engine/gncEmployee.c b/src/engine/gncEmployee.c
index 94d7a72..ebfb518 100644
--- a/src/engine/gncEmployee.c
+++ b/src/engine/gncEmployee.c
@@ -26,10 +26,11 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
 #include <string.h>
+#include <qofinstance-p.h>
 
 #include "Account.h"
 #include "gnc-commodity.h"
@@ -79,16 +80,19 @@ void mark_employee (GncEmployee *employee)
 enum
 {
     PROP_0,
-    PROP_USERNAME,
-    PROP_ID,
-    PROP_ACTIVE,
-    PROP_LANGUAGE,
-    PROP_CURRENCY,
-    PROP_ACL,
-    PROP_ADDRESS,
-    PROP_WORKDAY,
-    PROP_RATE,
-    PROP_CCARD
+    PROP_USERNAME,		/* Table */
+    PROP_ID,			/* Table */
+    PROP_LANGUAGE,		/* Table */
+    PROP_ACL,			/* Table */
+    PROP_ACTIVE,		/* Table */
+    PROP_CURRENCY,		/* Table */
+    PROP_CCARD,			/* Table */
+    PROP_WORKDAY,		/* Table (numeric) */
+    PROP_RATE,			/* Table (numeric) */
+    PROP_ADDRESS,		/* Table, 8 fields */
+    PROP_PDF_DIRNAME,		/* KVP */
+    PROP_LAST_POSTED,		/* KVP */
+    PROP_PAYMENT_LAST_ACCT,	/* KVP */
 };
 
 /* GObject Initialization */
@@ -124,6 +128,7 @@ gnc_employee_get_property (GObject         *object,
                            GParamSpec      *pspec)
 {
     GncEmployee *emp;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_EMPLOYEE(object));
 
@@ -160,6 +165,18 @@ gnc_employee_get_property (GObject         *object,
     case PROP_CCARD:
         g_value_take_object(value, emp->ccard_acc);
         break;
+    case PROP_PDF_DIRNAME:
+	key = OWNER_EXPORT_PDF_DIRNAME;
+	qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
+	break;
+    case PROP_LAST_POSTED:
+	key = LAST_POSTED_TO_ACCT;
+	qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
+	break;
+    case PROP_PAYMENT_LAST_ACCT:
+	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
+	qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -173,10 +190,13 @@ gnc_employee_set_property (GObject         *object,
                            GParamSpec      *pspec)
 {
     GncEmployee *emp;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_EMPLOYEE(object));
 
     emp = GNC_EMPLOYEE(object);
+    g_assert (qof_instance_get_editlevel(emp));
+
     switch (prop_id)
     {
     case PROP_USERNAME:
@@ -209,6 +229,18 @@ gnc_employee_set_property (GObject         *object,
     case PROP_CCARD:
         gncEmployeeSetCCard(emp, g_value_get_object(value));
         break;
+    case PROP_PDF_DIRNAME:
+	key = OWNER_EXPORT_PDF_DIRNAME;
+	qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
+	break;
+    case PROP_LAST_POSTED:
+	key = LAST_POSTED_TO_ACCT;
+	qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
+	break;
+    case PROP_PAYMENT_LAST_ACCT:
+	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
+	qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -367,6 +399,39 @@ gnc_employee_class_init (GncEmployeeClass *klass)
                           "The credit card account for this employee.",
                           GNC_TYPE_ACCOUNT,
                           G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_PDF_DIRNAME,
+     g_param_spec_string ("export-pdf-dir",
+                          "Export PDF Directory Name",
+                          "A subdirectory for exporting PDF reports which is "
+			  "appended to the target directory when writing them "
+			  "out. It is retrieved from preferences and stored on "
+			  "each 'Owner' object which prints items after "
+			  "printing.",
+                          NULL,
+                          G_PARAM_READWRITE));
+
+    g_object_class_install_property(
+       gobject_class,
+       PROP_LAST_POSTED,
+       g_param_spec_boxed("invoice-last-posted-account",
+			  "Invoice Last Posted Account",
+			  "The last account to which an invoice belonging to "
+			  "this owner was posted.",
+			  GNC_TYPE_GUID,
+			  G_PARAM_READWRITE));
+
+    g_object_class_install_property(
+       gobject_class,
+       PROP_PAYMENT_LAST_ACCT,
+       g_param_spec_boxed("payment-last-account",
+			  "Payment Last Account",
+			  "The last account to which an payment belonging to "
+			  "this owner was posted.",
+			  GNC_TYPE_GUID,
+			  G_PARAM_READWRITE));
 }
 
 /* Create/Destroy Functions */
diff --git a/src/engine/gncEntry.c b/src/engine/gncEntry.c
index 2593bed..173edbc 100644
--- a/src/engine/gncEntry.c
+++ b/src/engine/gncEntry.c
@@ -25,9 +25,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
+#include <qofinstance-p.h>
 
 #include "gnc-commodity.h"
 
@@ -211,7 +212,32 @@ void mark_entry (GncEntry *entry)
 enum
 {
     PROP_0,
-    PROP_DESCRIPTION
+//  PROP_DATE,		/* Table */
+//  PROP_DATE_ENTERED,	/* Table */
+    PROP_DESCRIPTION,	/* Table */
+//  PROP_ACTION,	/* Table */
+//  PROP_NOTES,		/* Table */
+//  PROP_QUANTITY,	/* Table (numeric) */
+//  PROP_I_ACCT,	/* Table */
+//  PROP_I_PRICE,	/* Table (numeric) */
+//  PROP_I_DISCOUNT,	/* Table (numeric) */
+//  PROP_INVOICE,	/* Table */
+//  PROP_I_DISC_TYPE,	/* Table */
+//  PROP_I_DISC_HOW,	/* Table */
+//  PROP_I_TAXABLE,	/* Table */
+//  PROP_I_TAX_INCL,	/* Table */
+//  PROP_I_TAXTABLE,	/* Table */
+//  PROP_B_ACCT,	/* Table */
+//  PROP_B_PRICE,	/* Table (numeric) */
+//  PROP_BILL,		/* Table */
+//  PROP_B_TAXTABLE_1,	/* Table */
+//  PROP_B_TAX_INCL,	/* Table */
+//  PROP_B_TAXTABLE,	/* Table */
+//  PROP_B_PAYTYPE,	/* Table */
+//  PROP_BILLABLE,	/* Table */
+//  PROP_BILLTO_TYPE,	/* Table */
+//  PROP_BILLTO,	/* Table */
+//  PROP_ORDER,		/* Table */
 };
 
 /* GObject Initialization */
@@ -267,6 +293,8 @@ gnc_entry_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_ENTRY(object));
 
     entry = GNC_ENTRY(object);
+    g_assert (qof_instance_get_editlevel(entry));
+
     switch (prop_id)
     {
     case PROP_DESCRIPTION:
diff --git a/src/engine/gncInvoice.c b/src/engine/gncInvoice.c
index 9b9fed4..0198958 100644
--- a/src/engine/gncInvoice.c
+++ b/src/engine/gncInvoice.c
@@ -27,10 +27,11 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
+#include <qofinstance-p.h>
 
 #include "Transaction.h"
 #include "Account.h"
@@ -81,8 +82,6 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
 
 #define _GNC_MOD_NAME     GNC_ID_INVOICE
 
-#define GNC_INVOICE_ID    "gncInvoice"
-#define GNC_INVOICE_GUID  "invoice-guid"
 #define GNC_INVOICE_IS_CN "credit-note"
 
 #define SET_STR(obj, member, str) { \
@@ -113,7 +112,22 @@ QofBook * gncInvoiceGetBook(GncInvoice *x)
 enum
 {
     PROP_0,
-    PROP_NOTES
+//  PROP_ID,		/* Table */
+//  PROP_DATE_OPENED,	/* Table */
+//  PROP_DATE_POSTED,	/* Table */
+    PROP_NOTES,		/* Table */
+//  PROP_ACTIVE,	/* Table */
+//  PROP_CURRENCY,	/* Table */
+//  PROP_OWNER_TYPE,	/* Table */
+//  PROP_OWNER,		/* Table */
+//  PROP_TERMS,		/* Table */
+//  PROP_BILLING_ID,	/* Table */
+//  PROP_POST_TXN,	/* Table */
+//  PROP_POST_LOT,	/* Table */
+//  PROP_POST_ACCOUNT,	/* Table */
+//  PROP_BILLTO_TYPE,	/* Table */
+//  PROP_BILLTO,	/* Table */
+//  PROP_CHARGE_AMOUNT, /* Table, (numeric) */
 };
 
 /* GObject Initialization */
@@ -169,6 +183,8 @@ gnc_invoice_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_INVOICE(object));
 
     inv = GNC_INVOICE(object);
+    g_assert (qof_instance_get_editlevel(inv));
+
     switch (prop_id)
     {
     case PROP_NOTES:
@@ -1133,52 +1149,37 @@ qofInvoiceSetJob (GncInvoice *invoice, GncJob *job)
 static void
 gncInvoiceDetachFromLot (GNCLot *lot)
 {
-    KvpFrame *kvp;
-
     if (!lot) return;
+
     gnc_lot_begin_edit (lot);
-    kvp = gnc_lot_get_slots (lot);
-    kvp_frame_set_slot_path (kvp, NULL, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
-    qof_instance_set_dirty (QOF_INSTANCE (lot));
+    qof_instance_set (QOF_INSTANCE (lot), "invoice", NULL, NULL);
     gnc_lot_commit_edit (lot);
 }
 
 static void
 gncInvoiceAttachToLot (GncInvoice *invoice, GNCLot *lot)
 {
-    KvpFrame *kvp;
-    KvpValue *value;
-
+    GncGUID *guid;
     if (!invoice || !lot)
         return;
 
     if (invoice->posted_lot) return;	/* Cannot reset invoice's lot */
-
+    guid  = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (invoice));
     gnc_lot_begin_edit (lot);
-    kvp = gnc_lot_get_slots (lot);
-    value = kvp_value_new_guid (qof_instance_get_guid (QOF_INSTANCE(invoice)));
-    kvp_frame_set_slot_path (kvp, value, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
-    qof_instance_set_dirty (QOF_INSTANCE (lot));
+    qof_instance_set (QOF_INSTANCE (lot), "invoice", guid, NULL);
     gnc_lot_commit_edit (lot);
-    kvp_value_delete (value);
     gncInvoiceSetPostedLot (invoice, lot);
 }
 
 GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot)
 {
-    KvpFrame *kvp;
-    KvpValue *value;
-    GncGUID *guid;
+    GncGUID *guid = NULL;
     QofBook *book;
 
     if (!lot) return NULL;
 
     book = gnc_lot_get_book (lot);
-    kvp = gnc_lot_get_slots (lot);
-    value = kvp_frame_get_slot_path (kvp, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
-    if (!value) return NULL;
-
-    guid = kvp_value_get_guid (value);
+    qof_instance_get (QOF_INSTANCE (lot), "invoice", &guid, NULL);
     return gncInvoiceLookup(book, guid);
 }
 
@@ -1194,10 +1195,8 @@ gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
     if (invoice->posted_txn) return;	/* Cannot reset invoice's txn */
 
     xaccTransBeginEdit (txn);
-    kvp = xaccTransGetSlots (txn);
-    value = kvp_value_new_guid (qof_instance_get_guid(QOF_INSTANCE(invoice)));
-    kvp_frame_set_slot_path (kvp, value, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
-    kvp_value_delete (value);
+    qof_instance_set (QOF_INSTANCE (txn), "invoice",
+		      qof_instance_get_guid (QOF_INSTANCE (invoice)), NULL);
     xaccTransSetTxnType (txn, TXN_TYPE_INVOICE);
     xaccTransCommitEdit (txn);
     gncInvoiceSetPostedTxn (invoice, txn);
@@ -1206,19 +1205,13 @@ gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
 GncInvoice *
 gncInvoiceGetInvoiceFromTxn (const Transaction *txn)
 {
-    KvpFrame *kvp;
-    KvpValue *value;
-    GncGUID *guid;
+    GncGUID *guid = NULL;
     QofBook *book;
 
     if (!txn) return NULL;
 
     book = xaccTransGetBook (txn);
-    kvp = xaccTransGetSlots (txn);
-    value = kvp_frame_get_slot_path (kvp, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
-    if (!value) return NULL;
-
-    guid = kvp_value_get_guid (value);
+    qof_instance_get (QOF_INSTANCE (txn), "invoice", &guid, NULL);
     return gncInvoiceLookup(book, guid);
 }
 
diff --git a/src/engine/gncInvoice.h b/src/engine/gncInvoice.h
index e3e41df..4914432 100644
--- a/src/engine/gncInvoice.h
+++ b/src/engine/gncInvoice.h
@@ -268,6 +268,7 @@ GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot);
  */
 static inline GncInvoice * gncInvoiceLookup (const QofBook *book, const GncGUID *guid)
 {
+    if (book == NULL || guid == NULL) return NULL;
     QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_INVOICE, GncInvoice);
 }
 
@@ -305,7 +306,6 @@ QofBook *gncInvoiceGetBook(GncInvoice *x);
 /** deprecated functions */
 #define gncInvoiceGetGUID(x) qof_instance_get_guid(QOF_INSTANCE(x))
 #define gncInvoiceRetGUID(x) (x ? *(qof_instance_get_guid(QOF_INSTANCE(x))) : *(guid_null()))
-#define gncInvoiceLookupDirect(G,B) gncInvoiceLookup((B),&(G))
 
 /** Test support function used by test-dbi-business-stuff.c */
 gboolean gncInvoiceEqual(const GncInvoice *a, const GncInvoice *b);
diff --git a/src/engine/gncJob.c b/src/engine/gncJob.c
index fe7043d..d4200a1 100644
--- a/src/engine/gncJob.c
+++ b/src/engine/gncJob.c
@@ -26,10 +26,11 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
 #include <string.h>
+#include <qofinstance-p.h>
 
 #include "gnc-features.h"
 #include "gncInvoice.h"
@@ -71,7 +72,13 @@ void mark_job (GncJob *job)
 enum
 {
     PROP_0,
-    PROP_NAME
+//  PROP_ID,		/* Table */
+    PROP_NAME,		/* Table */
+//  PROP_REFERENCE,	/* Table */
+//  PROP_ACTIVE,	/* Table */
+//  PROP_OWNER_TYPE,	/* Table */
+//  PROP_OWNER,		/* Table */
+    PROP_PDF_DIRNAME,	/* KVP */
 };
 
 /* GObject Initialization */
@@ -101,6 +108,7 @@ gnc_job_get_property (GObject         *object,
                       GParamSpec      *pspec)
 {
     GncJob *job;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_JOB(object));
 
@@ -110,6 +118,10 @@ gnc_job_get_property (GObject         *object,
     case PROP_NAME:
         g_value_set_string(value, job->name);
         break;
+    case PROP_PDF_DIRNAME:
+	key = OWNER_EXPORT_PDF_DIRNAME;
+	qof_instance_get_kvp (QOF_INSTANCE (job), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -123,15 +135,22 @@ gnc_job_set_property (GObject         *object,
                       GParamSpec      *pspec)
 {
     GncJob *job;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_JOB(object));
 
     job = GNC_JOB(object);
+    g_assert (qof_instance_get_editlevel(job));
+
     switch (prop_id)
     {
     case PROP_NAME:
         gncJobSetName(job, g_value_get_string(value));
         break;
+    case PROP_PDF_DIRNAME:
+	key = OWNER_EXPORT_PDF_DIRNAME;
+	qof_instance_set_kvp (QOF_INSTANCE (job), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -177,6 +196,19 @@ gnc_job_class_init (GncJobClass *klass)
                           "by the GUI as the job mnemonic.",
                           NULL,
                           G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_PDF_DIRNAME,
+     g_param_spec_string ("export-pdf-dir",
+                          "Export PDF Directory Name",
+                          "A subdirectory for exporting PDF reports which is "
+			  "appended to the target directory when writing them "
+			  "out. It is retrieved from preferences and stored on "
+			  "each 'Owner' object which prints items after "
+			  "printing.",
+                          NULL,
+                          G_PARAM_READWRITE));
 }
 
 /* Create/Destroy Functions */
diff --git a/src/engine/gncOrder.c b/src/engine/gncOrder.c
index dd613c4..2d36b54 100644
--- a/src/engine/gncOrder.c
+++ b/src/engine/gncOrder.c
@@ -25,10 +25,11 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
+#include <qofinstance-p.h>
 
 #include "gncEntry.h"
 #include "gncEntryP.h"
@@ -84,12 +85,14 @@ void mark_order (GncOrder *order)
 enum
 {
     PROP_0,
-    PROP_ID,
-    PROP_NOTES,
-    PROP_ACTIVE,
-    PROP_DATE_OPENED,
-    PROP_DATE_CLOSED,
-    PROP_REFERENCE
+    PROP_ID,		/* Table */
+    PROP_NOTES,		/* Table */
+    PROP_REFERENCE,	/* Table */
+    PROP_ACTIVE,	/* Table */
+    PROP_DATE_OPENED,	/* Table */
+    PROP_DATE_CLOSED,	/* Table */
+//  PROP_OWNER_TYPE,	/* Table */
+//  PROP_OWNER,		/* Table */
 };
 
 /* GObject Initialization */
@@ -160,6 +163,8 @@ gnc_order_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_ORDER(object));
 
     order = GNC_ORDER(object);
+    g_assert (qof_instance_get_editlevel(order));
+
     switch (prop_id)
     {
     case PROP_ID:
diff --git a/src/engine/gncOwner.c b/src/engine/gncOwner.c
index 8a1d0bf..6fa69d4 100644
--- a/src/engine/gncOwner.c
+++ b/src/engine/gncOwner.c
@@ -29,11 +29,12 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <string.h>		/* for memcpy() */
+#include <qofinstance-p.h>
 
 #include "gncCustomerP.h"
 #include "gncEmployeeP.h"
@@ -50,8 +51,6 @@
 #define _GNC_MOD_NAME   GNC_ID_OWNER
 
 #define GNC_OWNER_ID    "gncOwner"
-#define GNC_OWNER_TYPE  "owner-type"
-#define GNC_OWNER_GUID  "owner-guid"
 
 GncOwner * gncOwnerNew (void)
 {
@@ -99,6 +98,36 @@ void gncOwnerBeginEdit (GncOwner *owner)
     }
 }
 
+void gncOwnerCommitEdit (GncOwner *owner)
+{
+    if (!owner) return;
+    switch (owner->type)
+    {
+    case GNC_OWNER_NONE :
+    case GNC_OWNER_UNDEFINED :
+        break;
+    case GNC_OWNER_CUSTOMER :
+    {
+        gncCustomerCommitEdit(owner->owner.customer);
+        break;
+    }
+    case GNC_OWNER_JOB :
+    {
+        gncJobCommitEdit(owner->owner.job);
+        break;
+    }
+    case GNC_OWNER_VENDOR :
+    {
+        gncVendorCommitEdit(owner->owner.vendor);
+        break;
+    }
+    case GNC_OWNER_EMPLOYEE :
+    {
+        gncEmployeeCommitEdit(owner->owner.employee);
+        break;
+    }
+    }
+}
 
 void gncOwnerDestroy (GncOwner *owner)
 {
@@ -567,52 +596,31 @@ const GncGUID * gncOwnerGetEndGUID (const GncOwner *owner)
 
 void gncOwnerAttachToLot (const GncOwner *owner, GNCLot *lot)
 {
-    KvpFrame *kvp;
-    KvpValue *value;
-
-    if (!owner || !lot)
+     if (!owner || !lot)
         return;
 
-    kvp = gnc_lot_get_slots (lot);
     gnc_lot_begin_edit (lot);
 
-    value = kvp_value_new_gint64 (gncOwnerGetType (owner));
-    kvp_frame_set_slot_path (kvp, value, GNC_OWNER_ID, GNC_OWNER_TYPE, NULL);
-    kvp_value_delete (value);
-
-    value = kvp_value_new_guid (gncOwnerGetGUID (owner));
-    kvp_frame_set_slot_path (kvp, value, GNC_OWNER_ID, GNC_OWNER_GUID, NULL);
-    qof_instance_set_dirty (QOF_INSTANCE (lot));
+    qof_instance_set (QOF_INSTANCE (lot),
+		      "owner-type", (gint64)gncOwnerGetType (owner),
+		      "owner-guid", gncOwnerGetGUID (owner),
+		      NULL);
     gnc_lot_commit_edit (lot);
-    kvp_value_delete (value);
-
 }
 
 gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner)
 {
-    KvpFrame *kvp;
-    KvpValue *value;
-    GncGUID *guid;
+    GncGUID *guid = NULL;
     QofBook *book;
-    GncOwnerType type;
+    GncOwnerType type = GNC_OWNER_NONE;
 
     if (!lot || !owner) return FALSE;
 
     book = gnc_lot_get_book (lot);
-    kvp = gnc_lot_get_slots (lot);
-
-    value = kvp_frame_get_slot_path (kvp, GNC_OWNER_ID, GNC_OWNER_TYPE, NULL);
-    if (!value) return FALSE;
-
-    type = kvp_value_get_gint64 (value);
-
-    value = kvp_frame_get_slot_path (kvp, GNC_OWNER_ID, GNC_OWNER_GUID, NULL);
-    if (!value) return FALSE;
-
-    guid = kvp_value_get_guid (value);
-    if (!guid)
-        return FALSE;
-
+    qof_instance_get (QOF_INSTANCE (lot),
+		      "owner-type", &type,
+		      "owner-guid", &guid,
+		      NULL);
     switch (type)
     {
     case GNC_OWNER_CUSTOMER:
@@ -640,23 +648,6 @@ gboolean gncOwnerIsValid (const GncOwner *owner)
     return (owner->owner.undefined != NULL);
 }
 
-KvpFrame* gncOwnerGetSlots(GncOwner* owner)
-{
-    if (!owner) return NULL;
-
-    switch (gncOwnerGetType(owner))
-    {
-    case GNC_OWNER_CUSTOMER:
-    case GNC_OWNER_VENDOR:
-    case GNC_OWNER_EMPLOYEE:
-        return qof_instance_get_slots(QOF_INSTANCE(owner->owner.undefined));
-    case GNC_OWNER_JOB:
-        return gncOwnerGetSlots(gncJobGetOwner(gncOwnerGetJob(owner)));
-    default:
-        return NULL;
-    }
-}
-
 gboolean
 gncOwnerLotMatchOwnerFunc (GNCLot *lot, gpointer user_data)
 {
diff --git a/src/engine/gncOwner.h b/src/engine/gncOwner.h
index ac987bc..0874102 100644
--- a/src/engine/gncOwner.h
+++ b/src/engine/gncOwner.h
@@ -197,9 +197,6 @@ gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner);
 
 gboolean gncOwnerGetOwnerFromTypeGuid (QofBook *book, GncOwner *owner, QofIdType type, GncGUID *guid);
 
-/** Get the kvp-frame from the underlying owner object */
-KvpFrame* gncOwnerGetSlots(GncOwner* owner);
-
 /**
  * Create a lot for a payment to the owner using the other
  * parameters passed in. If a transaction is set, this transaction will be
@@ -307,6 +304,7 @@ void gncOwnerFree (GncOwner *owner);
  * without knowing its type.
  */
 void gncOwnerBeginEdit (GncOwner *owner);
+void gncOwnerCommitEdit (GncOwner *owner);
 void gncOwnerDestroy (GncOwner *owner);
 
 #endif /* GNC_OWNER_H_ */
diff --git a/src/engine/gncTaxTable.c b/src/engine/gncTaxTable.c
index 8650217..2c525f4 100644
--- a/src/engine/gncTaxTable.c
+++ b/src/engine/gncTaxTable.c
@@ -26,9 +26,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
+#include <qofinstance-p.h>
 
 #include "gnc-features.h"
 #include "gncTaxTableP.h"
@@ -208,9 +209,10 @@ gncTaxTableRemoveChild (GncTaxTable *table, const GncTaxTable *child)
 enum
 {
     PROP_0,
-    PROP_NAME,
-    PROP_INVISIBLE,
-    PROP_REFCOUNT
+    PROP_NAME,		/* Table */
+    PROP_INVISIBLE,	/* Table */
+    PROP_REFCOUNT,	/* Table */
+//  PROP_PARENT,	/* Table */
 };
 
 /* GObject Initialization */
@@ -272,6 +274,8 @@ gnc_taxtable_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_TAXTABLE(object));
 
     tt = GNC_TAXTABLE(object);
+    g_assert (qof_instance_get_editlevel(tt));
+
     switch (prop_id)
     {
     case PROP_NAME:
diff --git a/src/engine/gncVendor.c b/src/engine/gncVendor.c
index d416db4..3ebdb2b 100644
--- a/src/engine/gncVendor.c
+++ b/src/engine/gncVendor.c
@@ -26,10 +26,11 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <glib.h>
 #include <string.h>
+#include <qofinstance-p.h>
 
 #include "gnc-commodity.h"
 #include "gncAddressP.h"
@@ -88,17 +89,20 @@ void mark_vendor (GncVendor *vendor)
 enum
 {
     PROP_0,
-    PROP_NAME,
-    PROP_ID,
-    PROP_NOTES,
-    PROP_CURRENCY,
-    PROP_ACTIVE,
-    PROP_TAXTABLE_OVERRIDE,
-    PROP_BILLTERMS,
-    PROP_TAXTABLE,
-    PROP_ADDRESS,
-    PROP_TAX_INCLUDED,
-    PROP_TAX_INCLUDED_STR
+    PROP_NAME,			/* Table */
+    PROP_ID,			/* Table */
+    PROP_NOTES,			/* Table */
+    PROP_CURRENCY,		/* Table */
+    PROP_ACTIVE,		/* Table */
+    PROP_TAXTABLE_OVERRIDE,	/* Table */
+    PROP_BILLTERMS,		/* Table */
+    PROP_TAXTABLE,		/* Table */
+    PROP_ADDRESS,		/* Table, 8 fields */
+    PROP_TAX_INCLUDED,		/* Table */
+    PROP_TAX_INCLUDED_STR,	/* Alternate setter for PROP_TAX_INCLUDED */
+    PROP_PDF_DIRNAME,		/* KVP */
+    PROP_LAST_POSTED,		/* KVP */
+    PROP_PAYMENT_LAST_ACCT,	/* KVP */
 };
 
 /* GObject Initialization */
@@ -134,6 +138,7 @@ gnc_vendor_get_property (GObject         *object,
                          GParamSpec      *pspec)
 {
     GncVendor *vendor;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_VENDOR(object));
 
@@ -173,6 +178,18 @@ gnc_vendor_get_property (GObject         *object,
     case PROP_TAX_INCLUDED_STR:
         g_value_set_string(value, qofVendorGetTaxIncluded(vendor));
         break;
+    case PROP_PDF_DIRNAME:
+	key = OWNER_EXPORT_PDF_DIRNAME;
+	qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
+	break;
+    case PROP_LAST_POSTED:
+	key = LAST_POSTED_TO_ACCT;
+	qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
+	break;
+    case PROP_PAYMENT_LAST_ACCT:
+	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
+	qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -186,10 +203,13 @@ gnc_vendor_set_property (GObject         *object,
                          GParamSpec      *pspec)
 {
     GncVendor *vendor;
+    gchar *key;
 
     g_return_if_fail(GNC_IS_VENDOR(object));
 
     vendor = GNC_VENDOR(object);
+    g_assert (qof_instance_get_editlevel(vendor));
+
     switch (prop_id)
     {
     case PROP_NAME:
@@ -225,6 +245,18 @@ gnc_vendor_set_property (GObject         *object,
     case PROP_TAX_INCLUDED_STR:
         qofVendorSetTaxIncluded(vendor, g_value_get_string(value));
         break;
+    case PROP_PDF_DIRNAME:
+	key = OWNER_EXPORT_PDF_DIRNAME;
+	qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
+	break;
+    case PROP_LAST_POSTED:
+	key = LAST_POSTED_TO_ACCT;
+	qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
+	break;
+    case PROP_PAYMENT_LAST_ACCT:
+	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
+	qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
+	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -390,6 +422,38 @@ gnc_vendor_class_init (GncVendorClass *klass)
                          "The tax-included-string property contains a character version of tax-included.",
                          FALSE,
                          G_PARAM_READWRITE));
+    g_object_class_install_property
+    (gobject_class,
+     PROP_PDF_DIRNAME,
+     g_param_spec_string ("export-pdf-dir",
+                          "Export PDF Directory Name",
+                          "A subdirectory for exporting PDF reports which is "
+			  "appended to the target directory when writing them "
+			  "out. It is retrieved from preferences and stored on "
+			  "each 'Owner' object which prints items after "
+			  "printing.",
+                          NULL,
+                          G_PARAM_READWRITE));
+
+    g_object_class_install_property(
+       gobject_class,
+       PROP_LAST_POSTED,
+       g_param_spec_boxed("invoice-last-posted-account",
+			  "Invoice Last Posted Account",
+			  "The last account to which an invoice belonging to "
+			  "this owner was posted.",
+			  GNC_TYPE_GUID,
+			  G_PARAM_READWRITE));
+
+    g_object_class_install_property(
+       gobject_class,
+       PROP_PAYMENT_LAST_ACCT,
+       g_param_spec_boxed("payment-last-account",
+			  "Payment Last Account",
+			  "The last account to which an payment belonging to "
+			  "this owner was posted.",
+			  GNC_TYPE_GUID,
+			  G_PARAM_READWRITE));
 }
 
 /* Create/Destroy Functions */
diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c
index ad35d9b..77086f0 100644
--- a/src/engine/test-core/test-engine-stuff.c
+++ b/src/engine/test-core/test-engine-stuff.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <qofinstance-p.h>
 
 #include "Account.h"
 #include "AccountP.h"
@@ -1339,7 +1340,7 @@ get_random_split(QofBook *book, Account *acct, Transaction *trn)
     else
         g_assert(!gnc_numeric_positive_p(amt)); /* non-positive amt */
 
-    xaccSplitSetSlots_nc(ret, get_random_kvp_frame());
+    qof_instance_set_slots(QOF_INSTANCE (ret), get_random_kvp_frame());
     xaccTransCommitEdit(trn);
 
     return ret;
@@ -1366,7 +1367,7 @@ make_random_changes_to_split (Split *split)
     xaccSplitSetDateReconciledTS (split, ts);
     g_free(ts);
 
-    xaccSplitSetSlots_nc (split, get_random_kvp_frame());
+    qof_instance_set_slots (QOF_INSTANCE (split), get_random_kvp_frame());
 
     /* Don't change share values/prices here, since that would
      * throw transactions out of balance. Do that in the corresponding
@@ -2169,13 +2170,13 @@ make_trans_query (Transaction *trans, TestQueryTypes query_types)
     }
 
     if (query_types & SPLIT_KVP_QT)
-        add_kvp_query (q, xaccSplitGetSlots (s), GNC_ID_SPLIT);
+        add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (s)), GNC_ID_SPLIT);
 
     if (query_types & TRANS_KVP_QT)
-        add_kvp_query (q, xaccTransGetSlots (trans), GNC_ID_TRANS);
+        add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (trans)), GNC_ID_TRANS);
 
     if (query_types & ACCOUNT_KVP_QT)
-        add_kvp_query (q, xaccAccountGetSlots (a), GNC_ID_ACCOUNT);
+        add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (a)), GNC_ID_ACCOUNT);
 
     return q;
 }
diff --git a/src/engine/test/Makefile.am b/src/engine/test/Makefile.am
index ec7bed0..9e1f098 100644
--- a/src/engine/test/Makefile.am
+++ b/src/engine/test/Makefile.am
@@ -116,6 +116,7 @@ test_engine_SOURCES = \
 	utest-Account.c \
 	utest-Budget.c \
 	utest-Invoice.c \
+	test-engine-kvp-properties.c \
 	dummy.cpp
 
 test_engine_LDADD = \
diff --git a/src/engine/test/test-account-object.c b/src/engine/test/test-account-object.c
index 60765b5..b87bb22 100644
--- a/src/engine/test/test-account-object.c
+++ b/src/engine/test/test-account-object.c
@@ -33,6 +33,7 @@
 #include "cashobjects.h"
 #include "test-stuff.h"
 #include "test-engine-stuff.h"
+#include <qofinstance-p.h>
 
 static void
 run_test (void)
@@ -61,7 +62,9 @@ run_test (void)
     /*****/
 
     five = gnc_numeric_create(5, 1);
+    qof_instance_increase_editlevel (acc);
     g_object_set(acc, "start-balance", &five, NULL);
+    qof_instance_decrease_editlevel (acc);
     xaccAccountRecomputeBalance(acc);
     g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
     end2 = xaccAccountGetBalance(acc);
diff --git a/src/engine/test/test-customer.c b/src/engine/test/test-customer.c
index 02f67df..fe8fb2f 100644
--- a/src/engine/test/test-customer.c
+++ b/src/engine/test/test-customer.c
@@ -24,9 +24,11 @@
  *
  *********************************************************************/
 
-#include "config.h"
+#include <config.h>
 #include <glib.h>
-#include "qof.h"
+#include <qof.h>
+#include <qofinstance-p.h>
+
 #include "cashobjects.h"
 #include "gncCustomerP.h"
 #include "gncInvoiceP.h"
diff --git a/src/engine/test/test-employee.c b/src/engine/test/test-employee.c
index 03bb066..1835bbf 100644
--- a/src/engine/test/test-employee.c
+++ b/src/engine/test/test-employee.c
@@ -24,9 +24,11 @@
  *
  *********************************************************************/
 
-#include "config.h"
+#include <config.h>
 #include <glib.h>
-#include "qof.h"
+#include <qof.h>
+#include <qofinstance-p.h>
+
 #include "gncEmployeeP.h"
 #include "gncCustomerP.h"
 #include "gncJobP.h"
diff --git a/src/engine/test/test-engine-kvp-properties.c b/src/engine/test/test-engine-kvp-properties.c
new file mode 100644
index 0000000..8b95526
--- /dev/null
+++ b/src/engine/test/test-engine-kvp-properties.c
@@ -0,0 +1,458 @@
+/********************************************************************
+ * test-engine-kvp-properties.c: GLib g_test test suite for         *
+ * KVP-based properties in several engine classes.                  *
+ * Copyright 2013 John Ralls <jralls at ceridwen.us>		    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+/**
+ * Test Engine KVP Properties Acceptance testing for KVP Properties
+ * added to various engine classes to make private the internals of
+ * KVP storage used for a variety of parameters on several engine
+ * classes.
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <qof.h>
+#include <unittest-support.h>
+#include "../Transaction.h"
+#include "../Split.h"
+#include "../Account.h"
+#include "../SchedXAction.h"
+#include "../gncCustomer.h"
+#include "../gncEmployee.h"
+#include "../gncJob.h"
+#include "../gncVendor.h"
+
+typedef struct
+{
+    union
+    {
+	Account      *acct;
+	Transaction  *trans;
+	Split        *split;
+	GNCLot       *lot;
+	GncCustomer  *cust;
+	GncEmployee  *emp;
+	GncJob       *job;
+	GncVendor    *vend;
+    };
+    GSList *hdlrs;
+} Fixture;
+
+/* Prototype to shut clang up */
+void test_suite_engine_kvp_properties (void);
+
+/* Private QofInstance functions needed for testing */
+extern void qof_instance_mark_clean (QofInstance*);
+
+const gchar *suitename = "/engine/kvp-properties";
+
+static void
+setup_account (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = qof_book_new ();
+    fixture->acct = xaccMallocAccount (book);
+}
+
+static void
+setup_trans (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = qof_book_new ();
+    fixture->trans = xaccMallocTransaction (book);
+}
+
+static void
+setup_split (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = qof_book_new ();
+    fixture->split = xaccMallocSplit (book);
+}
+
+static void
+setup_lot (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = qof_book_new ();
+    fixture->lot = gnc_lot_new (book);
+}
+
+static void
+setup_customer (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = qof_book_new ();
+    fixture->cust = gncCustomerCreate (book);
+}
+
+static void
+setup_employee (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = qof_book_new ();
+    fixture->emp = gncEmployeeCreate (book);
+}
+
+static void
+setup_job (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = qof_book_new ();
+    fixture->job = gncJobCreate (book);
+}
+
+static void
+setup_vendor (Fixture *fixture, gconstpointer pData)
+{
+    QofBook *book = qof_book_new ();
+    fixture->vend = gncVendorCreate (book);
+}
+
+static void
+teardown (Fixture *fixture, gconstpointer pData)
+{
+/* It doesn't actually matter which union member we use here, they're
+ * all QofInstances, so this will work for any of them.
+ */
+    QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->acct));
+    test_destroy (fixture->acct);
+    test_destroy (book);
+}
+
+static void
+test_account_kvp_properties (Fixture *fixture, gconstpointer pData)
+{
+    gint64 next_id = 12345678909876;
+    gint64 ab_acct_uid = 67890987654321;
+    gint64 next_id_r, ab_acct_uid_r;
+    gchar *online_id = "my online id";
+    gchar *ab_acct_id = "1234-5678-9087";
+    gchar *ab_bank_code = "0032340";
+    gchar *online_id_r, *ab_acct_id_r, *ab_bank_code_r;
+    GncGUID *ofx_income_acct = guid_malloc ();
+    GncGUID *ofx_income_acct_r;
+    Timespec trans_retr = timespec_now ();
+    Timespec *trans_retr_r;
+
+    xaccAccountBeginEdit (fixture->acct);
+    qof_instance_set (QOF_INSTANCE (fixture->acct),
+		      "lot-next-id", next_id,
+		      "online-id", online_id,
+		      "ofx-income-account", ofx_income_acct,
+		      "ab-account-id", ab_acct_id,
+		      "ab-bank-code", ab_bank_code,
+		      "ab-account-uid", ab_acct_uid,
+		      "ab-trans-retrieval", &trans_retr,
+		      NULL);
+
+    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
+    qof_instance_mark_clean (QOF_INSTANCE (fixture->acct));
+
+    qof_instance_get (QOF_INSTANCE (fixture->acct),
+		      "lot-next-id", &next_id_r,
+		      "online-id", &online_id_r,
+		      "ofx-income-account", &ofx_income_acct_r,
+		      "ab-account-id", &ab_acct_id_r,
+		      "ab-bank-code", &ab_bank_code_r,
+		      "ab-account-uid", &ab_acct_uid_r,
+		      "ab-trans-retrieval", &trans_retr_r,
+		      NULL);
+    g_assert_cmpint (next_id, ==, next_id_r);
+    g_assert_cmpstr (online_id, ==, online_id_r);
+    g_assert (guid_equal (ofx_income_acct, ofx_income_acct_r));
+    g_assert_cmpstr (ab_acct_id, ==, ab_acct_id_r);
+    g_assert_cmpstr (ab_bank_code, ==, ab_bank_code_r);
+    g_assert_cmpint (ab_acct_uid, ==, ab_acct_uid_r);
+    g_assert (timespec_equal (&trans_retr, trans_retr_r));
+    g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
+}
+
+static void
+test_trans_kvp_properties (Fixture *fixture, gconstpointer pData)
+{
+    GncGUID *invoice = guid_malloc ();
+    GncGUID *from_sx = guid_malloc ();
+    GncGUID *invoice_r, *from_sx_r;
+    gchar *online_id = "my online id";
+    gchar *online_id_r;
+
+    xaccTransBeginEdit (fixture->trans);
+    qof_instance_set (QOF_INSTANCE (fixture->trans),
+		      "invoice", invoice,
+		      "from-sched-xaction", from_sx,
+		      "online-id", online_id,
+		      NULL);
+
+    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->trans)));
+    qof_instance_mark_clean (QOF_INSTANCE (fixture->trans));
+
+    qof_instance_get (QOF_INSTANCE (fixture->trans),
+		      "invoice", &invoice_r,
+		      "from-sched-xaction", &from_sx_r,
+		      "online-id", &online_id_r,
+		      NULL);
+    g_assert (guid_equal (invoice, invoice_r));
+    g_assert (guid_equal (from_sx, from_sx_r));
+    g_assert_cmpstr (online_id, ==, online_id_r);
+    g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->trans)));
+    guid_free (invoice);
+    guid_free (invoice_r);
+    guid_free (from_sx);
+    guid_free (from_sx_r);
+    g_free (online_id_r);
+}
+
+static void
+test_split_kvp_properties (Fixture *fixture, gconstpointer pData)
+{
+    gchar *debit_formula = "e^xdydx";
+    gchar *credit_formula = "seccostansin";
+    gchar *sx_shares = "43";
+    gchar *online_id = "my_online_id";
+    gchar *debit_formula_r, *credit_formula_r, *sx_shares_r;
+    gchar *online_id_r;
+    GncGUID *sx_account = guid_malloc ();
+    GncGUID *sx_account_r;
+    gnc_numeric debit_numeric = gnc_numeric_create (123, 456);
+    gnc_numeric credit_numeric = gnc_numeric_create (789, 456);
+    gnc_numeric *debit_numeric_r, *credit_numeric_r;
+
+    qof_begin_edit (QOF_INSTANCE (fixture->split));
+    qof_instance_set (QOF_INSTANCE (fixture->split),
+		      "sx-debit-formula", debit_formula,
+		      "sx-debit-numeric", &debit_numeric,
+		      "sx-credit-formula", credit_formula,
+		      "sx-credit-numeric", &credit_numeric,
+		      "sx-account", sx_account,
+		      "sx-shares", sx_shares,
+		      "online-id", online_id,
+		      NULL);
+
+    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->split)));
+    qof_instance_mark_clean (QOF_INSTANCE (fixture->split));
+
+    qof_instance_get (QOF_INSTANCE (fixture->split),
+		      "sx-debit-formula", &debit_formula_r,
+		      "sx-debit-numeric", &debit_numeric_r,
+		      "sx-credit-formula", &credit_formula_r,
+		      "sx-credit-numeric", &credit_numeric_r,
+		      "sx-account", &sx_account_r,
+		      "sx-shares", &sx_shares_r,
+		      "online-id", &online_id_r,
+		      NULL);
+    g_assert_cmpstr (debit_formula, ==, debit_formula_r);
+    g_assert (gnc_numeric_equal (debit_numeric, *debit_numeric_r));
+    g_assert_cmpstr (credit_formula, ==, credit_formula_r);
+    g_assert (gnc_numeric_equal (credit_numeric, *credit_numeric_r));
+    g_assert (guid_equal (sx_account, sx_account_r));
+    g_assert_cmpstr (sx_shares, ==, sx_shares_r);
+    g_assert_cmpstr (online_id, ==, online_id_r);
+    g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->split)));
+    g_free (debit_formula_r);
+    g_free (debit_numeric_r);
+    g_free (credit_formula_r);
+    g_free (credit_numeric_r);
+    qof_begin_edit (QOF_INSTANCE (fixture->split));
+    qof_instance_set (QOF_INSTANCE (fixture->split),
+		      "sx-credit-formula", NULL,
+		      NULL);
+    qof_instance_get (QOF_INSTANCE (fixture->split),
+		      "sx-credit-formula", &credit_numeric_r,
+		      NULL);
+    g_assert (credit_numeric_r == NULL);
+    g_free (sx_shares_r);
+    g_free (online_id_r);
+    guid_free (sx_account);
+    guid_free (sx_account_r);
+}
+
+static void
+test_lot_kvp_properties (Fixture *fixture, gconstpointer pData)
+{
+    GncGUID *invoice = guid_malloc ();
+    GncGUID *invoice_r;
+    gint64 owner_type = 47;
+    gint64 owner_type_r;
+    GncGUID *owner = guid_malloc ();
+    GncGUID *owner_r;
+
+    qof_begin_edit (QOF_INSTANCE (fixture->lot));
+    qof_instance_set (QOF_INSTANCE (fixture->lot),
+		      "invoice", invoice,
+		      "owner-type", owner_type,
+		      "owner-guid", owner,
+		      NULL);
+
+    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->lot)));
+    qof_instance_mark_clean (QOF_INSTANCE (fixture->lot));
+
+    qof_instance_get (QOF_INSTANCE (fixture->lot),
+		      "invoice", &invoice_r,
+		      "owner-type", &owner_type_r,
+		      "owner-guid", &owner_r,
+		      NULL);
+    g_assert (guid_equal (invoice, invoice_r));
+    g_assert_cmpint (owner_type, ==, owner_type_r);
+    g_assert (guid_equal (owner, owner_r));
+    g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->lot)));
+    guid_free (invoice);
+    guid_free (invoice_r);
+    guid_free (owner);
+    guid_free (owner_r);
+}
+
+static void
+test_customer_kvp_properties (Fixture *fixture, gconstpointer pData)
+{
+    gchar *pdf_dir = "/foo/bar/baz";
+    gchar *pdf_dir_r;
+    GncGUID *inv_acct = guid_malloc ();
+    GncGUID *pmt_acct = guid_malloc ();
+    GncGUID *inv_acct_r, *pmt_acct_r;
+
+    qof_begin_edit (QOF_INSTANCE (fixture->cust));
+    qof_instance_set (QOF_INSTANCE (fixture->cust),
+		      "export-pdf-dir", pdf_dir,
+		      "invoice-last-posted-account", inv_acct,
+		      "payment-last-account", pmt_acct,
+		      NULL);
+
+    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->cust)));
+    qof_instance_mark_clean (QOF_INSTANCE (fixture->cust));
+
+    qof_instance_get (QOF_INSTANCE (fixture->cust),
+		      "export-pdf-dir", &pdf_dir_r,
+		      "invoice-last-posted-account", &inv_acct_r,
+		      "payment-last-account", &pmt_acct_r,
+		      NULL);
+
+    g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
+    g_assert (guid_equal (inv_acct, inv_acct_r));
+    g_assert (guid_equal (pmt_acct, pmt_acct_r));
+    guid_free (inv_acct);
+    guid_free (inv_acct_r);
+    guid_free (pmt_acct);
+    guid_free (pmt_acct_r);
+    g_free (pdf_dir_r);
+
+}
+
+static void
+test_employee_kvp_properties (Fixture *fixture, gconstpointer pData)
+{
+    gchar *pdf_dir = "/foo/bar/baz";
+    gchar *pdf_dir_r;
+    GncGUID *inv_acct = guid_malloc ();
+    GncGUID *pmt_acct = guid_malloc ();
+    GncGUID *inv_acct_r, *pmt_acct_r;
+
+    qof_begin_edit (QOF_INSTANCE (fixture->emp));
+    qof_instance_set (QOF_INSTANCE (fixture->emp),
+		      "export-pdf-dir", pdf_dir,
+		      "invoice-last-posted-account", inv_acct,
+		      "payment-last-account", pmt_acct,
+		      NULL);
+
+    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->emp)));
+    qof_instance_mark_clean (QOF_INSTANCE (fixture->emp));
+
+    qof_instance_get (QOF_INSTANCE (fixture->emp),
+		      "export-pdf-dir", &pdf_dir_r,
+		      "invoice-last-posted-account", &inv_acct_r,
+		      "payment-last-account", &pmt_acct_r,
+		      NULL);
+
+    g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
+    g_assert (guid_equal (inv_acct, inv_acct_r));
+    g_assert (guid_equal (pmt_acct, pmt_acct_r));
+    guid_free (inv_acct);
+    guid_free (inv_acct_r);
+    guid_free (pmt_acct);
+    guid_free (pmt_acct_r);
+    g_free (pdf_dir_r);
+
+}
+
+static void
+test_job_kvp_properties (Fixture *fixture, gconstpointer pData)
+{
+    gchar *pdf_dir = "/foo/bar/baz";
+    gchar *pdf_dir_r;
+
+    qof_begin_edit (QOF_INSTANCE (fixture->job));
+    qof_instance_set (QOF_INSTANCE (fixture->job),
+		      "export-pdf-dir", pdf_dir,
+		      NULL);
+
+    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->job)));
+    qof_instance_mark_clean (QOF_INSTANCE (fixture->job));
+
+    qof_instance_get (QOF_INSTANCE (fixture->job),
+		      "export-pdf-dir", &pdf_dir_r,
+		      NULL);
+
+    g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
+    g_free (pdf_dir_r);
+
+}
+
+static void
+test_vendor_kvp_properties (Fixture *fixture, gconstpointer pData)
+{
+    gchar *pdf_dir = "/foo/bar/baz";
+    gchar *pdf_dir_r;
+    GncGUID *inv_acct = guid_malloc ();
+    GncGUID *pmt_acct = guid_malloc ();
+    GncGUID *inv_acct_r, *pmt_acct_r;
+
+    qof_begin_edit (QOF_INSTANCE (fixture->vend));
+    qof_instance_set (QOF_INSTANCE (fixture->vend),
+		      "export-pdf-dir", pdf_dir,
+		      "invoice-last-posted-account", inv_acct,
+		      "payment-last-account", pmt_acct,
+		      NULL);
+
+    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->vend)));
+    qof_instance_mark_clean (QOF_INSTANCE (fixture->vend));
+
+    qof_instance_get (QOF_INSTANCE (fixture->vend),
+		      "export-pdf-dir", &pdf_dir_r,
+		      "invoice-last-posted-account", &inv_acct_r,
+		      "payment-last-account", &pmt_acct_r,
+		      NULL);
+
+    g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
+    g_assert (guid_equal (inv_acct, inv_acct_r));
+    g_assert (guid_equal (pmt_acct, pmt_acct_r));
+    guid_free (inv_acct);
+    guid_free (inv_acct_r);
+    guid_free (pmt_acct);
+    guid_free (pmt_acct_r);
+    g_free (pdf_dir_r);
+
+}
+
+void test_suite_engine_kvp_properties (void)
+{
+    GNC_TEST_ADD (suitename, "Account", Fixture, NULL, setup_account, test_account_kvp_properties, teardown);
+    GNC_TEST_ADD (suitename, "Transaction", Fixture, NULL, setup_trans, test_trans_kvp_properties, teardown);
+    GNC_TEST_ADD (suitename, "Split", Fixture, NULL, setup_split, test_split_kvp_properties, teardown);
+    GNC_TEST_ADD (suitename, "Lot", Fixture, NULL, setup_lot, test_lot_kvp_properties, teardown);
+    GNC_TEST_ADD (suitename, "Customer", Fixture, NULL, setup_customer, test_customer_kvp_properties, teardown);
+    GNC_TEST_ADD (suitename, "Employee", Fixture, NULL, setup_employee, test_employee_kvp_properties, teardown);
+    GNC_TEST_ADD (suitename, "Job", Fixture, NULL, setup_job, test_job_kvp_properties, teardown);
+    GNC_TEST_ADD (suitename, "Vendor", Fixture, NULL, setup_vendor, test_vendor_kvp_properties, teardown);
+}
diff --git a/src/engine/test/test-engine.c b/src/engine/test/test-engine.c
index 508856e..19221b8 100644
--- a/src/engine/test/test-engine.c
+++ b/src/engine/test/test-engine.c
@@ -31,6 +31,7 @@ extern void test_suite_budget();
 extern void test_suite_gncInvoice();
 extern void test_suite_transaction();
 extern void test_suite_split();
+extern void test_suite_engine_kvp_properties (void);
 
 int
 main (int   argc,
@@ -49,6 +50,7 @@ main (int   argc,
     test_suite_gncInvoice();
     test_suite_transaction();
     test_suite_split();
+    test_suite_engine_kvp_properties ();
 
     return g_test_run( );
 }
diff --git a/src/engine/test/test-job.c b/src/engine/test/test-job.c
index b90950a..9791b4f 100644
--- a/src/engine/test/test-job.c
+++ b/src/engine/test/test-job.c
@@ -24,9 +24,11 @@
  *
  *********************************************************************/
 
-#include "config.h"
+#include <config.h>
 #include <glib.h>
-#include "qof.h"
+#include <qof.h>
+#include <qofinstance-p.h>
+
 #include "gncJobP.h"
 #include "gncInvoiceP.h"
 #include "gncCustomerP.h"
diff --git a/src/engine/test/test-vendor.c b/src/engine/test/test-vendor.c
index 65adf3e..c36ff72 100644
--- a/src/engine/test/test-vendor.c
+++ b/src/engine/test/test-vendor.c
@@ -24,8 +24,10 @@
  *
  *********************************************************************/
 
-#include "config.h"
+#include <config.h>
 #include <glib.h>
+#include <qofinstance-p.h>
+
 #include "gncInvoiceP.h"
 #include "gncCustomerP.h"
 #include "gncJobP.h"
diff --git a/src/engine/test/utest-Account.c b/src/engine/test/utest-Account.c
index 2a8fe33..f96abf3 100644
--- a/src/engine/test/utest-Account.c
+++ b/src/engine/test/utest-Account.c
@@ -25,6 +25,7 @@
 #include <unittest-support.h>
 #include <gnc-event.h>
 #include <gnc-gdate-utils.h>
+#include <qofinstance-p.h>
 /* Add specific headers for this class */
 #include "../Account.h"
 #include "../AccountP.h"
@@ -444,11 +445,11 @@ test_gnc_account_name_violations_errmsg ()
     message = gnc_account_name_violations_errmsg (separator, nonames);
     g_assert (message == NULL);
     validation_message = g_strdup_printf (
-                             "The separator character \"%s\" is used in one or more account "
-                             "names.\n\nThis will result in unexpected behaviour. "
-                             "Either change the account names or choose another separator "
-                             "character.\n\nBelow you will find the list of invalid account names:\n"
-                             "%s", separator, account_list);
+        "The separator character \"%s\" is used in one or more account "
+        "names.\n\nThis will result in unexpected behaviour. "
+        "Either change the account names or choose another separator "
+        "character.\n\nBelow you will find the list of invalid account names:\n"
+        "%s", separator, account_list);
     message = gnc_account_name_violations_errmsg (separator, badnames);
     g_assert_cmpstr ( message, == , validation_message);
     g_free (validation_message);
@@ -1356,6 +1357,8 @@ test_xaccAccountOrder ( )
     g_assert (xaccAccountOrder (ab, aa) == 1);
 
     ab = xaccMallocAccount (book);
+    qof_instance_increase_editlevel (aa);
+    qof_instance_increase_editlevel (ab);
     g_object_set (G_OBJECT (aa),
                   "code", "3333",
                   "type", ACCT_TYPE_ASSET,
@@ -1398,6 +1401,8 @@ test_xaccAccountOrder ( )
                   "name", "bar",
                   NULL);
     g_assert_cmpint (xaccAccountOrder (aa, ab), < , 0);
+    qof_instance_decrease_editlevel (aa);
+    qof_instance_decrease_editlevel (ab);
 
     xaccAccountBeginEdit (aa);
     xaccAccountDestroy (aa);
@@ -2157,7 +2162,9 @@ test_xaccAccountType_Stuff (void)
             g_assert_cmpstr (typestr_uc, == , typename);
         g_free (typestr_uc);
 
+	qof_instance_increase_editlevel (acc);
         g_object_set (acc, "type", type, NULL);
+	qof_instance_decrease_editlevel (acc);
         if (type == ACCT_TYPE_STOCK || type == ACCT_TYPE_MUTUAL ||
                 type == ACCT_TYPE_CURRENCY)
             g_assert (xaccAccountIsPriced (acc));
@@ -2401,11 +2408,13 @@ test_gnc_account_merge_children (Fixture *fixture, gconstpointer pData)
     */
     sig4 = test_signal_new (QOF_INSTANCE (div), QOF_EVENT_MODIFY, NULL);
     sig5 = test_signal_new (QOF_INSTANCE (div1), QOF_EVENT_MODIFY, NULL);
+    qof_instance_increase_editlevel (div1);
     g_object_set (div1, "name", "div", NULL);
+    qof_instance_decrease_editlevel (div1);
     gnc_account_merge_children (taxable);
     g_assert_cmpint (gnc_account_n_descendants (taxable), == , taxable_desc - 1);
     test_signal_assert_hits (sig4, 1);
-    test_signal_assert_hits (sig5, 4);
+    test_signal_assert_hits (sig5, 3);
     test_signal_free (sig4);
     test_signal_free (sig5);
     gnc_account_merge_children (expense);
diff --git a/src/engine/test/utest-Split.cpp b/src/engine/test/utest-Split.cpp
index 17f062c..e4165e5 100644
--- a/src/engine/test/utest-Split.cpp
+++ b/src/engine/test/utest-Split.cpp
@@ -38,7 +38,7 @@ extern "C"
 #include <TransactionP.h>
 #include <gnc-lot.h>
 #include <gnc-event.h>
-#include <qofbookslots.h>
+#include <qofinstance-p.h>
 
 #ifdef HAVE_GLIB_2_38
 #define _Q "'"
@@ -318,15 +318,15 @@ test_xaccDupeSplit (Fixture *fixture, gconstpointer pData)
     g_assert (split->gains_split != f_split->gains_split);
 
 }
-/* xaccSplitClone
+/* xaccSplitCloneNoKvp
 Split *
-xaccSplitClone (const Split *s)// C: 1
+xaccSplitCloneNoKvp (const Split *s)// C: 1 
 */
 static void
-test_xaccSplitClone (Fixture *fixture, gconstpointer pData)
+test_xaccSplitCloneNoKvp (Fixture *fixture, gconstpointer pData)
 {
     Split *f_split = fixture->split;
-    Split *split = xaccSplitClone (f_split);
+    Split *split = xaccSplitCloneNoKvp (f_split);
 
     g_assert (split != fixture->split);
     g_assert (qof_instance_get_guid (split) != qof_instance_get_guid (f_split));
@@ -339,7 +339,7 @@ test_xaccSplitClone (Fixture *fixture, gconstpointer pData)
     g_assert (split->lot == f_split->lot);
     g_assert_cmpstr (split->memo, ==, f_split->memo);
     g_assert_cmpstr (split->action, ==, f_split->action);
-    g_assert (kvp_frame_compare (split->inst.kvp_data, f_split->inst.kvp_data) == 0);
+    g_assert (kvp_frame_is_empty (split->inst.kvp_data));
     g_assert_cmpint (split->reconciled, ==, f_split->reconciled);
     g_assert (timespec_equal (&(split->date_reconciled), &(f_split->date_reconciled)));
     g_assert (gnc_numeric_equal (split->value, f_split->value));
@@ -417,7 +417,7 @@ xaccSplitEqual(const Split *sa, const Split *sb,// C: 2 in 2 SCM: 1
 static void
 test_xaccSplitEqual (Fixture *fixture, gconstpointer pData)
 {
-    Split *split1 = xaccSplitClone (fixture->split);
+    Split *split1 = xaccSplitCloneNoKvp (fixture->split);
     Split *split2 = xaccDupeSplit (fixture->split);
     gchar *msg01 = "[xaccSplitEqual] one is NULL";
     gchar *msg02 = "[xaccSplitEqual] GUIDs differ";
@@ -468,9 +468,11 @@ test_xaccSplitEqual (Fixture *fixture, gconstpointer pData)
     split1->parent = fixture->split->parent;
     g_assert (xaccSplitEqual (fixture->split, split1, FALSE, TRUE, TRUE) == TRUE);
     /* Now set the GUIDs equal and see that the comparison passes */
+    qof_instance_increase_editlevel (split1->parent);
     g_object_set (G_OBJECT (split1),
                   "guid", qof_instance_get_guid (QOF_INSTANCE(fixture->split)),
                   NULL);
+    qof_instance_increase_editlevel (split1->parent);
     g_assert (xaccSplitEqual (fixture->split, split1, TRUE, TRUE, TRUE) == TRUE);
     g_assert_cmpint (checkA.hits, ==, 3);
     g_assert_cmpint (checkB.hits, ==, 1);
@@ -607,10 +609,12 @@ test_xaccSplitCommitEdit (Fixture *fixture, gconstpointer pData)
     g_assert_cmpint (checkB.hits, ==, 2);
 
     qof_instance_mark_clean (QOF_INSTANCE (fixture->split->parent));
+    qof_instance_increase_editlevel (fixture->split->acc);
     g_object_set (fixture->split->acc,
                   "sort-dirty", FALSE,
                   "balance-dirty", FALSE,
                   NULL);
+    qof_instance_decrease_editlevel (fixture->split->acc);
 
     qof_instance_set_dirty (QOF_INSTANCE (fixture->split));
     xaccSplitCommitEdit (fixture->split);
@@ -780,16 +784,6 @@ test_get_commodity_denom (Fixture *fixture, gconstpointer pData)
     fixture->split->acc = acc;
     g_assert_cmpint (fixture->func->get_commodity_denom (fixture->split), ==, denom);
 }
-/* xaccSplitGetSlots
-KvpFrame *
-xaccSplitGetSlots (const Split * s)// C: 17 in 8
-Simple passthrough, no test.
-*/
-// Not Used
-/* xaccSplitSetSlots_nc
-void
-xaccSplitSetSlots_nc(Split *s, KvpFrame *frm)//
-*/
 /* xaccSplitSetSharePriceAndAmount
 void
 xaccSplitSetSharePriceAndAmount (Split *s, gnc_numeric price, gnc_numeric amt)// C: 1
@@ -1115,8 +1109,9 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
 {
     const char *slot_path;
     Split *split = fixture->split;
-    Split *o_split = xaccMallocSplit (xaccSplitGetBook (split));
-    Transaction *o_txn = xaccMallocTransaction (xaccSplitGetBook (split));
+    QofBook *book = xaccSplitGetBook (split);
+    Split *o_split = xaccMallocSplit (book);
+    Transaction *o_txn = xaccMallocTransaction (book);
     Transaction *txn = split->parent;
 
     g_assert_cmpint (xaccSplitOrder (split, split), ==, 0);
@@ -1155,11 +1150,12 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
      */
 
     /* create correct slot path */
-    slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/",
-                                            OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_NUM_FIELD_SOURCE, NULL );
-    g_assert( slot_path != NULL );
     g_test_message( "Testing with use-split-action-for-num set to true - t" );
-    qof_book_set_string_option( xaccSplitGetBook (split), slot_path, "t" );
+    qof_book_begin_edit (book);
+    qof_instance_set (QOF_INSTANCE (book),
+		      "split-action-num-field", "t",
+		      NULL);
+    qof_book_commit_edit (book);
     g_assert(qof_book_use_split_action_for_num_field(xaccSplitGetBook(split)) == TRUE);
 
     g_assert_cmpint (xaccSplitOrder (split, o_split), ==, -1);
@@ -1171,7 +1167,11 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
     o_split->action = NULL;
     split->action = "foo";
     o_split->parent = NULL;
-    qof_book_set_string_option( xaccSplitGetBook (split), slot_path, "f" );
+    qof_book_begin_edit (book);
+    qof_instance_set (QOF_INSTANCE (book),
+		      "split-action-num-field", "f",
+		      NULL);
+    qof_book_commit_edit (book);
     g_assert(qof_book_use_split_action_for_num_field(xaccSplitGetBook(split)) == FALSE);
     split->parent = NULL;
     /* This should return > 0 because o_split has no memo string */
@@ -1772,7 +1772,6 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
     Split *split2 = xaccMallocSplit (book);
     Account *acc2 = xaccMallocAccount (book);
     KvpValue *kvptrue = kvp_value_new_string ("t");
-    KvpFrame *book_slots = qof_book_get_slots (book);
 
     g_assert (xaccSplitGetOtherSplit (NULL) == NULL);
     g_assert (xaccSplitGetOtherSplit (split1) == NULL);
@@ -1801,9 +1800,11 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
     g_assert (kvp_frame_get_slot (split->inst.kvp_data, "lot-split") == NULL);
     kvp_frame_set_slot (split1->inst.kvp_data, "lot-split", NULL);
     g_assert (kvp_frame_get_slot (split1->inst.kvp_data, "lot-split") == NULL);
-    kvp_frame_set_slot_path (book_slots, kvptrue, KVP_OPTION_PATH,
-                             OPTION_SECTION_ACCOUNTS,
-                             OPTION_NAME_TRADING_ACCOUNTS, NULL);
+    qof_book_begin_edit (book);
+    qof_instance_set (QOF_INSTANCE (book),
+		      "trading-accts", "t",
+		      NULL);
+    qof_book_commit_edit (book);
     g_assert (xaccTransUseTradingAccounts (txn));
     g_assert (xaccSplitGetOtherSplit (split) == NULL);
     split2->acc = acc2;
@@ -1882,7 +1883,7 @@ test_suite_split (void)
     GNC_TEST_ADD_FUNC (suitename, "gnc split set & get property", test_gnc_split_set_get_property);
     GNC_TEST_ADD (suitename, "xaccMallocSplit", Fixture, NULL, setup, test_xaccMallocSplit, teardown);
     GNC_TEST_ADD (suitename, "xaccDupeSplit", Fixture, NULL, setup, test_xaccDupeSplit, teardown);
-    GNC_TEST_ADD (suitename, "xaccSplitClone", Fixture, NULL, setup, test_xaccSplitClone, teardown);
+    GNC_TEST_ADD (suitename, "xaccSplitCloneNoKvp", Fixture, NULL, setup, test_xaccSplitCloneNoKvp, teardown);
     GNC_TEST_ADD (suitename, "mark split", Fixture, NULL, setup, test_mark_split, teardown);
     GNC_TEST_ADD (suitename, "xaccSplitEqualCheckBal", Fixture, NULL, setup, test_xaccSplitEqualCheckBal, teardown);
     GNC_TEST_ADD (suitename, "xaccSplitEqual", Fixture, NULL, setup, test_xaccSplitEqual, teardown);
diff --git a/src/engine/test/utest-Transaction.c b/src/engine/test/utest-Transaction.c
index 35330a4..c2a963f 100644
--- a/src/engine/test/utest-Transaction.c
+++ b/src/engine/test/utest-Transaction.c
@@ -1,5 +1,5 @@
 /********************************************************************
- * utest-Transaction.c: GLib g_test test suite for Transaction.c.		    *
+ * utest-Transaction.c: GLib g_test test suite for Transaction.c.   *
  * Copyright 2012 John Ralls <jralls at ceridwen.us>		    *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
@@ -33,7 +33,6 @@
 #include "../gnc-lot.h"
 #include "../gnc-event.h"
 #include <qof.h>
-#include <qofbookslots.h>
 #include <qofbackend-p.h>
 
 #ifdef HAVE_GLIB_2_38
@@ -569,12 +568,12 @@ test_xaccTransSortSplits (Fixture *fixture, gconstpointer pData)
 
     xaccTransCommitEdit (txn);
 }
-/* xaccDupeTransaction
-Transaction *
-xaccDupeTransaction (const Transaction *from)// Local: 1:0:0
+/* dupe_trans
+static Transaction *
+dupe_trans (const Transaction *from)// Local: 1:0:0
 */
 static void
-test_xaccDupeTransaction (Fixture *fixture, gconstpointer pData)
+test_dupe_trans (Fixture *fixture, gconstpointer pData)
 {
     Timespec posted = gnc_dmy2timespec (12, 7, 2011);
     Timespec entered = gnc_dmy2timespec (14, 7, 2011);
@@ -587,7 +586,7 @@ test_xaccDupeTransaction (Fixture *fixture, gconstpointer pData)
     kvp_frame_set_string (old->inst.kvp_data, "/foo/bar/baz",
                           "The Great Waldo Pepper");
 
-    new = xaccDupeTransaction (old);
+    new = fixture->func->dupe_trans (old);
 
     g_assert_cmpstr (new->num, ==, old->num);
     g_assert_cmpstr (new->description, ==, old->description);
@@ -1048,14 +1047,14 @@ test_xaccTransGetImbalance_trading (Fixture *fixture,
     Account *acc1 = xaccMallocAccount (book);
     Account *acc2 = xaccMallocAccount (book);
     gnc_numeric value;
-    gchar *trading_account_path = g_strdup_printf("%s/%s/%s", KVP_OPTION_PATH,
-                                  OPTION_SECTION_ACCOUNTS,
-                                  OPTION_NAME_TRADING_ACCOUNTS);
     MonetaryList *mlist;
+    qof_book_begin_edit (book);
+    qof_instance_set (QOF_INSTANCE (book),
+		      "trading-accts", "t",
+		      NULL);
+    qof_book_commit_edit (book);
 
-    qof_book_set_string_option( book, trading_account_path, "t" );
-    g_free (trading_account_path);
-    /* Without trading splits, the list is unbalanced */
+ /* Without trading splits, the list is unbalanced */
     mlist = xaccTransGetImbalance (fixture->txn);
     g_assert_cmpint (g_list_length (mlist), ==, 2);
     gnc_monetary_list_free (mlist);
@@ -1135,12 +1134,13 @@ test_xaccTransIsBalanced_trading (Fixture *fixture, gconstpointer pData)
     Split *split2 = xaccMallocSplit (book);
     Account *acc1 = xaccMallocAccount (book);
     Account *acc2 = xaccMallocAccount (book);
-    gchar *trading_account_path = g_strdup_printf("%s/%s/%s", KVP_OPTION_PATH,
-                                  OPTION_SECTION_ACCOUNTS,
-                                  OPTION_NAME_TRADING_ACCOUNTS);
 
-    qof_book_set_string_option( book, trading_account_path, "t" );
-    g_free (trading_account_path);
+    qof_book_begin_edit (book);
+    qof_instance_set (QOF_INSTANCE (book),
+		      "trading-accts", "t",
+		      NULL);
+    qof_book_commit_edit (book);
+
     xaccAccountSetCommodity (acc1, fixture->curr);
     xaccAccountSetCommodity (acc2, fixture->comm);
     xaccAccountSetType (acc1, ACCT_TYPE_TRADING);
@@ -1398,29 +1398,27 @@ void
 xaccTransDestroy (Transaction *trans)// C: 26 in 15 SCM: 4 in 4 Local: 3:0:0
 */
 static void
-test_xaccTransDestroy ()
+test_xaccTransDestroy (Fixture *fixture, gconstpointer pData)
 {
-    QofBook *book = qof_book_new ();
-    Transaction *txn = xaccMallocTransaction (book);
-    Transaction *dupe = xaccDupeTransaction (txn);
+    Transaction *txn = fixture->txn;
+    QofBook *book = qof_instance_get_book (QOF_INSTANCE (txn));
+    Transaction *dupe = xaccTransClone (txn);
 
     xaccTransBeginEdit (txn);
     g_assert (!qof_instance_get_destroying (QOF_INSTANCE (txn)));
-    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
+    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
     xaccTransDestroy (txn);
     g_assert (qof_instance_get_destroying (QOF_INSTANCE (txn)));
-    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
+    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
     xaccTransRollbackEdit (txn);
     qof_book_mark_readonly (book);
     xaccTransBeginEdit (txn);
     xaccTransDestroy (txn);
     g_assert (qof_instance_get_destroying (QOF_INSTANCE (txn)));
-    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
+    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
     xaccTransRollbackEdit (txn);
 
-    test_destroy (txn);
     test_destroy (dupe);
-    test_destroy (book);
 }
 /* destroy_gains
 static void
@@ -1645,10 +1643,6 @@ test_xaccTransCommitEdit (void)
         xaccTransSetCurrency (txn, curr);
         xaccSplitSetParent (split1, txn);
         xaccSplitSetParent (split2, txn);
-        /* xaccTransCommitEdit doesn't do anything with kvp
-        kvp_frame_set_double (frame, "/qux/quux/corge", 123.456);
-         qof_instance_set_slots (QOF_INSTANCE (txn), frame);
-         */
     }
     /* Setup's done, now test: */
     xaccTransCommitEdit (txn);
@@ -1790,7 +1784,7 @@ static void
 test_xaccTransOrder_num_action (Fixture *fixture, gconstpointer pData)
 {
     Transaction *txnA = fixture->txn;
-    Transaction *txnB = xaccDupeTransaction (txnA);
+    Transaction *txnB = fixture->func->dupe_trans (txnA);
 
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, NULL, NULL), ==, -1);
     g_assert_cmpint (xaccTransOrder_num_action (NULL, NULL, txnA, NULL), ==, 1);
@@ -2042,7 +2036,7 @@ test_suite_transaction (void)
     GNC_TEST_ADD (suitename, "gnc transaction set/get property", Fixture, NULL, setup, test_gnc_transaction_set_get_property, teardown);
     GNC_TEST_ADD (suitename, "xaccMallocTransaction", Fixture, NULL, setup, test_xaccMallocTransaction, teardown);
     GNC_TEST_ADD (suitename, "xaccTransSortSplits", Fixture, NULL, setup, test_xaccTransSortSplits, teardown);
-    GNC_TEST_ADD (suitename, "xaccDupeTransaction", Fixture, NULL, setup, test_xaccDupeTransaction, teardown);
+    GNC_TEST_ADD (suitename, "dupe_trans", Fixture, NULL, setup, test_dupe_trans, teardown);
     GNC_TEST_ADD (suitename, "xaccTransClone", Fixture, NULL, setup, test_xaccTransClone, teardown);
     GNC_TEST_ADD (suitename, "xaccTransCopyFromClipBoard", Fixture, NULL, setup, test_xaccTransCopyFromClipBoard, teardown);
     GNC_TEST_ADD (suitename, "xaccTransCopyFromClipBoard No-Start", Fixture, NULL, setup, test_xaccTransCopyFromClipBoard_no_start, teardown);
@@ -2063,7 +2057,7 @@ test_suite_transaction (void)
 
     GNC_TEST_ADD (suitename, "xaccTransSetCurrency", Fixture, NULL, setup, test_xaccTransSetCurrency, teardown);
     GNC_TEST_ADD_FUNC (suitename, "xaccTransBeginEdit", test_xaccTransBeginEdit);
-    GNC_TEST_ADD_FUNC (suitename, "xaccTransDestroy", test_xaccTransDestroy);
+    GNC_TEST_ADD (suitename, "xaccTransDestroy", Fixture, NULL, setup, test_xaccTransDestroy, teardown);
     GNC_TEST_ADD (suitename, "destroy gains", GainsFixture, NULL, setup_with_gains, test_destroy_gains, teardown_with_gains);
     GNC_TEST_ADD (suitename, "do destroy", GainsFixture, NULL, setup_with_gains, test_do_destroy, teardown_with_gains);
     GNC_TEST_ADD (suitename, "was trans emptied", Fixture, NULL, setup, test_was_trans_emptied, teardown);
diff --git a/src/gnome-utils/dialog-preferences.c b/src/gnome-utils/dialog-preferences.c
index 53f2e94..4e371be 100644
--- a/src/gnome-utils/dialog-preferences.c
+++ b/src/gnome-utils/dialog-preferences.c
@@ -1054,7 +1054,7 @@ gnc_preferences_dialog_create(void)
     GtkWidget *dialog, *notebook, *label, *image;
     GtkWidget *box, *date, *period, *currency;
     GHashTable *prefs_table;
-    GDate* gdate;
+    GDate* gdate = NULL;
     gchar buf[128];
     GtkListStore *store;
     GtkTreePath *path;
@@ -1120,16 +1120,10 @@ gnc_preferences_dialog_create(void)
 
 
     book = gnc_get_current_book();
-    book_frame = qof_book_get_slots(book);
-    month = kvp_frame_get_gint64(book_frame, "/book/fyear_end/month");
-    day = kvp_frame_get_gint64(book_frame, "/book/fyear_end/day");
-    date_is_valid = g_date_valid_dmy(day, month, 2005 /* not leap year */);
-    if (date_is_valid)
-    {
-        g_date_clear(&fy_end, 1);
-        g_date_set_dmy(&fy_end, day, month, G_DATE_BAD_YEAR);
-    }
-
+    g_date_clear (&fy_end, 1);
+    qof_instance_get (QOF_INSTANCE (book),
+		      "fy-end", &fy_end,
+		      NULL);
     box = GTK_WIDGET(gtk_builder_get_object (builder,
                      "pref/" GNC_PREFS_GROUP_ACCT_SUMMARY "/" GNC_PREF_START_PERIOD));
     period = gnc_period_select_new(TRUE);
diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c
index 4ab4257..923c877 100644
--- a/src/gnome-utils/gnc-main-window.c
+++ b/src/gnome-utils/gnc-main-window.c
@@ -3973,20 +3973,21 @@ gnc_book_options_dialog_apply_cb(GNCOptionWin * optionwin,
                                  gpointer user_data)
 {
     GNCOptionDB * options = user_data;
-    kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
     gboolean use_split_action_for_num_before =
         qof_book_use_split_action_for_num_field (gnc_get_current_book ());
     gboolean use_split_action_for_num_after;
+    QofBook *book = gnc_get_current_book ();
 
     if (!options) return;
 
     gnc_option_db_commit (options);
-    gnc_option_db_save_to_kvp (options, slots, TRUE);
-    qof_book_kvp_changed (gnc_get_current_book());
+    qof_book_begin_edit (book);
+    qof_book_save_options (book, gnc_option_db_save_to_kvp, options, TRUE);
     use_split_action_for_num_after =
         qof_book_use_split_action_for_num_field (gnc_get_current_book ());
     if (use_split_action_for_num_before != use_split_action_for_num_after)
         gnc_book_option_num_field_source_change_cb (use_split_action_for_num_after);
+    qof_book_commit_edit (book);
 }
 
 static void
@@ -4002,12 +4003,12 @@ gnc_book_options_dialog_close_cb(GNCOptionWin * optionwin,
 GtkWidget *
 gnc_book_options_dialog_cb (gboolean modal, gchar *title)
 {
-    kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
+    QofBook *book = gnc_get_current_book ();
     GNCOptionDB *options;
     GNCOptionWin *optionwin;
 
     options = gnc_option_db_new_for_type (QOF_ID_BOOK);
-    gnc_option_db_load_from_kvp (options, slots);
+    qof_book_load_options (book, gnc_option_db_load_from_kvp, options);
     gnc_option_db_clean (options);
 
     optionwin = gnc_options_dialog_new_modal (modal,
diff --git a/src/gnome-utils/gnc-tree-util-split-reg.c b/src/gnome-utils/gnc-tree-util-split-reg.c
index 88c4ee3..d6e5747 100644
--- a/src/gnome-utils/gnc-tree-util-split-reg.c
+++ b/src/gnome-utils/gnc-tree-util-split-reg.c
@@ -397,30 +397,20 @@ const char *
 gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
 {
     static char *name = NULL;
+    Account *account;
+    GncGUID *guid = NULL;
 
-    kvp_frame *kvpf;
+    /* Callers either g_strdup the return or use it as a temp for comparison,
+       so we keep our static ref and free it on every call. */
+    g_free (name);
 
     if (!split)
         return NULL;
-
-    kvpf = xaccSplitGetSlots (split);
-
-    g_free (name);
-
-    if (kvpf)
-    {
-        Account *account;
-        GncGUID *guid;
-
-        guid = kvp_value_get_guid(
-                   kvp_frame_get_slot_path (kvpf, "sched-xaction", "account", NULL));
-
-        account = xaccAccountLookup (guid, gnc_get_current_book ());
-
-        name = account ? gnc_get_account_name_for_register (account) : NULL;
-    }
-    else
-        name = NULL;
+    qof_instance_get (QOF_INSTANCE (split),
+		      "sx-account", &guid,
+		      NULL);
+    account = xaccAccountLookup (guid, gnc_get_current_book ());
+    name = account ? gnc_get_account_name_for_register (account) : NULL;
 
     return name;
 }
@@ -429,20 +419,27 @@ gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
 const char *
 gnc_tree_util_split_reg_template_get_fdebt_entry (Split *split)
 {
-    kvp_frame *kvpf = xaccSplitGetSlots (split);
+    gchar *formula = NULL;
 
-    return kvp_value_get_string(
-               kvp_frame_get_slot_path (kvpf, "sched-xaction", "debit-formula", NULL));
-}
+    g_return_val_if_fail (split != NULL, NULL);
+    qof_instance_get (QOF_INSTANCE (split),
+		      "sx-debit-formula", &formula,
+		      NULL);
 
+    return formula;
+}
 
 const char *
 gnc_tree_util_split_reg_template_get_fcred_entry (Split *split)
 {
-    kvp_frame *kvpf = xaccSplitGetSlots (split);
+    gchar *formula = NULL;
+
+    g_return_val_if_fail (split != NULL, NULL);
+    qof_instance_get (QOF_INSTANCE (split),
+		      "sx-credit-formula", &formula,
+		      NULL);
 
-    return kvp_value_get_string(
-               kvp_frame_get_slot_path (kvpf, "sched-xaction", "credit-formula", NULL));
+    return formula;
 }
 
 
diff --git a/src/gnome-utils/gnc-tree-view-account.c b/src/gnome-utils/gnc-tree-view-account.c
index d1912e5..bde9de5 100644
--- a/src/gnome-utils/gnc-tree-view-account.c
+++ b/src/gnome-utils/gnc-tree-view-account.c
@@ -1730,43 +1730,44 @@ gtva_currency_changed_cb (void)
         gtva_update_column_names (ptr->data);
     }
 }
-/* This function implements a custom mapping between an account's KVP
- * and the cell renderer's 'text' property. */
+/* Retrieve a specified account string property and put the result
+ * into the tree column's text property.
+ */
 static void
-account_cell_kvp_data_func (GtkTreeViewColumn *tree_column,
-                            GtkCellRenderer *cell,
-                            GtkTreeModel *s_model,
-                            GtkTreeIter *s_iter,
-                            gpointer key)
+account_cell_property_data_func (GtkTreeViewColumn *tree_column,
+				 GtkCellRenderer *cell,
+				 GtkTreeModel *s_model,
+				 GtkTreeIter *s_iter,
+				 gpointer key)
 {
     Account *account;
-    kvp_frame * frame;
+    gchar *string = NULL;
 
     g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model));
     account = gnc_tree_view_account_get_account_from_iter(s_model, s_iter);
-    frame = xaccAccountGetSlots(account);
-
-    g_object_set (G_OBJECT (cell),
-                  "text", kvp_frame_get_string(frame, (gchar *)key),
-                  "xalign", 0.0,
-                  NULL);
+    qof_instance_get (QOF_INSTANCE (account),
+		      key, &string,
+		      NULL);
+    if (string == NULL)
+	string = "";
 
+    g_object_set (G_OBJECT (cell), "text", string, "xalign", 0.0, NULL);
 }
 
 
 GtkTreeViewColumn *
-gnc_tree_view_account_add_kvp_column (GncTreeViewAccount *view,
+gnc_tree_view_account_add_property_column (GncTreeViewAccount *view,
                                       const gchar *column_title,
-                                      const gchar *kvp_key)
+                                      const gchar *propname)
 {
     GtkCellRenderer *renderer;
     GtkTreeViewColumn *column;
 
     g_return_val_if_fail (GNC_IS_TREE_VIEW_ACCOUNT (view), NULL);
-    g_return_val_if_fail (kvp_key != NULL, NULL);
+    g_return_val_if_fail (propname != NULL, NULL);
 
     column = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), column_title,
-                                           kvp_key, NULL, "Sample text",
+                                           propname, NULL, "Sample text",
                                            -1, -1, NULL);
 
     /* This new kvp column has only had one renderer added to it so
@@ -1775,8 +1776,8 @@ gnc_tree_view_account_add_kvp_column (GncTreeViewAccount *view,
     g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
 
     gtk_tree_view_column_set_cell_data_func (column, renderer,
-            account_cell_kvp_data_func,
-            g_strdup(kvp_key), g_free);
+            account_cell_property_data_func,
+            g_strdup(propname), g_free);
     return column;
 }
 
diff --git a/src/gnome-utils/gnc-tree-view-account.h b/src/gnome-utils/gnc-tree-view-account.h
index 87778cd..5088b75 100644
--- a/src/gnome-utils/gnc-tree-view-account.h
+++ b/src/gnome-utils/gnc-tree-view-account.h
@@ -203,20 +203,19 @@ void gnc_tree_view_account_notes_edited_cb(Account *account, GtkTreeViewColumn *
 
 /** Add a new column to the set of columns in an account tree view.
  *  This column will be visible as soon as it is added and will
- *  display the contents of the specified KVP slot.
+ *  display the contents of the specified account property
  *
  *  @param view A pointer to an account tree view.
  *
  *  @param column_title The title for this new column.
  *
- *  @param kvp_key The lookup key to use for looking up data in the
- *  account KVP structures. The value associated with this key is what
- *  will be displayed in the column.
+ *  @param propname The g_object_property name of the desired
+ *  value. This must be a string property.
  */
 GtkTreeViewColumn *
-gnc_tree_view_account_add_kvp_column (GncTreeViewAccount *view,
-                                      const gchar *column_title,
-                                      const gchar *kvp_key);
+gnc_tree_view_account_add_property_column (GncTreeViewAccount *view,
+					   const gchar *column_title,
+					   const gchar *propname);
 
 /** @} */
 
diff --git a/src/gnome-utils/gnc-tree-view-split-reg.c b/src/gnome-utils/gnc-tree-view-split-reg.c
index 74d4b98..c1ff190 100644
--- a/src/gnome-utils/gnc-tree-view-split-reg.c
+++ b/src/gnome-utils/gnc-tree-view-split-reg.c
@@ -4801,9 +4801,8 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
             if (viewcol == COL_TRANSFERVOID)
             {
                 Account *template_acc;
+		Account *acct;
                 const GncGUID *acctGUID;
-                kvp_frame *kvpf;
-                Account *acct;
 
                 /* save the account GncGUID into the kvp_data. */
                 view->priv->stop_cell_move = FALSE;
@@ -4822,9 +4821,9 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
                 }
 
                 acctGUID = xaccAccountGetGUID (acct);
-                kvpf = xaccSplitGetSlots (split);
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_guid (acctGUID),
-                             GNC_SX_ID, GNC_SX_ACCOUNT, NULL);
+		qof_instance_set (QOF_INSTANCE (split),
+				  "sx-account", acctGUID,
+				  NULL);
 
                 template_acc = gnc_tree_model_split_reg_get_template_account (model);
 
@@ -4844,20 +4843,11 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
             /* Setup the debit and credit fields */
             if (viewcol == COL_DEBIT)
             {
-                kvp_frame *kvpf;
                 char *error_loc;
                 gnc_numeric new_value;
                 gboolean parse_result;
 
-                kvpf = xaccSplitGetSlots (split);
-
-                DEBUG ("kvp_frame debit before: %s\n", kvp_frame_to_string (kvpf));
-
                 /* Setup the debit formula */
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (new_text),
-                                         GNC_SX_ID,
-                                         GNC_SX_DEBIT_FORMULA,
-                                         NULL);
 
                 /* If the value can be parsed into a numeric result, store that
                  * numeric value additionally. See above comment.*/
@@ -4866,45 +4856,22 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
                 {
                     new_value = gnc_numeric_zero();
                 }
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
-                                         GNC_SX_ID,
-                                         GNC_SX_DEBIT_NUMERIC,
-                                         NULL);
-
-                DEBUG ("kvp_frame debit after: %s\n", kvp_frame_to_string (kvpf));
-
-                /* Blank the credit formula */
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (NULL),
-                                         GNC_SX_ID,
-                                         GNC_SX_CREDIT_FORMULA,
-                                         NULL);
-
-                new_value = gnc_numeric_zero();
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
-                                         GNC_SX_ID,
-                                         GNC_SX_CREDIT_NUMERIC,
-                                         NULL);
+		qof_instance_set (QOF_INSTANCE (split),
+				  "sx-debit-formula", new_text,
+				  "sx-debit-numeric", &new_value,
+				  "sx-credit-formula", NULL,
+				  "sx-credit-numeric", NULL,
+				  NULL);
             }
 
             /* Setup the debit and credit fields */
             if (viewcol == COL_CREDIT)
             {
-                kvp_frame *kvpf;
                 char *error_loc;
                 gnc_numeric new_value;
                 gboolean parse_result;
 
-                kvpf = xaccSplitGetSlots (split);
-
-                DEBUG ("kvp_frame credit before: %s\n", kvp_frame_to_string (kvpf));
-
-                /* Setup the credit formula */
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (new_text),
-                                             GNC_SX_ID,
-                                             GNC_SX_CREDIT_FORMULA,
-                                             NULL);
-
-                /* If the value can be parsed into a numeric result (without any
+               /* If the value can be parsed into a numeric result (without any
                  * further variable definitions), store that numeric value
                  * additionally in the kvp. Otherwise store a zero numeric
                  * there.*/
@@ -4913,24 +4880,12 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
                 {
                     new_value = gnc_numeric_zero();
                 }
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
-                                         GNC_SX_ID,
-                                         GNC_SX_CREDIT_NUMERIC,
-                                         NULL);
-
-                DEBUG ("kvp_frame credit after: %s\n", kvp_frame_to_string (kvpf));
-
-                /* Blank the debit formula */
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (NULL),
-                                         GNC_SX_ID,
-                                         GNC_SX_DEBIT_FORMULA,
-                                         NULL);
-
-                new_value = gnc_numeric_zero();
-                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
-                                         GNC_SX_ID,
-                                         GNC_SX_DEBIT_NUMERIC,
-                                         NULL);
+		qof_instance_set (QOF_INSTANCE (split),
+				  "sx-credit-formula", new_text,
+				  "sx-credit-numeric", &new_value,
+				  "sx-debit-formula", NULL,
+				  "sx-debit-numeric", NULL,
+				  NULL);
             }
             /* set the amount to an innocuous value */
             xaccSplitSetValue (split, gnc_numeric_create (0, 1));
diff --git a/src/gnome/assistant-hierarchy.c b/src/gnome/assistant-hierarchy.c
index da0d5af..23b98f8 100644
--- a/src/gnome/assistant-hierarchy.c
+++ b/src/gnome/assistant-hierarchy.c
@@ -1008,18 +1008,17 @@ finish_book_options_helper(GNCOptionWin * optionwin,
                           gpointer user_data)
 {
     GNCOptionDB * options = user_data;
-    kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
+    QofBook *book = gnc_get_current_book ();
     gboolean use_split_action_for_num_before =
-        qof_book_use_split_action_for_num_field (gnc_get_current_book ());
+        qof_book_use_split_action_for_num_field (book);
     gboolean use_split_action_for_num_after;
 
     if (!options) return;
 
     gnc_option_db_commit (options);
-    gnc_option_db_save_to_kvp (options, slots, TRUE);
-    qof_book_kvp_changed (gnc_get_current_book());
+    qof_book_save_options (book, gnc_option_db_save_to_kvp, options, TRUE);
     use_split_action_for_num_after =
-        qof_book_use_split_action_for_num_field (gnc_get_current_book ());
+        qof_book_use_split_action_for_num_field (book);
     if (use_split_action_for_num_before != use_split_action_for_num_after)
         gnc_book_option_num_field_source_change_cb (use_split_action_for_num_after);
 }
@@ -1119,11 +1118,11 @@ book_options_dialog_close_cb(GNCOptionWin * optionwin,
 static void
 assistant_instert_book_options_page (hierarchy_data *data)
 {
-    kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
     GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
 
     data->options = gnc_option_db_new_for_type (QOF_ID_BOOK);
-    gnc_option_db_load_from_kvp (data->options, slots);
+    qof_book_load_options (gnc_get_current_book (),
+			   gnc_option_db_load_from_kvp, data->options);
     gnc_option_db_clean (data->options);
 
     data->optionwin = gnc_options_dialog_new_modal (TRUE, _("New Book Options"));
diff --git a/src/gnome/dialog-sx-editor.c b/src/gnome/dialog-sx-editor.c
index b3fb1e8..4b7b95f 100644
--- a/src/gnome/dialog-sx-editor.c
+++ b/src/gnome/dialog-sx-editor.c
@@ -549,9 +549,7 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
         int numIters, i;
         GHashTable *vars, *txns;
         GList *splitList = NULL;
-        char *str;
-        kvp_frame *f;
-        kvp_value *v;
+        gchar *credit_formula = NULL, *debit_formula = NULL;
         Split *s;
         Transaction *t;
         gnc_numeric tmp;
@@ -559,8 +557,10 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
         gpointer unusedKey, unusedValue;
 
         unbalanceable = FALSE; /* innocent until proven guilty */
-        vars = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)gnc_sx_variable_free);
-        txns = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
+        vars = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+				     (GDestroyNotify)gnc_sx_variable_free);
+        txns = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+				     g_free);
         numIters = NUM_ITERS_NO_VARS;
         /**
          * Plan:
@@ -604,10 +604,10 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
 
             for ( ; splitList; splitList = splitList->next )
             {
-                GncGUID *acct_guid;
-                Account *acct;
-                gnc_commodity *split_cmdty;
-                txnCreditDebitSums *tcds;
+                GncGUID *acct_guid = NULL;
+                Account *acct = NULL;
+                gnc_commodity *split_cmdty = NULL;
+                txnCreditDebitSums *tcds = NULL;
 
                 s = (Split*)splitList->data;
                 t = xaccSplitGetParent( s );
@@ -622,14 +622,11 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
                     g_hash_table_insert( txns, (gpointer)t, (gpointer)tcds );
                 }
 
-                f = xaccSplitGetSlots( s );
-
-                /* contains the guid of the split's actual account. */
-                v = kvp_frame_get_slot_path(f,
-                                            GNC_SX_ID,
-                                            GNC_SX_ACCOUNT,
-                                            NULL);
-                acct_guid = kvp_value_get_guid( v );
+		qof_instance_get (QOF_INSTANCE (s),
+				  "sx-account", &acct_guid,
+				  "sx-credit-formula", &credit_formula,
+				  "sx-debit-formula", &debit_formula,
+				  NULL);
                 acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
                 split_cmdty = xaccAccountGetCommodity(acct);
                 if (base_cmdty == NULL)
@@ -638,62 +635,48 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
                 }
                 multi_commodity |= !gnc_commodity_equal(split_cmdty, base_cmdty);
 
-                v = kvp_frame_get_slot_path( f,
-                                             GNC_SX_ID,
-                                             GNC_SX_CREDIT_FORMULA,
-                                             NULL );
-                if ( v
-                        && (str = kvp_value_get_string(v))
-                        && strlen( str ) != 0 )
-                {
-                    if ( gnc_sx_parse_vars_from_formula( str, vars, &tmp ) < 0 )
-                    {
-                        GString *errStr;
-
-                        errStr = g_string_sized_new( 32 );
-                        g_string_printf( errStr,
-                                         _( "Couldn't parse credit formula for "
-                                            "split \"%s\"." ),
-                                         xaccSplitGetMemo( s ) );
-                        gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
-                                          errStr->str );
-                        g_string_free( errStr, TRUE );
-
-                        return FALSE;
-                    }
-                    tcds->creditSum =
-                        gnc_numeric_add( tcds->creditSum, tmp, 100,
-                                         (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
-                    tmp = gnc_numeric_zero();
-                }
-                v = kvp_frame_get_slot_path( f,
-                                             GNC_SX_ID,
-                                             GNC_SX_DEBIT_FORMULA,
-                                             NULL );
-                if ( v
-                        && (str = kvp_value_get_string(v))
-                        && strlen(str) != 0 )
-                {
-                    if ( gnc_sx_parse_vars_from_formula( str, vars, &tmp ) < 0 )
-                    {
-                        GString *errStr;
-
-                        errStr = g_string_sized_new( 32 );
-                        g_string_printf( errStr,
-                                         _( "Couldn't parse debit formula for "
-                                            "split \"%s\"." ),
-                                         xaccSplitGetMemo( s ) );
-                        gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
-                                          (gchar*)errStr->str );
-                        g_string_free( errStr, TRUE );
-
-                        return FALSE;
-                    }
-                    tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
-                                                      (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
-                    tmp = gnc_numeric_zero();
-                }
-            }
+		if ( g_strcmp0 (credit_formula, "") != 0 &&
+		     gnc_sx_parse_vars_from_formula(credit_formula, vars,
+						    &tmp ) < 0 )
+		{
+		    GString *errStr;
+
+		    errStr = g_string_sized_new( 32 );
+		    g_string_printf( errStr,
+				     _( "Couldn't parse credit formula for "
+					"split \"%s\"." ),
+				     xaccSplitGetMemo( s ) );
+		    gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
+				      errStr->str );
+		    g_string_free( errStr, TRUE );
+
+		    return FALSE;
+		}
+		tcds->creditSum =
+		    gnc_numeric_add( tcds->creditSum, tmp, 100,
+				     (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
+		tmp = gnc_numeric_zero();
+		if ( g_strcmp0 (debit_formula, "") != 0 &&
+		     gnc_sx_parse_vars_from_formula( debit_formula, vars,
+						     &tmp ) < 0 )
+		{
+		    GString *errStr;
+
+		    errStr = g_string_sized_new( 32 );
+		    g_string_printf( errStr,
+				     _( "Couldn't parse debit formula for "
+					"split \"%s\"." ),
+				     xaccSplitGetMemo( s ) );
+		    gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
+				      (gchar*)errStr->str );
+		    g_string_free( errStr, TRUE );
+
+		    return FALSE;
+		}
+		tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
+						  (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
+		tmp = gnc_numeric_zero();
+	    }
 
             g_hash_table_foreach( txns,
                                   check_credit_debit_balance,
diff --git a/src/gnome/dialog-sx-editor2.c b/src/gnome/dialog-sx-editor2.c
index c9de4dc..a5c5d61 100644
--- a/src/gnome/dialog-sx-editor2.c
+++ b/src/gnome/dialog-sx-editor2.c
@@ -546,9 +546,7 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
         int numIters, i;
         GHashTable *vars, *txns;
         GList *splitList = NULL;
-        char *str;
-        kvp_frame *f;
-        kvp_value *v;
+        char *credit_formula = NULL, *debit_formula = NULL;
         Split *s;
         Transaction *t;
         gnc_numeric tmp;
@@ -597,7 +595,7 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
 
             for (; splitList; splitList = splitList->next)
             {
-                GncGUID *acct_guid;
+                GncGUID *acct_guid = NULL;
                 Account *acct;
                 gnc_commodity *split_cmdty;
                 txnCreditDebitSums *tcds;
@@ -615,77 +613,60 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
                     g_hash_table_insert (txns, (gpointer)t, (gpointer)tcds);
                 }
 
-                f = xaccSplitGetSlots (s);
-
-                /* contains the guid of the split's actual account. */
-                v = kvp_frame_get_slot_path (f,
-                                            GNC_SX_ID,
-                                            GNC_SX_ACCOUNT,
-                                            NULL);
-                acct_guid = kvp_value_get_guid (v);
-                acct = xaccAccountLookup (acct_guid, gnc_get_current_book ());
-                split_cmdty = xaccAccountGetCommodity (acct);
+		qof_instance_get (QOF_INSTANCE (s),
+				  "sx-account", &acct_guid,
+				  "sx-credit-formula", &credit_formula,
+				  "sx-debit-formula", &debit_formula,
+				  NULL);
+                acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
+                split_cmdty = xaccAccountGetCommodity(acct);
                 if (base_cmdty == NULL)
                 {
                     base_cmdty = split_cmdty;
                 }
-                multi_commodity |= !gnc_commodity_equal (split_cmdty, base_cmdty);
-
-                v = kvp_frame_get_slot_path (f,
-                                             GNC_SX_ID,
-                                             GNC_SX_CREDIT_FORMULA,
-                                             NULL);
-                if (v
-                        && (str = kvp_value_get_string (v))
-                        && strlen( str ) != 0)
-                {
-                    if (gnc_sx_parse_vars_from_formula (str, vars, &tmp ) < 0)
-                    {
-                        GString *errStr;
-
-                        errStr = g_string_sized_new (32);
-                        g_string_printf (errStr,
-                                         _( "Couldn't parse credit formula for "
-                                            "split \"%s\"."),
-                                         xaccSplitGetMemo (s));
-                        gnc_error_dialog (GTK_WIDGET (sxed->dialog), "%s",
-                                          errStr->str);
-                        g_string_free (errStr, TRUE);
-
-                        return FALSE;
-                    }
-                    tcds->creditSum =
-                        gnc_numeric_add (tcds->creditSum, tmp, 100,
-                                         (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD));
-                    tmp = gnc_numeric_zero();
-                }
-                v = kvp_frame_get_slot_path (f,
-                                             GNC_SX_ID,
-                                             GNC_SX_DEBIT_FORMULA,
-                                             NULL);
-                if (v
-                        && (str = kvp_value_get_string (v))
-                        && strlen(str) != 0 )
-                {
-                    if (gnc_sx_parse_vars_from_formula (str, vars, &tmp ) < 0)
-                    {
-                        GString *errStr;
-
-                        errStr = g_string_sized_new (32);
-                        g_string_printf (errStr,
-                                         _( "Couldn't parse debit formula for "
-                                            "split \"%s\"."),
-                                         xaccSplitGetMemo (s));
-                        gnc_error_dialog (GTK_WIDGET (sxed->dialog), "%s",
-                                          (gchar*)errStr->str);
-                        g_string_free (errStr, TRUE);
-
-                        return FALSE;
-                    }
-                    tcds->debitSum = gnc_numeric_add (tcds->debitSum, tmp, 100,
-                                                      (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD));
-                    tmp = gnc_numeric_zero();
-                }
+                multi_commodity |= !gnc_commodity_equal(split_cmdty, base_cmdty);
+
+		if ( g_strcmp0 (credit_formula, "") != 0 &&
+		     gnc_sx_parse_vars_from_formula(credit_formula, vars,
+						    &tmp ) < 0 )
+		{
+		    GString *errStr;
+
+		    errStr = g_string_sized_new( 32 );
+		    g_string_printf( errStr,
+				     _( "Couldn't parse credit formula for "
+					"split \"%s\"." ),
+				     xaccSplitGetMemo( s ) );
+		    gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
+				      errStr->str );
+		    g_string_free( errStr, TRUE );
+
+		    return FALSE;
+		}
+		tcds->creditSum =
+		    gnc_numeric_add( tcds->creditSum, tmp, 100,
+				     (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
+		tmp = gnc_numeric_zero();
+		if ( g_strcmp0 (debit_formula, "") != 0 &&
+		     gnc_sx_parse_vars_from_formula( debit_formula, vars,
+						     &tmp ) < 0 )
+		{
+		    GString *errStr;
+
+		    errStr = g_string_sized_new( 32 );
+		    g_string_printf( errStr,
+				     _( "Couldn't parse debit formula for "
+					"split \"%s\"." ),
+				     xaccSplitGetMemo( s ) );
+		    gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
+				      (gchar*)errStr->str );
+		    g_string_free( errStr, TRUE );
+
+		    return FALSE;
+		}
+		tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
+						  (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
+		tmp = gnc_numeric_zero();
             }
 
             g_hash_table_foreach (txns,
diff --git a/src/gnome/gnc-plugin-page-register2.c b/src/gnome/gnc-plugin-page-register2.c
index c5494e4..b24793d 100644
--- a/src/gnome/gnc-plugin-page-register2.c
+++ b/src/gnome/gnc-plugin-page-register2.c
@@ -3646,39 +3646,30 @@ gnc_plugin_page_register2_cmd_schedule (GtkAction *action,
     /* If the transaction has a sched-xact KVP frame, then go to the editor
      * for the existing SX; otherwise, do the sx-from-trans dialog. */
     {
-        kvp_frame *txn_frame;
-        kvp_value *kvp_val;
-        /* set a kvp-frame element in the transaction indicating and
-         * pointing-to the SX this was created from. */
-        txn_frame = xaccTransGetSlots (trans);
-        if ( txn_frame != NULL )
-        {
-            kvp_val = kvp_frame_get_slot (txn_frame, "from-sched-xaction");
-            if (kvp_val)
-            {
-                GncGUID *fromSXId = kvp_value_get_guid (kvp_val);
-                SchedXaction *theSX = NULL;
-                GList *sxElts;
-
-                /* Get the correct SX */
-                for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
-                        (!theSX) && sxElts;
-                        sxElts = sxElts->next )
-                {
-                    SchedXaction *sx = (SchedXaction*)sxElts->data;
-                    theSX =
-                        ((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
-                          ? sx : NULL);
-                }
-
-                if (theSX)
-                {
-                    gnc_ui_scheduled_xaction_editor_dialog_create2 (theSX, FALSE);
-                    LEAVE(" ");
-                    return;
-                }
-            }
-        }
+	GncGUID *fromSXId = NULL;
+	SchedXaction *theSX = NULL;
+	GList *sxElts;
+	qof_instance_get (QOF_INSTANCE (trans),
+			  "from-sched-xaction", &fromSXId,
+			  NULL);
+
+	/* Get the correct SX */
+	for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
+	      (!theSX) && sxElts;
+	      sxElts = sxElts->next )
+	{
+	    SchedXaction *sx = (SchedXaction*)sxElts->data;
+	    theSX =
+		((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
+		 ? sx : NULL);
+	}
+
+	if (theSX)
+	{
+	    gnc_ui_scheduled_xaction_editor_dialog_create2 (theSX, FALSE);
+	    LEAVE(" ");
+	    return;
+	}
     }
     gnc_sx_create_from_trans (trans);
     LEAVE(" ");
diff --git a/src/gnome/gnc-split-reg.c b/src/gnome/gnc-split-reg.c
index b9d198a..e5e56ac 100644
--- a/src/gnome/gnc-split-reg.c
+++ b/src/gnome/gnc-split-reg.c
@@ -1387,38 +1387,29 @@ gsr_default_schedule_handler( GNCSplitReg *gsr, gpointer data )
     /* If the transaction has a sched-xact KVP frame, then go to the editor
      * for the existing SX; otherwise, do the sx-from-trans dialog. */
     {
-        kvp_frame *txn_frame;
-        kvp_value *kvp_val;
-        /* set a kvp-frame element in the transaction indicating and
-         * pointing-to the SX this was created from. */
-        txn_frame = xaccTransGetSlots( pending_trans );
-        if ( txn_frame != NULL )
-        {
-            kvp_val = kvp_frame_get_slot( txn_frame, "from-sched-xaction" );
-            if ( kvp_val )
-            {
-                GncGUID *fromSXId = kvp_value_get_guid( kvp_val );
-                SchedXaction *theSX = NULL;
-                GList *sxElts;
-
-                /* Get the correct SX */
-                for ( sxElts = gnc_book_get_schedxactions(gnc_get_current_book())->sx_list;
-                        (!theSX) && sxElts;
-                        sxElts = sxElts->next )
-                {
-                    SchedXaction *sx = (SchedXaction*)sxElts->data;
-                    theSX =
-                        ( ( guid_equal( xaccSchedXactionGetGUID( sx ), fromSXId ) )
-                          ? sx : NULL );
-                }
-
-                if ( theSX )
-                {
-                    gnc_ui_scheduled_xaction_editor_dialog_create(theSX, FALSE);
-                    return;
-                }
-            }
-        }
+	GncGUID *fromSXId = NULL;
+	SchedXaction *theSX = NULL;
+	GList *sxElts;
+	qof_instance_get (QOF_INSTANCE (pending_trans),
+			  "from-sched-xaction", &fromSXId,
+			  NULL);
+
+	/* Get the correct SX */
+	for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
+	      (!theSX) && sxElts;
+	      sxElts = sxElts->next )
+	{
+	    SchedXaction *sx = (SchedXaction*)sxElts->data;
+	    theSX =
+		((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
+		 ? sx : NULL);
+	}
+
+	if ( theSX )
+	{
+	    gnc_ui_scheduled_xaction_editor_dialog_create(theSX, FALSE);
+	    return;
+	}
     }
 
     gnc_sx_create_from_trans(pending_trans);
diff --git a/src/import-export/Makefile.am b/src/import-export/Makefile.am
index 0f07e24..4230c83 100644
--- a/src/import-export/Makefile.am
+++ b/src/import-export/Makefile.am
@@ -18,13 +18,11 @@ libgncmod_generic_import_la_SOURCES = \
 	import-parse.c \
 	import-utilities.c \
 	import-settings.c \
-	import-match-map.c \
 	import-main-matcher.c \
 	gncmod-generic-import.c
 
 gncincludedir = ${GNC_INCLUDE_DIR}
 gncinclude_HEADERS = \
-  import-match-map.h \
   import-parse.h
 
 noinst_HEADERS = \
@@ -32,7 +30,6 @@ noinst_HEADERS = \
   import-backend.h \
   import-commodity-matcher.h \
   import-main-matcher.h \
-  import-match-map.h \
   import-match-picker.h \
   import-settings.h \
   import-utilities.h
diff --git a/src/import-export/aqb/gnc-ab-kvp.c b/src/import-export/aqb/gnc-ab-kvp.c
index 074a37b..b99390b 100644
--- a/src/import-export/aqb/gnc-ab-kvp.c
+++ b/src/import-export/aqb/gnc-ab-kvp.c
@@ -32,134 +32,105 @@
 
 #include "gnc-ab-kvp.h"
 
-#define AB_KEY "hbci"
-#define AB_ACCOUNT_ID "account-id"
-#define AB_ACCOUNT_UID "account-uid"
-#define AB_BANK_CODE "bank-code"
-#define AB_TRANS_RETRIEVAL "trans-retrieval"
-#define AB_TEMPLATES "template-list"
-
 /* This static indicates the debugging module that this .o belongs to.  */
 G_GNUC_UNUSED static QofLogModule log_module = G_LOG_DOMAIN;
 
-static kvp_frame *gnc_ab_get_account_kvp(const Account *a, gboolean create);
 static kvp_frame *gnc_ab_get_book_kvp(QofBook *b, gboolean create);
 
 const gchar *
 gnc_ab_get_account_accountid(const Account *a)
 {
-    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
-    kvp_value *value = kvp_frame_get_slot(frame, AB_ACCOUNT_ID);
-    return kvp_value_get_string(value);
+    gchar *id = NULL;
+    qof_instance_get (QOF_INSTANCE (a),
+		      "ab-account-id", &id,
+		      NULL);
+    return id;
 }
 
 void
 gnc_ab_set_account_accountid(Account *a, const gchar *id)
 {
-    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
-    kvp_value *value = kvp_value_new_string(id);
     xaccAccountBeginEdit(a);
-    kvp_frame_set_slot_nc(frame, AB_ACCOUNT_ID, value);
-    qof_instance_set_dirty(QOF_INSTANCE (a));
+    qof_instance_set (QOF_INSTANCE (a),
+		      "ab-account-id", id,
+		      NULL);
     xaccAccountCommitEdit(a);
 }
 
 const gchar *
 gnc_ab_get_account_bankcode(const Account *a)
 {
-    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
-    kvp_value *value = kvp_frame_get_slot(frame, AB_BANK_CODE);
-    return kvp_value_get_string(value);
+    gchar *code = NULL;
+    qof_instance_get (QOF_INSTANCE (a),
+		      "ab-bank-code", &code,
+		      NULL);
+    return code;
 }
 
 void
 gnc_ab_set_account_bankcode(Account *a, const gchar *code)
 {
-    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
-    kvp_value *value = kvp_value_new_string(code);
     xaccAccountBeginEdit(a);
-    kvp_frame_set_slot_nc(frame, AB_BANK_CODE, value);
-    qof_instance_set_dirty(QOF_INSTANCE (a));
+    qof_instance_set (QOF_INSTANCE (a),
+		      "ab-bank-code", code,
+		      NULL);
     xaccAccountCommitEdit(a);
 }
 
 guint32
 gnc_ab_get_account_uid(const Account *a)
 {
-    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
-    kvp_value *value = kvp_frame_get_slot(frame, AB_ACCOUNT_UID);
-    return (guint32) kvp_value_get_gint64(value);
+    guint64 uid = 0LL;
+    qof_instance_get (QOF_INSTANCE (a),
+		      "ab-account-uid", &uid,
+		      NULL);
+    return (guint32)uid;
 }
 
 void
 gnc_ab_set_account_uid(Account *a, guint32 uid)
 {
-    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
-    kvp_value *value = kvp_value_new_gint64(uid);
     xaccAccountBeginEdit(a);
-    kvp_frame_set_slot_nc(frame, AB_ACCOUNT_UID, value);
-    qof_instance_set_dirty(QOF_INSTANCE (a));
+    qof_instance_set (QOF_INSTANCE (a),
+		      "ab-account-uid", (guint64)uid,
+		      NULL);
     xaccAccountCommitEdit(a);
 }
 
 Timespec
 gnc_ab_get_account_trans_retrieval(const Account *a)
 {
-    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
-    kvp_value *value = kvp_frame_get_slot(frame, AB_TRANS_RETRIEVAL);
-    return kvp_value_get_timespec(value);
+    Timespec t = {0LL, 0LL};
+    qof_instance_get (QOF_INSTANCE (a),
+		      "ab-trans-retrieval", &t,
+		      NULL);
+    return t;
 }
 
 void
 gnc_ab_set_account_trans_retrieval(Account *a, Timespec time)
 {
-    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
-    kvp_value *value = kvp_value_new_timespec(time);
     xaccAccountBeginEdit(a);
-    kvp_frame_set_slot_nc(frame, AB_TRANS_RETRIEVAL, value);
-    qof_instance_set_dirty(QOF_INSTANCE (a));
+    qof_instance_set (QOF_INSTANCE (a),
+		      "ab-trans-retrieval", &time,
+		      NULL);
     xaccAccountCommitEdit(a);
 }
 
 GList *
 gnc_ab_get_book_template_list(QofBook *b)
 {
-    kvp_frame *frame = gnc_ab_get_book_kvp(b, FALSE);
-    kvp_value *value = kvp_frame_get_slot(frame, AB_TEMPLATES);
-    return kvp_value_get_glist(value);
+    GList *template_list = NULL;
+    qof_instance_get (QOF_INSTANCE (b),
+		      "ab-templates", &template_list,
+		      NULL);
+    return template_list;
 }
 
 void
 gnc_ab_set_book_template_list(QofBook *b, GList *template_list)
 {
-    kvp_frame *frame = gnc_ab_get_book_kvp(b, TRUE);
-    kvp_value *value = kvp_value_new_glist_nc(template_list);
-    kvp_frame_set_slot_nc(frame, AB_TEMPLATES, value);
-    qof_book_kvp_changed (b);
-}
-
-static kvp_frame *
-gnc_ab_get_account_kvp(const Account *a, gboolean create)
-{
-    kvp_frame *toplevel = xaccAccountGetSlots(a);
-    kvp_frame *result = kvp_frame_get_frame(toplevel, AB_KEY);
-    if (!result && create)
-    {
-        result = kvp_frame_new();
-        kvp_frame_add_frame_nc(toplevel, AB_KEY, result);
-    }
-    return result;
-}
-
-static kvp_frame *
-gnc_ab_get_book_kvp(QofBook *b, gboolean create)
-{
-    kvp_frame *toplevel = qof_book_get_slots(b);
-    kvp_frame *result = kvp_frame_get_frame(toplevel, AB_KEY);
-    if (!result && create)
-    {
-        result = kvp_frame_new();
-        kvp_frame_add_frame_nc(toplevel, AB_KEY, result);
-    }
-    return result;
+    qof_instance_set (QOF_INSTANCE (b),
+		      "ab-templates", &template_list,
+		      NULL);
 }
diff --git a/src/import-export/import-account-matcher.c b/src/import-export/import-account-matcher.c
index a828311..27d7fe3 100644
--- a/src/import-export/import-account-matcher.c
+++ b/src/import-export/import-account-matcher.c
@@ -114,8 +114,8 @@ build_acct_tree(AccountPickerDialog *picker)
     g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
 
     /* Add our custom column. */
-    col = gnc_tree_view_account_add_kvp_column (picker->account_tree,
-            _("Account ID"), "online_id");
+    col = gnc_tree_view_account_add_property_column (picker->account_tree,
+            _("Account ID"), "online-id");
     g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
 
     gtk_container_add(GTK_CONTAINER(picker->account_tree_sw),
diff --git a/src/import-export/import-backend.c b/src/import-export/import-backend.c
index 4e0d34e..a372bc4 100644
--- a/src/import-export/import-backend.c
+++ b/src/import-export/import-backend.c
@@ -44,6 +44,40 @@
 #include "gnc-prefs.h"
 #include "gnc-ui-util.h"
 
+/* Private interface to Account GncImportMatchMap functions */
+
+/** @{
+Obtain an ImportMatchMap object from an Account */
+extern GncImportMatchMap * gnc_account_create_imap (Account *acc);
+/*@}*/
+
+/* Look up an Account in the map */
+extern Account* gnc_imap_find_account(GncImportMatchMap *imap,
+				      const char* category,
+				      const char *key);
+
+/* Store an Account in the map. This mapping is immediatly stored in
+  the underlying kvp frame, regardless of whether the MatchMap is
+  destroyed later or not. */
+extern void gnc_imap_add_account (GncImportMatchMap *imap,
+				  const char *category,
+				  const char *key, Account *acc);
+
+/* Look up an Account in the map from a GList* of pointers to strings(tokens)
+  from the current transaction */
+extern Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap,
+					     GList* tokens);
+
+/* Store an Account in the map. This mapping is immediatly stored in
+  the underlying kvp frame, regardless of whether the MatchMap is
+  destroyed later or not. */
+extern void gnc_imap_add_account_bayes (GncImportMatchMap *imap,
+					GList* tokens,
+					Account *acc);
+
+#define GNCIMPORT_DESC    "desc"
+#define GNCIMPORT_MEMO    "memo"
+#define GNCIMPORT_PAYEE    "payee"
 
 /********************************************************************\
  *   Constants                                                      *
@@ -457,6 +491,15 @@ TransactionGetTokens(GNCImportTransInfo *info)
     /* return the pointer to the GList */
     return tokens;
 }
+/* Destroy an import map. But all stored entries will still continue
+ * to exist in the underlying kvp frame of the account.
+ */
+static void
+gnc_imap_destroy (GncImportMatchMap *imap)
+{
+    if (!imap) return;
+    g_free (imap);
+}
 
 /* searches using the GNCImportTransInfo through all existing transactions
  * if there is an exact match of the description and memo
@@ -471,7 +514,7 @@ matchmap_find_destination (GncImportMatchMap *matchmap, GNCImportTransInfo *info
 
     g_assert (info);
     tmp_map = ((matchmap != NULL) ? matchmap :
-               gnc_imap_create_from_account
+               gnc_account_create_imap
                (xaccSplitGetAccount
                 (gnc_import_TransInfo_get_fsplit (info))));
 
@@ -541,7 +584,7 @@ matchmap_store_destination (GncImportMatchMap *matchmap,
 
     tmp_matchmap = ((matchmap != NULL) ?
                     matchmap :
-                    gnc_imap_create_from_account
+                    gnc_account_create_imap
                     (xaccSplitGetAccount
                      (gnc_import_TransInfo_get_fsplit (trans_info))));
 
diff --git a/src/import-export/import-backend.h b/src/import-export/import-backend.h
index 2978fd5..99e6421 100644
--- a/src/import-export/import-backend.h
+++ b/src/import-export/import-backend.h
@@ -29,11 +29,11 @@
 #define TRANSACTION_MATCHER_H
 
 #include "Transaction.h"
-#include "import-match-map.h"
 #include "import-settings.h"
 
 typedef struct _transactioninfo GNCImportTransInfo;
 typedef struct _matchinfo GNCImportMatchInfo;
+typedef struct _GncImportMatchMap GncImportMatchMap;
 
 typedef enum _action
 {
diff --git a/src/import-export/import-main-matcher.c b/src/import-export/import-main-matcher.c
index 3793212..24b8b63 100644
--- a/src/import-export/import-main-matcher.c
+++ b/src/import-export/import-main-matcher.c
@@ -44,7 +44,6 @@
 #include "gnc-ui-util.h"
 #include "gnc-engine.h"
 #include "import-settings.h"
-#include "import-match-map.h"
 #include "import-match-picker.h"
 #include "import-backend.h"
 #include "import-account-matcher.h"
diff --git a/src/import-export/import-match-map.c b/src/import-export/import-match-map.c
deleted file mode 100644
index 558800d..0000000
--- a/src/import-export/import-match-map.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/********************************************************************\
- * This program is free software; you can redistribute it and/or    *
- * modify it under the terms of the GNU General Public License as   *
- * published by the Free Software Foundation; either version 2 of   *
- * the License, or (at your option) any later version.              *
- *                                                                  *
- * This program is distributed in the hope that it will be useful,  *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
- * GNU General Public License for more details.                     *
- *                                                                  *
- * You should have received a copy of the GNU General Public License*
- * along with this program; if not, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-/** @addtogroup Import_Export
-    @{ */
-/** @internal
-	@file import-match-map.c
-    @brief Generic import mapper service, maps strings->accounts
-    *
-    An import mapper service that stores Account Maps for the
-    generic importer.  This allows importers to map various
-    "strings" to Gnucash accounts in a generic manner.
-    @author Copyright (C) 2002,2003 Derek Atkins <derek at ihtfp.com>
- */
-#include "config.h"
-#include <string.h>
-#include <glib.h>
-#include "import-match-map.h"
-#include "gnc-ui-util.h"
-#include "gnc-engine.h"
-
-/********************************************************************\
- *   Constants   *
-\********************************************************************/
-
-static QofLogModule log_module = GNC_MOD_IMPORT;
-
-
-struct _GncImportMatchMap
-{
-    kvp_frame *	frame;
-    Account *	acc;
-    QofBook *	book;
-};
-
-#define IMAP_FRAME		"import-map"
-#define IMAP_FRAME_BAYES	"import-map-bayes"
-
-static GncImportMatchMap *
-gnc_imap_create_from_frame (kvp_frame *frame, Account *acc, QofBook *book)
-{
-    GncImportMatchMap *imap;
-
-    g_return_val_if_fail (frame != NULL, NULL);
-    g_return_val_if_fail ((acc && !book) || (!acc && book), NULL);
-
-    imap = g_new0(GncImportMatchMap, 1);
-    imap->frame = frame;
-
-    /* Cache the book for easy lookups; store the account/book for
-     * marking dirtiness
-     */
-    if (acc)
-        book = gnc_account_get_book (acc);
-    imap->acc = acc;
-    imap->book = book;
-
-    return imap;
-}
-
-/** Obtain an ImportMatchMap object from an Account or a Book */
-GncImportMatchMap * gnc_imap_create_from_account (Account *acc)
-{
-    kvp_frame * frame;
-
-    if (!acc) return NULL;
-    frame = xaccAccountGetSlots (acc);
-    g_return_val_if_fail (frame != NULL, NULL);
-
-    return gnc_imap_create_from_frame (frame, acc, NULL);
-}
-
-GncImportMatchMap * gnc_imap_create_from_book (QofBook *book)
-{
-    kvp_frame * frame;
-
-    if (!book) return NULL;
-    frame = qof_book_get_slots (book);
-    g_return_val_if_fail (frame != NULL, NULL);
-
-    return gnc_imap_create_from_frame (frame, NULL, book);
-}
-
-/** Destroy an import map */
-void gnc_imap_destroy (GncImportMatchMap *imap)
-{
-    if (!imap) return;
-    g_free (imap);
-}
-
-/** Clear an import map -- this removes ALL entries in the map */
-void gnc_imap_clear (GncImportMatchMap *imap)
-{
-    if (!imap) return;
-    xaccAccountBeginEdit (imap->acc);
-    /* Clear the IMAP_FRAME kvp */
-    kvp_frame_set_slot_path (imap->frame, NULL, IMAP_FRAME);
-
-    /* Clear the bayes kvp, IMAP_FRAME_BAYES */
-    kvp_frame_set_slot_path (imap->frame, NULL, IMAP_FRAME_BAYES);
-    qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
-    xaccAccountCommitEdit (imap->acc);
-}
-
-/** Look up an Account in the map */
-Account * gnc_imap_find_account (GncImportMatchMap *imap, const char *category,
-                                 const char *key)
-{
-    kvp_value *value;
-    GncGUID * guid;
-
-    if (!imap || !key) return NULL;
-    if (!category)
-    {
-        category = key;
-        key = NULL;
-    }
-
-    value = kvp_frame_get_slot_path (imap->frame, IMAP_FRAME, category, key, NULL);
-    if (!value) return NULL;
-
-    guid = kvp_value_get_guid (value);
-    return xaccAccountLookup (guid, imap->book);
-}
-
-/** Store an Account in the map */
-void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
-                           const char *key, Account *acc)
-{
-    kvp_value *value;
-
-    if (!imap || !key || !acc || (strlen (key) == 0)) return;
-    if (!category)
-    {
-        category = key;
-        key = NULL;
-    }
-    g_return_if_fail (acc != NULL);
-
-    value = kvp_value_new_guid (xaccAccountGetGUID (acc));
-    g_return_if_fail (value != NULL);
-    xaccAccountBeginEdit (imap->acc);
-    kvp_frame_set_slot_path (imap->frame, value, IMAP_FRAME, category, key, NULL);
-    qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
-    xaccAccountCommitEdit (imap->acc);
-    kvp_value_delete (value);
-
-    /* XXX Mark the account (or book) as dirty! */
-}
-
-
-
-
-/*--------------------------------------------------------------------------
- Below here is the bayes transaction to account matching system
---------------------------------------------------------------------------*/
-
-
-struct account_token_count
-{
-    char* account_name;
-    gint64 token_count; /**< occurances of a given token for this account_name */
-};
-
-/** total_count and the token_count for a given account let us calculate the
- * probability of a given account with any single token
- */
-struct token_accounts_info
-{
-    GList *accounts; /**< array of struct account_token_count */
-    gint64 total_count;
-};
-
-/** gpointer is a pointer to a struct token_accounts_info
- * \note Can always assume that keys are unique, reduces code in this function
- */
-static void buildTokenInfo(const char *key, kvp_value *value, gpointer data)
-{
-    struct token_accounts_info *tokenInfo = (struct token_accounts_info*)data;
-    struct account_token_count* this_account;
-
-    //  PINFO("buildTokenInfo: account '%s', token_count: '%ld'\n", (char*)key,
-    //			(long)kvp_value_get_gint64(value));
-
-    /* add the count to the total_count */
-    tokenInfo->total_count += kvp_value_get_gint64(value);
-
-    /* allocate a new structure for this account and it's token count */
-    this_account = (struct account_token_count*)
-                   g_new0(struct account_token_count, 1);
-
-    /* fill in the account name and number of tokens found for this account name */
-    this_account->account_name = (char*)key;
-    this_account->token_count = kvp_value_get_gint64(value);
-
-    /* append onto the glist a pointer to the new account_token_count structure */
-    tokenInfo->accounts = g_list_prepend(tokenInfo->accounts, this_account);
-}
-
-/** intermediate values used to calculate the bayes probability of a given account
-  where p(AB) = (a*b)/[a*b + (1-a)(1-b)], product is (a*b),
-  product_difference is (1-a) * (1-b)
- */
-struct account_probability
-{
-    double product; /* product of probabilities */
-    double product_difference; /* product of (1-probabilities) */
-};
-
-/** convert a hash table of account names and (struct account_probability*)
-  into a hash table of 100000x the percentage match value, ie. 10% would be
-  0.10 * 100000 = 10000
- */
-#define PROBABILITY_FACTOR 100000
-static void buildProbabilities(gpointer key, gpointer value, gpointer data)
-{
-    GHashTable *final_probabilities = (GHashTable*)data;
-    struct account_probability *account_p = (struct account_probability*)value;
-
-    /* P(AB) = A*B / [A*B + (1-A)*(1-B)]
-     * NOTE: so we only keep track of a running product(A*B*C...)
-     * and product difference ((1-A)(1-B)...)
-     */
-    gint32 probability =
-        (account_p->product /
-         (account_p->product + account_p->product_difference))
-        * PROBABILITY_FACTOR;
-
-    PINFO("P('%s') = '%d'\n", (char*)key, probability);
-
-    g_hash_table_insert(final_probabilities, key, GINT_TO_POINTER(probability));
-}
-
-/** Frees an array of the same time that buildProperties built */
-static void freeProbabilities(gpointer key, gpointer value, gpointer data)
-{
-    /* free up the struct account_probability that was allocated
-     * in gnc_imap_find_account_bayes()
-     */
-    g_free(value);
-}
-
-/** holds an account name and its corresponding integer probability
-  the integer probability is some factor of 10
- */
-struct account_info
-{
-    char* account_name;
-    gint32 probability;
-};
-
-/** Find the highest probability and the corresponding account name
-    store in data, a (struct account_info*)
-    NOTE: this is a g_hash_table_foreach() function for a hash table of entries
-    key is a  pointer to the account name, value is a gint32, 100000x
-    the probability for this account
-*/
-static void highestProbability(gpointer key, gpointer value, gpointer data)
-{
-    struct account_info *account_i = (struct account_info*)data;
-
-    /* if the current probability is greater than the stored, store the current */
-    if (GPOINTER_TO_INT(value) > account_i->probability)
-    {
-        /* Save the new highest probability and the assoaciated account name */
-        account_i->probability = GPOINTER_TO_INT(value);
-        account_i->account_name = key;
-    }
-}
-
-
-#define threshold (.90 * PROBABILITY_FACTOR) /* 90% */
-
-/** Look up an Account in the map */
-Account* gnc_imap_find_account_bayes(GncImportMatchMap *imap, GList *tokens)
-{
-    struct token_accounts_info tokenInfo; /**< holds the accounts and total
-					 * token count for a single token */
-    GList *current_token;		        /**< pointer to the current token from the
-				         * input GList *tokens */
-    GList *current_account_token;		/**< pointer to the struct
-					 * account_token_count */
-    struct account_token_count *account_c; /**< an account name and the number
-					  * of times a token has appeared
-					  * for the account */
-    struct account_probability *account_p; /**< intermediate storage of values
-					  * to compute the bayes probability
-					  * of an account */
-    GHashTable *running_probabilities = g_hash_table_new(g_str_hash, g_str_equal);
-    GHashTable *final_probabilities = g_hash_table_new(g_str_hash, g_str_equal);
-    struct account_info account_i;
-    kvp_value* value;
-    kvp_frame* token_frame;
-
-    ENTER(" ");
-
-    /* check to see if the imap is NULL */
-    if (!imap)
-    {
-        PINFO("imap is null, returning null");
-        LEAVE(" ");
-        return NULL;
-    }
-
-    /* find the probability for each account that contains any of the tokens
-     * in the input tokens list
-     */
-    for (current_token = tokens; current_token; current_token = current_token->next)
-    {
-        /* zero out the token_accounts_info structure */
-        memset(&tokenInfo, 0, sizeof(struct token_accounts_info));
-
-        PINFO("token: '%s'", (char*)current_token->data);
-
-        /* find the slot for the given token off of the source account
-         * for these tokens, search off of the IMAP_FRAME_BAYES path so
-         * we aren't looking from the parent of the entire kvp tree
-         */
-        value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
-                                        (char*)current_token->data, NULL);
-
-        /* if value is null we should skip over this token */
-        if (!value)
-            continue;
-
-        /* convert the slot(value) into a the frame that contains the
-         * list of accounts
-         */
-        token_frame = kvp_value_get_frame(value);
-
-        /* token_frame should NEVER be null */
-        if (!token_frame)
-        {
-            PERR("token '%s' has no accounts", (char*)current_token->data);
-            continue; /* skip over this token */
-        }
-
-        /* process the accounts for this token, adding the account if it
-         * doesn't already exist or adding to the existing accounts token
-         * count if it does
-         */
-        kvp_frame_for_each_slot(token_frame, buildTokenInfo, &tokenInfo);
-
-        /* for each account we have just found, see if the account already exists
-         * in the list of account probabilities, if not add it
-         */
-        for (current_account_token = tokenInfo.accounts; current_account_token;
-                current_account_token = current_account_token->next)
-        {
-            /* get the account name and corresponding token count */
-            account_c = (struct account_token_count*)current_account_token->data;
-
-            PINFO("account_c->account_name('%s'), "
-                  "account_c->token_count('%ld')/total_count('%ld')",
-                  account_c->account_name, (long)account_c->token_count,
-                  (long)tokenInfo.total_count);
-
-            account_p = g_hash_table_lookup(running_probabilities,
-                                            account_c->account_name);
-
-            /* if the account exists in the list then continue
-             * the running probablities
-             */
-            if (account_p)
-            {
-                account_p->product =
-                    ((double)account_c->token_count / (double)tokenInfo.total_count)
-                    * account_p->product;
-                account_p->product_difference =
-                    ((double)1 - ((double)account_c->token_count /
-                                  (double)tokenInfo.total_count))
-                    * account_p->product_difference;
-                PINFO("product == %f, product_difference == %f",
-                      account_p->product, account_p->product_difference);
-            }
-            else
-            {
-                /* add a new entry */
-                PINFO("adding a new entry for this account");
-                account_p = (struct account_probability*)
-                            g_new0(struct account_probability, 1);
-
-                /* set the product and product difference values */
-                account_p->product = ((double)account_c->token_count /
-                                      (double)tokenInfo.total_count);
-                account_p->product_difference =
-                    (double)1 - ((double)account_c->token_count /
-                                 (double)tokenInfo.total_count);
-
-                PINFO("product == %f, product_difference == %f",
-                      account_p->product, account_p->product_difference);
-
-                /* add the account name and (struct account_probability*)
-                 * to the hash table */
-                g_hash_table_insert(running_probabilities,
-                                    account_c->account_name, account_p);
-            }
-        } /* for all accounts in tokenInfo */
-
-        /* free the data in tokenInfo */
-        for (current_account_token = tokenInfo.accounts; current_account_token;
-                current_account_token = current_account_token->next)
-        {
-            /* free up each struct account_token_count we allocated */
-            g_free((struct account_token_count*)current_account_token->data);
-        }
-
-        g_list_free(tokenInfo.accounts); /* free the accounts GList */
-    }
-
-    /* build a hash table of account names and their final probabilities
-     * from each entry in the running_probabilties hash table
-     */
-    g_hash_table_foreach(running_probabilities, buildProbabilities,
-                         final_probabilities);
-
-    /* find the highest probabilty and the corresponding account */
-    memset(&account_i, 0, sizeof(struct account_info));
-    g_hash_table_foreach(final_probabilities, highestProbability, &account_i);
-
-    /* free each element of the running_probabilities hash */
-    g_hash_table_foreach(running_probabilities, freeProbabilities, NULL);
-
-    /* free the hash tables */
-    g_hash_table_destroy(running_probabilities);
-    g_hash_table_destroy(final_probabilities);
-
-    PINFO("highest P('%s') = '%d'",
-          account_i.account_name ? account_i.account_name : "(null)",
-          account_i.probability);
-
-    /* has this probability met our threshold? */
-    if (account_i.probability >= threshold)
-    {
-        PINFO("found match");
-        LEAVE(" ");
-        return gnc_account_lookup_by_full_name(gnc_book_get_root_account(imap->book),
-                                               account_i.account_name);
-    }
-
-    PINFO("no match");
-    LEAVE(" ");
-
-    return NULL; /* we didn't meet our threshold, return NULL for an account */
-}
-
-
-/** Updates the imap for a given account using a list of tokens */
-void gnc_imap_add_account_bayes(GncImportMatchMap *imap, GList *tokens, Account *acc)
-{
-    GList *current_token;
-    kvp_value *value;
-    gint64 token_count;
-    char* account_fullname;
-    kvp_value *new_value; /* the value that will be added back into the kvp tree */
-
-    ENTER(" ");
-
-    /* if imap is null return */
-    if (!imap)
-    {
-        LEAVE(" ");
-        return;
-    }
-
-    g_return_if_fail (acc != NULL);
-    account_fullname = gnc_account_get_full_name(acc);
-    xaccAccountBeginEdit (imap->acc);
-
-    PINFO("account name: '%s'\n", account_fullname);
-
-    /* process each token in the list */
-    for (current_token = g_list_first(tokens); current_token;
-            current_token = current_token->next)
-    {
-        /* Jump to next iteration if the pointer is not valid or if the
-        	 string is empty. In HBCI import we almost always get an empty
-        	 string, which doesn't work in the kvp loopkup later. So we
-        	 skip this case here. */
-        if (!current_token->data || (*((char*)current_token->data) == '\0'))
-            continue;
-
-        /* start off with no tokens for this account */
-        token_count = 0;
-
-        PINFO("adding token '%s'\n", (char*)current_token->data);
-
-        /* is this token/account_name already in the kvp tree? */
-        value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
-                                        (char*)current_token->data, account_fullname,
-                                        NULL);
-
-        /* if the token/account is already in the tree, read the current
-         * value from the tree and use this for the basis of the value we
-         * are putting back
-         */
-        if (value)
-        {
-            PINFO("found existing value of '%ld'\n",
-                  (long)kvp_value_get_gint64(value));
-
-            /* convert this value back into an integer */
-            token_count += kvp_value_get_gint64(value);
-        }
-
-        /* increment the token count */
-        token_count++;
-
-        /* create a new value */
-        new_value = kvp_value_new_gint64(token_count);
-
-        /* insert the value into the kvp tree at
-         * /imap->frame/IMAP_FRAME/token_string/account_name_string
-         */
-        kvp_frame_set_slot_path(imap->frame, new_value, IMAP_FRAME_BAYES,
-                                (char*)current_token->data, account_fullname, NULL);
-        /* kvp_frame_set_slot_path() copied the value so we
-         * need to delete this one ;-) */
-        kvp_value_delete(new_value);
-    }
-
-    /* free up the account fullname string */
-    qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
-    xaccAccountCommitEdit (imap->acc);
-    g_free(account_fullname);
-
-    LEAVE(" ");
-}
-
-/** @} */
diff --git a/src/import-export/import-match-map.h b/src/import-export/import-match-map.h
deleted file mode 100644
index 88c6945..0000000
--- a/src/import-export/import-match-map.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/********************************************************************\
- * This program is free software; you can redistribute it and/or    *
- * modify it under the terms of the GNU General Public License as   *
- * published by the Free Software Foundation; either version 2 of   *
- * the License, or (at your option) any later version.              *
- *                                                                  *
- * This program is distributed in the hope that it will be useful,  *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
- * GNU General Public License for more details.                     *
- *                                                                  *
- * You should have received a copy of the GNU General Public License*
- * along with this program; if not, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-/** @addtogroup Import_Export
-    @{ */
-/** @file import-match-map.h
-    @brief Generic import mapper service, maps strings->accounts
-    *
-    An import mapper service that stores Account Maps for the
-    generic importer.  This allows importers to map various
-    "strings" to Gnucash accounts in a generic manner.
-    @author Copyright (C) 2002,2003 Derek Atkins <derek at ihtfp.com>
- */
-#ifndef GNC_IMPORT_MATCH_MAP_H
-#define GNC_IMPORT_MATCH_MAP_H
-
-typedef struct _GncImportMatchMap GncImportMatchMap;
-
-#include "Account.h"
-
-/** @{
-Obtain an ImportMatchMap object from an Account or a Book */
-GncImportMatchMap * gnc_imap_create_from_account (Account *acc);
-GncImportMatchMap * gnc_imap_create_from_book (QofBook *book);
-/*@}*/
-
-/** Destroy an import map. But all stored entries will still continue
- to exist in the underlying kvp frame of the account or book. */
-void gnc_imap_destroy (GncImportMatchMap *imap);
-
-/** Clear an import map -- this removes ALL entries in the map */
-void gnc_imap_clear (GncImportMatchMap *imap);
-
-/** Look up an Account in the map */
-Account* gnc_imap_find_account(GncImportMatchMap *imap, const char* category,
-                               const char *key);
-
-/** Store an Account in the map. This mapping is immediatly stored in
-  the underlying kvp frame, regardless of whether the MatchMap is
-  destroyed later or not. */
-void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
-                           const char *key, Account *acc);
-
-/** Look up an Account in the map from a GList* of pointers to strings(tokens)
-  from the current transaction */
-Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList* tokens);
-
-/** Store an Account in the map. This mapping is immediatly stored in
-  the underlying kvp frame, regardless of whether the MatchMap is
-  destroyed later or not. */
-void gnc_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
-                                 Account *acc);
-
-
-/** @name Some well-known categories
-
-  NOTE: You DO NOT have to use these values in your importer -- these
-  are just "well known" values, not "mandatory" values.  You are free
-  to use these if they apply, map your own fields to these labels, or
-  create your own category strings.
-*/
-/** @{*/
-#define GNCIMPORT_DESC	"desc"
-#define GNCIMPORT_MEMO	"memo"
-#define GNCIMPORT_PAYEE	"payee"
-/**@}*/
-
-#endif /* GNC_IMPORT_MATCH_MAP_H */
-/**@}*/
diff --git a/src/import-export/import-utilities.c b/src/import-export/import-utilities.c
index 51b8f53..60bf1ae 100644
--- a/src/import-export/import-utilities.c
+++ b/src/import-export/import-utilities.c
@@ -40,42 +40,36 @@
  * Account, Transaction and Split
 \********************************************************************/
 
-const gchar * gnc_import_get_acc_online_id(Account * account)
+const gchar * gnc_import_get_acc_online_id (Account * account)
 {
-    kvp_frame * frame;
-    frame = xaccAccountGetSlots(account);
-    return kvp_frame_get_string(frame, "online_id");
+    gchar *id = NULL;
+    qof_instance_get (QOF_INSTANCE (account), "online-id", &id, NULL);
+    return id;
 }
 
 /* Used in the midst of editing a transaction; make it save the
  * account data. */
-void gnc_import_set_acc_online_id(Account * account,
-                                  const gchar * string_value)
+void gnc_import_set_acc_online_id (Account *account, const gchar *id)
 {
-    kvp_frame * frame;
     g_return_if_fail (account != NULL);
-    frame = xaccAccountGetSlots(account);
     xaccAccountBeginEdit (account);
-    kvp_frame_set_str(frame, "online_id", string_value);
-    qof_instance_set_dirty (QOF_INSTANCE (account));
+    qof_instance_set (QOF_INSTANCE (account), "online-id", &id, NULL);
     xaccAccountCommitEdit (account);
 }
 
-const gchar * gnc_import_get_trans_online_id(Transaction * transaction)
+const gchar * gnc_import_get_trans_online_id (Transaction * transaction)
 {
-    kvp_frame * frame;
-    frame = xaccTransGetSlots(transaction);
-    return kvp_frame_get_string(frame, "online_id");
+    gchar *id = NULL;
+    qof_instance_get (QOF_INSTANCE (transaction), "online-id", &id, NULL);
+    return id;
 }
 /* Not actually used */
-void gnc_import_set_trans_online_id(Transaction * transaction,
-                                    const gchar * string_value)
+void gnc_import_set_trans_online_id (Transaction *transaction,
+				     const gchar *id)
 {
-    kvp_frame * frame;
+    g_return_if_fail (transaction != NULL);
     xaccTransBeginEdit (transaction);
-    frame = xaccTransGetSlots(transaction);
-    kvp_frame_set_str (frame, "online_id", string_value);
-    qof_instance_set_dirty (QOF_INSTANCE (transaction));
+    qof_instance_set (QOF_INSTANCE (transaction), "online-id", &id, NULL);
     xaccTransCommitEdit (transaction);
 }
 
@@ -86,24 +80,19 @@ gboolean gnc_import_trans_has_online_id(Transaction * transaction)
     return (online_id != NULL && strlen(online_id) > 0);
 }
 
-const gchar * gnc_import_get_split_online_id(Split * split)
+const gchar * gnc_import_get_split_online_id (Split * split)
 {
-    kvp_frame * frame;
-    frame = xaccSplitGetSlots(split);
-    return kvp_frame_get_string(frame, "online_id");
+    gchar *id = NULL;
+    qof_instance_get (QOF_INSTANCE (split), "online-id", &id, NULL);
+    return id;
 }
 /* Used several places in a transaction edit where many other
  * parameters are also being set, so individual commits wouldn't be
- * appropriate. */
-void gnc_import_set_split_online_id(Split * split,
-                                    const gchar * string_value)
+ * appropriate. Besides, there isn't a function for one.*/
+void gnc_import_set_split_online_id (Split *split, const gchar *id)
 {
-    kvp_frame * frame;
-    xaccTransBeginEdit (xaccSplitGetParent (split));
-    frame = xaccSplitGetSlots(split);
-    kvp_frame_set_str (frame, "online_id", string_value);
-    qof_instance_set_dirty (QOF_INSTANCE (split));
-    xaccTransCommitEdit (xaccSplitGetParent (split));
+    g_return_if_fail (split != NULL);
+    qof_instance_set (QOF_INSTANCE (split), "online-id", &id, NULL);
 }
 
 gboolean gnc_import_split_has_online_id(Split * split)
diff --git a/src/import-export/log-replay/gnc-log-replay.c b/src/import-export/log-replay/gnc-log-replay.c
index 5577571..bbd26d7 100644
--- a/src/import-export/log-replay/gnc-log-replay.c
+++ b/src/import-export/log-replay/gnc-log-replay.c
@@ -45,6 +45,9 @@
 
 #define GNC_PREFS_GROUP "dialogs.log-replay"
 
+/* EFFECTIVE FRIEND FUNCTION */
+void qof_instance_set_guid (gpointer inst, const GncGUID *guid);
+
 /* NW: If you want a new log_module, just define
 a unique string either in gnc-engine.h or
 locally.*/
@@ -435,7 +438,8 @@ static void  process_trans_record(  FILE *log_file)
                             xaccTransBeginEdit(trans);
                         }
 
-                        xaccTransSetGUID (trans, &(record.trans_guid));
+                        qof_instance_set_guid (QOF_INSTANCE (trans),
+					       &(record.trans_guid));
                         /*Fill the transaction info*/
                         if (record.date_entered_present)
                         {
diff --git a/src/import-export/ofx/gnc-ofx-kvp.c b/src/import-export/ofx/gnc-ofx-kvp.c
index 05b26e7..e4e5d6f 100644
--- a/src/import-export/ofx/gnc-ofx-kvp.c
+++ b/src/import-export/ofx/gnc-ofx-kvp.c
@@ -26,44 +26,34 @@
 #include "config.h"
 #include "gnc-ofx-kvp.h"
 
-static const char *KEY_ASSOC_INCOME_ACCOUNT = "ofx/associated-income-account";
+static void force_account_dirty(Account *acct);
+/* OUTSIDE SLOT ACCESS */
 
 
 Account *gnc_ofx_kvp_get_assoc_account(const Account* investment_account)
 {
-    kvp_frame * acc_frame;
-    kvp_value * kvp_val;
     Account *result = NULL;
-
+    GncGUID *income_guid= NULL;
     g_assert(investment_account);
-
-    acc_frame = xaccAccountGetSlots(investment_account);
-    kvp_val = kvp_frame_get_slot(acc_frame, KEY_ASSOC_INCOME_ACCOUNT);
-    if (kvp_val != NULL)
-    {
-        result = xaccAccountLookup(kvp_value_get_guid(kvp_val),
-                                   gnc_account_get_book(investment_account));
-    }
-    return result;
+    qof_instance_get (QOF_INSTANCE (investment_account),
+		      "ofx-income-account", &income_guid,
+		      NULL);
+    return xaccAccountLookup(income_guid,
+			       gnc_account_get_book(investment_account));
 }
 
 void gnc_ofx_kvp_set_assoc_account(Account* investment_account,
                                    const Account *income_account)
 {
-    kvp_frame * acc_frame;
-    kvp_value * kvp_val;
     const GncGUID * income_acc_guid;
 
     g_assert(investment_account);
     g_assert(income_account);
 
-    acc_frame = xaccAccountGetSlots(investment_account);
-    g_assert(acc_frame); // Must not be NULL, but the QofInstance doc is unclear about this
     income_acc_guid = xaccAccountGetGUID(income_account);
-    kvp_val = kvp_value_new_guid(income_acc_guid);
     xaccAccountBeginEdit(investment_account);
-    kvp_frame_set_slot_nc(acc_frame, KEY_ASSOC_INCOME_ACCOUNT,
-                          kvp_val);
-    qof_instance_set_dirty(QOF_INSTANCE (investment_account));
+    qof_instance_set (QOF_INSTANCE (investment_account),
+		      "ofx-income-account", income_acc_guid,
+		      NULL);
     xaccAccountCommitEdit(investment_account);
 }
diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp
index c52b8e8..881d029 100644
--- a/src/libqof/qof/kvp_frame.cpp
+++ b/src/libqof/qof/kvp_frame.cpp
@@ -1665,4 +1665,192 @@ kvp_frame_get_hash(const KvpFrame *frame)
     return frame->hash;
 }
 
+static GValue *gvalue_from_kvp_value (KvpValue*);
+static KvpValue *kvp_value_from_gvalue (const GValue*);
+
+static void
+gvalue_list_from_kvp_value (KvpValue *kval, gpointer pList)
+{
+    GList **gvlist = NULL;
+    GValue *gval = gvalue_from_kvp_value (kval);
+    gvlist =  (GList**)pList;
+    if (G_VALUE_TYPE (gval))
+	*gvlist = g_list_prepend (*gvlist, gval);
+}
+
+static void
+kvp_value_list_from_gvalue (GValue *gval, gpointer pList)
+{
+    GList **kvplist = (GList**)pList;
+    KvpValue *kvp;
+    if (!(gval && G_VALUE_TYPE (gval)))
+	return;
+    kvp = kvp_value_from_gvalue (gval);
+    *kvplist = g_list_prepend (*kvplist, kvp);
+}
+
+static GValue*
+gvalue_from_kvp_value (KvpValue *kval)
+{
+    GValue *val;
+    gnc_numeric num;
+    Timespec tm;
+    GDate gdate;
+
+    if (kval == NULL) return NULL;
+    val = g_slice_new0 (GValue);
+
+    switch (kval->type)
+    {
+	case KVP_TYPE_GINT64:
+	    g_value_init (val, G_TYPE_INT64);
+	    g_value_set_int64 (val, kvp_value_get_gint64 (kval));
+	    break;
+	case KVP_TYPE_DOUBLE:
+	    g_value_init (val, G_TYPE_DOUBLE);
+	    g_value_set_double (val, kvp_value_get_double (kval));
+	    break;
+	case KVP_TYPE_NUMERIC:
+	    g_value_init (val, GNC_TYPE_NUMERIC);
+	    num = kvp_value_get_numeric (kval);
+	    g_value_set_boxed (val, &num);
+	    break;
+	case KVP_TYPE_STRING:
+	    g_value_init (val, G_TYPE_STRING);
+	    g_value_set_string (val, kvp_value_get_string (kval));
+	    break;
+	case KVP_TYPE_GUID:
+	    g_value_init (val, GNC_TYPE_GUID);
+	    g_value_set_boxed (val, kvp_value_get_guid (kval));
+	    break;
+	case KVP_TYPE_TIMESPEC:
+	    g_value_init (val, GNC_TYPE_TIMESPEC);
+	    tm = kvp_value_get_timespec (kval);
+	    g_value_set_boxed (val, &tm);
+	    break;
+	case KVP_TYPE_BINARY:
+	    PWARN ("Error! Don't use Kvp Binary!");
+	    g_slice_free (GValue, val);
+	    val = NULL;
+	    break;
+	case KVP_TYPE_GDATE:
+	    g_value_init (val, G_TYPE_DATE);
+	    gdate = kvp_value_get_gdate (kval);
+	    g_value_set_boxed (val, &gdate);
+	    break;
+	case KVP_TYPE_GLIST:
+	{
+	    GList *gvalue_list = NULL;
+	    GList *kvp_list = kvp_value_get_glist (kval);
+	    g_list_foreach (kvp_list, (GFunc)gvalue_list_from_kvp_value, &gvalue_list);
+	    g_value_init (val, GNC_TYPE_VALUE_LIST);
+	    gvalue_list = g_list_reverse (gvalue_list);
+	    g_value_set_boxed (val, gvalue_list);
+	    break;
+	}
+/* No transfer of KVP frames outside of QofInstance-derived classes! */
+	case KVP_TYPE_FRAME:
+	    PWARN ("Error! Attempt to transfer KvpFrame!");
+	default:
+	    PWARN ("Error! Invalid KVP Transfer Request!");
+	    g_slice_free (GValue, val);
+	    val = NULL;
+	    break;
+    }
+    return val;
+}
+
+KvpValue*
+kvp_value_from_gvalue (const GValue *gval)
+{
+    KvpValue *val = NULL;
+    GType type = G_VALUE_TYPE (gval);
+    g_return_val_if_fail (G_VALUE_TYPE (gval), NULL);
+
+    if (type == G_TYPE_INT64)
+	val = kvp_value_new_gint64 (g_value_get_int64 (gval));
+    else if (type == G_TYPE_DOUBLE)
+	val = kvp_value_new_double (g_value_get_double (gval));
+    else if (type == GNC_TYPE_NUMERIC)
+	val = kvp_value_new_numeric (*(gnc_numeric*)g_value_get_boxed (gval));
+    else if (type == G_TYPE_STRING)
+	val = kvp_value_new_string (g_value_get_string (gval));
+    else if (type == GNC_TYPE_GUID)
+	val = kvp_value_new_guid ((GncGUID*)g_value_get_boxed (gval));
+    else if (type == GNC_TYPE_TIMESPEC)
+	val = kvp_value_new_timespec (*(Timespec*)g_value_get_boxed (gval));
+    else if (type == G_TYPE_DATE)
+	val = kvp_value_new_gdate (*(GDate*)g_value_get_boxed (gval));
+    else if (type == GNC_TYPE_VALUE_LIST)
+    {
+	GList *gvalue_list = (GList*)g_value_get_boxed (gval);
+	GList *kvp_list = NULL;
+	g_list_foreach (gvalue_list, (GFunc)kvp_value_list_from_gvalue, &kvp_list);
+	kvp_list = g_list_reverse (kvp_list);
+	val = kvp_value_new_glist_nc (kvp_list);
+//	g_list_free_full (gvalue_list, (GDestroyNotify)g_value_unset);
+//	gvalue_list = NULL;
+    }
+    else
+	PWARN ("Error! Don't know how to make a KvpValue from a %s",
+	       G_VALUE_TYPE_NAME (gval));
+
+    return val;
+}
+
+GValue*
+kvp_frame_get_gvalue (KvpFrame *frame, const gchar *key)
+{
+    KvpValue *kval = kvp_frame_get_value (frame, key);
+    GValue *value = gvalue_from_kvp_value (kval);
+    return value;
+}
+
+void
+kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *value)
+{
+  kvp_frame_set_value_nc (frame, key, kvp_value_from_gvalue (value));
+}
+
+static GValue*
+gnc_gvalue_copy (GValue *src, gpointer uData)
+{
+    GValue *dest = g_value_init (g_slice_new0 (GValue), G_VALUE_TYPE (src));
+    g_value_copy (src, dest);
+    return dest;
+}
+
+void
+gnc_gvalue_free (GValue *val)
+{
+    if (val == NULL || ! G_IS_VALUE (val)) return;
+    g_value_unset (val);
+    g_slice_free (GValue, val);
+}
+
+static GList*
+gnc_value_list_copy (GList *list)
+{
+    return g_list_copy_deep (list, (GCopyFunc)gnc_gvalue_copy, NULL);
+}
+
+static void
+gnc_value_list_free (GList *list)
+{
+    g_list_free_full (list, (GDestroyNotify)gnc_gvalue_free);
+}
+
+GType
+gnc_value_list_get_type (void)
+{
+    static GType type = 0;
+    if (type == 0)
+    {
+	type = g_boxed_type_register_static ("gnc_value_list",
+					     (GBoxedCopyFunc)gnc_value_list_copy,
+					     (GBoxedFreeFunc)gnc_value_list_free);
+    }
+    return type;
+}
+
 /* ========================== END OF FILE ======================= */
diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h
index 440377a..12f9ab5 100644
--- a/src/libqof/qof/kvp_frame.h
+++ b/src/libqof/qof/kvp_frame.h
@@ -594,6 +594,59 @@ gchar* kvp_frame_to_string(const KvpFrame *frame);
 gchar* binary_to_string(const void *data, guint32 size);
 GHashTable* kvp_frame_get_hash(const KvpFrame *frame);
 
+/** KvpItem: GValue Exchange
+ * \brief Transfer of KVP to and from GValue, with the key
+ *
+ * Used to parameterize KVP <-> GValue exchanges.
+ */
+typedef struct
+{
+    const gchar   *key;
+    GValue        *value;
+}KvpItem;
+
+/** Return a KvpItem containing the value of a KvpFrame
+ *
+ * Structure types (gnc_numeric, Timespec) are converted to pointers
+ * and must be extracted with g_value_get_boxed. A KVP_TYPE_GLIST will
+ * have all of its contents converted from KvpValues to GValues, so
+ * the return type will be a GValue containing a GList of GValue*, not
+ * GValue.  Use gnc_value_list_free() to free such a list if you take
+ * it out of the GValue.
+ *
+ * \param frame: (transfer-none) The KvpFrame retrieved with kvp_get_frame_foo()
+ * \param key: (transfer-none) A slash-delimited string with the path to
+ * the stored value. Must not be NULL or empty.
+ * \return (transfer-full) A KvpItem* which must be freed with kvp_item_free().
+ */
+GValue *kvp_frame_get_gvalue (KvpFrame *frame, const gchar *key);
+
+/** Replace or create a Kvp slot from a KvpItem
+ *
+ * Structure types (gnc_numeric, Timespec) should be stored as
+ * boxed-type pointers in the GValue with the appropriate type from
+ * qof.h. Lists should be stored as a GValue containing a GList of
+ * GValues of type convertable to KvpValues. Unsupported types will
+ * emit a warning message and will be skipped.
+ *
+ * \param frame: (transfer none) The KvpFrame into which the value
+ * will be added.
+ * \param key: (transfer none) The subkey of the frame at which to
+ * store the value
+ * \param value: GValue containing the paramter to store.
+ */
+void kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *value);
+
+/**
+ * \brief Convenience function to release the value in a GValue
+ * acquired by kvp_frame_get_gvalue and to free the GValue.
+ * \param value: A GValue* created by kvp_frame_get_gvalue
+ */
+void gnc_gvalue_free (GValue *value);
+
+GType gnc_value_list_get_type (void);
+#define GNC_TYPE_VALUE_LIST (gnc_value_list_get_type ())
+
 /** @} */
 #ifdef __cplusplus
 }
diff --git a/src/libqof/qof/qof.h b/src/libqof/qof/qof.h
index f34dc2e..68ad9ff 100644
--- a/src/libqof/qof/qof.h
+++ b/src/libqof/qof/qof.h
@@ -84,7 +84,6 @@
 #include "kvp-util-p.h"
 #include "qofbackend.h"
 #include "qofid-p.h"
-#include "qofinstance-p.h"
 #include "qofbook.h"
 #include "qofclass.h"
 #include "qofevent.h"
diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp
index 0ae2b21..a21d04b 100644
--- a/src/libqof/qof/qofbook.cpp
+++ b/src/libqof/qof/qofbook.cpp
@@ -58,8 +58,28 @@ extern "C"
 #include "qofbookslots.h"
 
 static QofLogModule log_module = QOF_MOD_ENGINE;
+#define AB_KEY "hbci"
+#define AB_TEMPLATES "template-list"
+
+enum
+{
+    PROP_0,
+//  PROP_ROOT_ACCOUNT,		/* Table */
+//  PROP_ROOT_TEMPLATE,		/* Table */
+    PROP_OPT_TRADING_ACCOUNTS,	/* KVP */
+    PROP_OPT_AUTO_READONLY_DAYS,/* KVP */
+    PROP_OPT_NUM_FIELD_SOURCE,	/* KVP */
+    PROP_OPT_DEFAULT_BUDGET,	/* KVP */
+    PROP_OPT_FY_END,		/* KVP */
+    PROP_AB_TEMPLATES,		/* KVP */
+    N_PROPERTIES		/* Just a counter */
+};
+
+QOF_GOBJECT_GET_TYPE(QofBook, qof_book, QOF_TYPE_INSTANCE, {});
+QOF_GOBJECT_DISPOSE(qof_book);
+QOF_GOBJECT_FINALIZE(qof_book);
 
-QOF_GOBJECT_IMPL(qof_book, QofBook, QOF_TYPE_INSTANCE);
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
 
 /* ====================================================================== */
 /* constructor / destructor */
@@ -90,6 +110,186 @@ qof_book_init (QofBook *book)
     book->version = 0;
 }
 
+static void
+qof_book_get_property (GObject* object,
+		       guint prop_id,
+		       GValue* value,
+		       GParamSpec* pspec)
+{
+    QofBook *book;
+    gchar *key;
+
+    g_return_if_fail (QOF_IS_BOOK (object));
+    book = QOF_BOOK (object);
+    switch (prop_id)
+    {
+    case PROP_OPT_TRADING_ACCOUNTS:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_TRADING_ACCOUNTS);
+	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
+    case PROP_OPT_AUTO_READONLY_DAYS:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_AUTO_READONLY_DAYS);
+	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
+    case PROP_OPT_NUM_FIELD_SOURCE:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_NUM_FIELD_SOURCE);
+	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
+    case PROP_OPT_DEFAULT_BUDGET:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_DEFAULT_BUDGET);
+	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+    case PROP_OPT_FY_END:
+	key = "fy_end";
+	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
+	break;
+    case PROP_AB_TEMPLATES:
+	key = AB_KEY "/" AB_TEMPLATES;
+	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
+	break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+qof_book_set_property (GObject      *object,
+		       guint         prop_id,
+		       const GValue *value,
+		       GParamSpec   *pspec)
+{
+    QofBook *book;
+    gchar *key;
+
+    g_return_if_fail (QOF_IS_BOOK (object));
+    book = QOF_BOOK (object);
+    g_assert (qof_instance_get_editlevel(book));
+
+    switch (prop_id)
+    {
+    case PROP_OPT_TRADING_ACCOUNTS:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_TRADING_ACCOUNTS);
+	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
+    case PROP_OPT_AUTO_READONLY_DAYS:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_AUTO_READONLY_DAYS);
+	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
+    case PROP_OPT_NUM_FIELD_SOURCE:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_NUM_FIELD_SOURCE);
+	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
+    case PROP_OPT_DEFAULT_BUDGET:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_DEFAULT_BUDGET);
+	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
+    case PROP_OPT_FY_END:
+	key = "fy_end";
+	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
+	break;
+    case PROP_AB_TEMPLATES:
+	key = AB_KEY "/" AB_TEMPLATES;
+	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
+	break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+qof_book_class_init (QofBookClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+    gobject_class->dispose = qof_book_dispose;
+    gobject_class->finalize = qof_book_finalize;
+    gobject_class->get_property = qof_book_get_property;
+    gobject_class->set_property = qof_book_set_property;
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_OPT_TRADING_ACCOUNTS,
+     g_param_spec_string("trading-accts",
+                         "Use Trading Accounts",
+			 "Scheme true ('t') or NULL. If 't', then the book "
+			 "uses trading accounts for managing multiple-currency "
+			 "transactions.",
+                         NULL,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_OPT_NUM_FIELD_SOURCE,
+     g_param_spec_string("split-action-num-field",
+                         "Use Split-Action in the Num Field",
+			 "Scheme true ('t') or NULL. If 't', then the book "
+			 "will put the split action value in the Num field.",
+                         NULL,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_OPT_AUTO_READONLY_DAYS,
+     g_param_spec_double("autoreadonly-days",
+                         "Transaction Auto-read-only Days",
+			 "Prevent editing of transactions posted more than "
+			 "this many days ago.",
+			 0,
+                         G_MAXDOUBLE,
+			 0,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
+     PROP_OPT_DEFAULT_BUDGET,
+     g_param_spec_boxed("default-budget",
+                        "Book Default Budget",
+                        "The default Budget for this book.",
+                        GNC_TYPE_GUID,
+                        G_PARAM_READWRITE));
+    g_object_class_install_property
+    (gobject_class,
+     PROP_OPT_FY_END,
+     g_param_spec_boxed("fy-end",
+                        "Book Fiscal Year End",
+                        "A GDate with a bogus year having the last Month and "
+			"Day of the Fiscal year for the book.",
+                        G_TYPE_DATE,
+                        G_PARAM_READWRITE));
+    g_object_class_install_property
+    (gobject_class,
+     PROP_AB_TEMPLATES,
+     g_param_spec_boxed("ab-templates",
+                        "AQBanking Template List",
+                        "A GList of AQBanking Templates",
+                        GNC_TYPE_VALUE_LIST,
+                        G_PARAM_READWRITE));
+}
+
 QofBook *
 qof_book_new (void)
 {
@@ -161,6 +361,7 @@ qof_book_destroy (QofBook *book)
 
     LEAVE ("book=%p", book);
 }
+
 /* ====================================================================== */
 
 gboolean
@@ -253,20 +454,7 @@ qof_book_set_backend (QofBook *book, QofBackend *be)
     LEAVE (" ");
 }
 
-void qof_book_kvp_changed (QofBook *book)
-{
-    qof_book_begin_edit(book);
-    qof_instance_set_dirty (QOF_INSTANCE (book));
-    qof_book_commit_edit(book);
-}
-
 /* ====================================================================== */
-
-KvpFrame *qof_book_get_slots(const QofBook *book)
-{
-    return qof_instance_get_slots(QOF_INSTANCE(book));
-}
-
 /* Store arbitrary pointers in the QofBook for data storage extensibility */
 /* XXX if data is NULL, we should remove the key from the hash table!
  */
@@ -389,7 +577,7 @@ qof_book_get_counter (QofBook *book, const char *counter_name)
     }
 
     /* Use the KVP in the book */
-    kvp = qof_book_get_slots (book);
+    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
 
     if (!kvp)
     {
@@ -441,7 +629,7 @@ qof_book_increment_and_format_counter (QofBook *book, const char *counter_name)
     counter++;
 
     /* Get the KVP from the current book */
-    kvp = qof_book_get_slots (book);
+    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
 
     if (!kvp)
     {
@@ -490,7 +678,7 @@ qof_book_get_counter_format(const QofBook *book, const char *counter_name)
     }
 
     /* Get the KVP from the current book */
-    kvp = qof_book_get_slots (book);
+    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
 
     if (!kvp)
     {
@@ -641,19 +829,10 @@ qof_book_validate_counter_format_internal(const gchar *p,
 gboolean
 qof_book_use_trading_accounts (const QofBook *book)
 {
-    const char *opt;
-    kvp_value *kvp_val;
-
-    kvp_val = kvp_frame_get_slot_path (qof_book_get_slots (book),
-                                       KVP_OPTION_PATH,
-                                       OPTION_SECTION_ACCOUNTS,
-                                       OPTION_NAME_TRADING_ACCOUNTS,
-                                       NULL);
-    if (kvp_val == NULL)
-        return FALSE;
-
-    opt = kvp_value_get_string (kvp_val);
-
+    const char *opt = NULL;
+    qof_instance_get (QOF_INSTANCE (book),
+		      "trading-accts", &opt,
+		      NULL);
     if (opt && opt[0] == 't' && opt[1] == 0)
         return TRUE;
     return FALSE;
@@ -664,19 +843,10 @@ qof_book_use_trading_accounts (const QofBook *book)
 gboolean
 qof_book_use_split_action_for_num_field (const QofBook *book)
 {
-    const char *opt;
-    kvp_value *kvp_val;
-
-    g_assert(book);
-    kvp_val = kvp_frame_get_slot_path (qof_book_get_slots (book),
-                                       KVP_OPTION_PATH,
-                                       OPTION_SECTION_ACCOUNTS,
-                                       OPTION_NAME_NUM_FIELD_SOURCE,
-                                       NULL);
-    if (kvp_val == NULL)
-        return FALSE;
-
-    opt = kvp_value_get_string (kvp_val);
+    const char *opt = NULL;
+    qof_instance_get (QOF_INSTANCE (book),
+		      "split-action-num-field", &opt,
+		      NULL);
 
     if (opt && opt[0] == 't' && opt[1] == 0)
         return TRUE;
@@ -692,21 +862,13 @@ gboolean qof_book_uses_autoreadonly (const QofBook *book)
 gint qof_book_get_num_days_autoreadonly (const QofBook *book)
 {
     kvp_value *kvp_val;
-    double tmp;
-    g_assert(book);
-    kvp_val = kvp_frame_get_slot_path (qof_book_get_slots (book),
-                                       KVP_OPTION_PATH,
-                                       OPTION_SECTION_ACCOUNTS,
-                                       OPTION_NAME_AUTO_READONLY_DAYS,
-                                       NULL);
+    double tmp = 0;
+    KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
 
-    if (kvp_val == NULL)
-    {
-        //PWARN("kvp_val for slot '%s' is NULL", OPTION_NAME_AUTO_READONLY_DAYS);
-        return 0;
-    }
-
-    tmp = kvp_value_get_double (kvp_val);
+    g_assert(book);
+    qof_instance_get (QOF_INSTANCE (book),
+		      "autoreadonly-days", &tmp,
+		      NULL);
     return (gint) tmp;
 }
 
@@ -728,14 +890,16 @@ GDate* qof_book_get_autoreadonly_gdate (const QofBook *book)
 const char*
 qof_book_get_string_option(const QofBook* book, const char* opt_name)
 {
-    return kvp_frame_get_string(qof_book_get_slots(book), opt_name);
+    return kvp_frame_get_string(qof_instance_get_slots(QOF_INSTANCE (book)),
+				opt_name);
 }
 
 void
 qof_book_set_string_option(QofBook* book, const char* opt_name, const char* opt_val)
 {
     qof_book_begin_edit(book);
-    kvp_frame_set_string(qof_book_get_slots(book), opt_name, opt_val);
+    kvp_frame_set_string(qof_instance_get_slots(QOF_INSTANCE (book)),
+						opt_name, opt_val);
     qof_instance_set_dirty (QOF_INSTANCE (book));
     qof_book_commit_edit(book);
 }
@@ -752,7 +916,53 @@ static void commit_err (G_GNUC_UNUSED QofInstance *inst, QofBackendError errcode
 //  gnc_engine_signal_commit_error( errcode );
 }
 
-static void noop (G_GNUC_UNUSED QofInstance *inst) {}
+#define GNC_FEATURES "/features/"
+static void
+add_feature_to_hash (const gchar *key, KvpValue *value, gpointer user_data)
+{
+    gchar *descr = kvp_value_get_string (value);
+    g_hash_table_insert (*(GHashTable**)user_data, (gchar*)key, descr);
+}
+
+GHashTable *
+qof_book_get_features (QofBook *book)
+{
+    KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
+    GHashTable *features = g_hash_table_new (g_str_hash, g_str_equal);
+
+    frame = kvp_frame_get_frame (frame, GNC_FEATURES);
+    kvp_frame_for_each_slot (frame, &add_feature_to_hash, &features);
+    return features;
+}
+
+void
+qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr)
+{
+    KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
+    gchar *path = g_strconcat (GNC_FEATURES, key, NULL);
+    qof_book_begin_edit (book);
+    kvp_frame_set_string (frame, path, descr);
+    qof_instance_set_dirty (QOF_INSTANCE (book));
+    qof_book_commit_edit (book);
+}
+
+void
+qof_book_load_options (QofBook *book, GNCOptionLoad load_cb, GNCOptionDB *odb)
+{
+    KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book));
+    load_cb (odb, slots);
+}
+
+void
+qof_book_save_options (QofBook *book, GNCOptionSave save_cb,
+		       GNCOptionDB* odb, gboolean clear)
+{
+    KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book));
+    save_cb (odb, slots, clear);
+    qof_instance_set_dirty (QOF_INSTANCE (book));
+}
+
+static void noop (QofInstance *inst) {}
 
 void
 qof_book_commit_edit(QofBook *book)
diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h
index c3bd255..c1e5ae4 100644
--- a/src/libqof/qof/qofbook.h
+++ b/src/libqof/qof/qofbook.h
@@ -69,6 +69,11 @@ typedef struct _QofBookClass  QofBookClass;
 
 typedef void (*QofBookDirtyCB) (QofBook *, gboolean dirty, gpointer user_data);
 
+typedef struct gnc_option_db GNCOptionDB;
+
+typedef void (*GNCOptionSave) (GNCOptionDB*, KvpFrame*, gboolean);
+typedef void (*GNCOptionLoad) (GNCOptionDB*, KvpFrame*);
+
 /* Book structure */
 struct _QofBook
 {
@@ -211,24 +216,11 @@ QofCollection  * qof_book_get_collection (const QofBook *, QofIdType);
 typedef void (*QofCollectionForeachCB) (QofCollection *, gpointer user_data);
 void qof_book_foreach_collection (const QofBook *, QofCollectionForeachCB, gpointer);
 
-/** Return The kvp data for the book.
- *  Note that the book KVP data is persistent, and is stored/retrieved
- *  from the file/database.  Thus, the book KVP is the correct place to
- *  store data that needs to be persistent accross sessions (or shared
- *  between multiple users).  To store application runtime data, use
- *  qof_book_set_data() instead.
- */
-KvpFrame *qof_book_get_slots(const QofBook *book);
-
 /** The qof_book_set_data() allows arbitrary pointers to structs
  *    to be stored in QofBook. This is the "preferred" method for
  *    extending QofBook to hold new data types.  This is also
  *    the ideal location to store other arbitrary runtime data
  *    that the application may need.
- *
- *    The book data differs from the book KVP in that the contents
- *    of the book KVP are persistent (are saved and restored to file
- *    or database), whereas the data pointers exist only at runtime.
  */
 void qof_book_set_data (QofBook *book, const gchar *key, gpointer data);
 
@@ -312,10 +304,6 @@ time64 qof_book_get_session_dirty_time(const QofBook *book);
  */
 void qof_book_set_dirty_cb(QofBook *book, QofBookDirtyCB cb, gpointer user_data);
 
-/** Call this function when you change the book kvp, to make sure the book
- * is marked 'dirty'. */
-void qof_book_kvp_changed (QofBook *book);
-
 /** This will get the named counter for this book. The return value is
  *    -1 on error or the current value of the counter.
  */
@@ -343,9 +331,22 @@ const char *qof_book_get_counter_format (const QofBook *book,
 const char* qof_book_get_string_option(const QofBook* book, const char* opt_name);
 void qof_book_set_string_option(QofBook* book, const char* opt_name, const char* opt_val);
 
+/** Access functions for reading and setting the used-features on this book.
+ */
+GHashTable *qof_book_get_features (QofBook *book);
+void qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr);
+
 void qof_book_begin_edit(QofBook *book);
 void qof_book_commit_edit(QofBook *book);
 
+/* Access functions for loading and saving the file options */
+void qof_book_load_options (QofBook *book, GNCOptionLoad load_cb,
+			    GNCOptionDB *odb);
+void
+qof_book_save_options (QofBook *book, GNCOptionSave save_cb,
+		       GNCOptionDB* odb, gboolean clear);
+
+
 /** deprecated */
 #define qof_book_get_guid(X) qof_entity_get_guid (QOF_INSTANCE(X))
 
diff --git a/src/libqof/qof/qofid.cpp b/src/libqof/qof/qofid.cpp
index 6febf64..6ff6703 100644
--- a/src/libqof/qof/qofid.cpp
+++ b/src/libqof/qof/qofid.cpp
@@ -38,6 +38,7 @@ extern "C"
 
 #include "qof.h"
 #include "qofid-p.h"
+#include "qofinstance-p.h"
 
 static QofLogModule log_module = QOF_MOD_ENGINE;
 static gboolean qof_alt_dirty_mode = FALSE;
diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h
index aede28c..5be89b3 100644
--- a/src/libqof/qof/qofinstance-p.h
+++ b/src/libqof/qof/qofinstance-p.h
@@ -54,6 +54,61 @@ void qof_instance_set_last_update (QofInstance *inst, Timespec ts);
  *  collection flag at all. */
 void qof_instance_set_dirty_flag (gconstpointer inst, gboolean flag);
 
+/** Set the GncGUID of this instance */
+void qof_instance_set_guid (gpointer inst, const GncGUID *guid);
+
+/** Copy the GncGUID from one instance to another.  This routine should
+ *  be used with extreme caution, since GncGUID values are everywhere
+ *  assumed to be unique. */
+void qof_instance_copy_guid (gpointer to, gconstpointer from);
+
+//QofIdType qof_instance_get_e_type (const QofInstance *inst);
+//void qof_instance_set_e_type (QofInstance *ent, QofIdType e_type);
+
+/** Return the pointer to the kvp_data */
+/*@ dependent @*/
+KvpFrame* qof_instance_get_slots (const QofInstance *);
+void qof_instance_set_editlevel(gpointer inst, gint level);
+void qof_instance_increase_editlevel (gpointer ptr);
+void qof_instance_decrease_editlevel (gpointer ptr);
+void qof_instance_reset_editlevel (gpointer ptr);
+/** Set the flag that indicates whether or not this object is about to
+ *  be destroyed.
+ *
+ *  @param ptr The object whose flag should be set.
+ *
+ *  @param value The new value to be set for this object. */
+void qof_instance_set_destroying (gpointer ptr, gboolean value);
+
+/** \brief Set the dirty flag
+Sets this instance AND the collection as dirty.
+*/
+void qof_instance_set_dirty(QofInstance* inst);
+
+/* reset the dirty flag */
+void qof_instance_mark_clean (QofInstance *);
+/** Get the version number on this instance.  The version number is
+ *  used to manage multi-user updates. */
+gint32 qof_instance_get_version (gconstpointer inst);
+
+/** Set the version number on this instance.  The version number is
+ *  used to manage multi-user updates. */
+void qof_instance_set_version (gpointer inst, gint32 value);
+/** Copy the version number on this instance.  The version number is
+ *  used to manage multi-user updates. */
+void qof_instance_copy_version (gpointer to, gconstpointer from);
+
+/** Get the instance version_check number */
+guint32 qof_instance_get_version_check (gconstpointer inst);
+/** Set the instance version_check number */
+void qof_instance_set_version_check (gpointer inst, guint32 value);
+/** copy the instance version_check number */
+void qof_instance_copy_version_check (gpointer to, gconstpointer from);
+void qof_instance_set_idata(gpointer inst, guint32 idata);
+/* Convenience functions to save some typing in property handlers */
+void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value);
+void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp
index dc32af7..b5ac003 100644
--- a/src/libqof/qof/qofinstance.cpp
+++ b/src/libqof/qof/qofinstance.cpp
@@ -62,7 +62,6 @@ enum
     PROP_GUID,
     PROP_COLLECTION,
     PROP_BOOK,
-    PROP_KVP_DATA,
     PROP_LAST_UPDATE,
     PROP_EDITLEVEL,
     PROP_DESTROYING,
@@ -83,12 +82,6 @@ typedef struct QofInstancePrivate
     /* The entity_table in which this instance is stored */
     QofBook * book;
 
-    /* kvp_data is a key-value pair database for storing arbirtary
-     * information associated with this instance.
-     * See src/engine/kvp_doc.txt for a list and description of the
-     * important keys. */
-//    KvpFrame *kvp_data;
-
     /*  Timestamp used to track the last modification to this
      *  instance.  Typically used to compare two versions of the
      *  same object, to see which is newer.  When used with the
@@ -182,15 +175,6 @@ static void qof_instance_class_init(QofInstanceClass *klass)
 
     g_object_class_install_property
     (object_class,
-     PROP_KVP_DATA,
-     g_param_spec_pointer ("kvp-data",
-                           "Object KVP Data",
-                           "A pointer to the key-value data associated "
-                           "with this object.",
-                           G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (object_class,
      PROP_LAST_UPDATE,
      g_param_spec_pointer ("last-update",
                            "Object Last Update",
@@ -396,9 +380,6 @@ qof_instance_get_property (GObject         *object,
     case PROP_BOOK:
         g_value_take_object(value, priv->book);
         break;
-    case PROP_KVP_DATA:
-        g_value_set_pointer(value, inst->kvp_data);
-        break;
     case PROP_LAST_UPDATE:
         g_value_set_pointer(value, &priv->last_update);
         break;
@@ -455,9 +436,6 @@ qof_instance_set_property (GObject         *object,
         qof_instance_set_book(inst,
 			      static_cast<QofBook*>(g_value_get_object(value)));
         break;
-    case PROP_KVP_DATA:
-        qof_instance_set_slots(inst, static_cast<KvpFrame*>(g_value_get_pointer(value)));
-        break;
     case PROP_LAST_UPDATE:
         ts = static_cast<Timespec*>(g_value_get_pointer(value));
         qof_instance_set_last_update(inst, *ts);
@@ -960,6 +938,32 @@ gboolean qof_instance_refers_to_object(const QofInstance* inst, const QofInstanc
     }
 }
 
+/* g_object_set/get wrappers */
+void
+qof_instance_get (const QofInstance *inst, const gchar *first_prop, ...)
+{
+    va_list ap;
+    g_return_if_fail (QOF_IS_INSTANCE (inst));
+
+    va_start (ap, first_prop);
+    g_object_get_valist (G_OBJECT (inst), first_prop, ap);
+    va_end (ap);
+}
+
+void
+qof_instance_set (QofInstance *inst, const gchar *first_prop, ...)
+{
+    va_list ap;
+    QofInstancePrivate *priv = GET_PRIVATE(inst);
+    g_return_if_fail (QOF_IS_INSTANCE (inst));
+
+    qof_instance_set_dirty (inst);
+    va_start (ap, first_prop);
+    g_object_set_valist (G_OBJECT (inst), first_prop, ap);
+    va_end (ap);
+}
+
+
 /* =================================================================== */
 /* Entity edit and commit utilities */
 /* =================================================================== */
@@ -1064,5 +1068,25 @@ qof_commit_edit_part2(QofInstance *inst,
     return TRUE;
 }
 
+void
+qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value)
+{
+    KvpFrame *frame = qof_instance_get_slots (inst);
+    kvp_frame_set_gvalue (frame, key, value);
+}
+
+void
+qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value)
+{
+    KvpFrame *frame = qof_instance_get_slots (inst);
+    GValue *temp = kvp_frame_get_gvalue (frame, key);
+    if (temp)
+    {
+	g_value_copy (temp, value);
+	gnc_gvalue_free (temp);
+    }
+}
+
+
 /* ========================== END OF FILE ======================= */
 
diff --git a/src/libqof/qof/qofinstance.h b/src/libqof/qof/qofinstance.h
index a296099..ca485c3 100644
--- a/src/libqof/qof/qofinstance.h
+++ b/src/libqof/qof/qofinstance.h
@@ -121,30 +121,12 @@ const GncGUID * qof_entity_get_guid (gconstpointer);
 /*@ dependent @*/
 QofCollection* qof_instance_get_collection (gconstpointer inst);
 
-/** Set the GncGUID of this instance */
-void qof_instance_set_guid (gpointer inst, const GncGUID *guid);
-
-/** Copy the GncGUID from one instance to another.  This routine should
- *  be used with extreme caution, since GncGUID values are everywhere
- *  assumed to be unique. */
-void qof_instance_copy_guid (gpointer to, gconstpointer from);
-
 /** Compare the GncGUID values of two instances.  This routine returns 0
  *  if the two values are equal, <0 if the first is smaller than the
  *  second, or >0 if the second is smaller tan the first. */
 gint qof_instance_guid_compare(const gconstpointer ptr1, const gconstpointer ptr2);
 
-//QofIdType qof_instance_get_e_type (const QofInstance *inst);
-//void qof_instance_set_e_type (QofInstance *ent, QofIdType e_type);
-
-/** Return the pointer to the kvp_data */
-/*@ dependent @*/
-KvpFrame* qof_instance_get_slots (const QofInstance *);
-void qof_instance_set_editlevel(gpointer inst, gint level);
 gint qof_instance_get_editlevel (gconstpointer ptr);
-void qof_instance_increase_editlevel (gpointer ptr);
-void qof_instance_decrease_editlevel (gpointer ptr);
-void qof_instance_reset_editlevel (gpointer ptr);
 
 /** Compare two instances, based on thier last update times.
  *  Returns a negative, zero or positive value, respectively,
@@ -164,14 +146,6 @@ int qof_instance_version_cmp (const QofInstance *left, const QofInstance *right)
  *  is passed to the function. */
 gboolean qof_instance_get_destroying (gconstpointer ptr);
 
-/** Set the flag that indicates whether or not this object is about to
- *  be destroyed.
- *
- *  @param ptr The object whose flag should be set.
- *
- *  @param value The new value to be set for this object. */
-void qof_instance_set_destroying (gpointer ptr, gboolean value);
-
 /** Retrieve the flag that indicates whether or not this object has
  *  been modified.  This is specifically the flag on the object. It
  *  does not perform any other checking which might normally be
@@ -191,39 +165,22 @@ void qof_instance_print_dirty (const QofInstance *entity, gpointer dummy);
 #define qof_instance_is_dirty qof_instance_get_dirty
 gboolean qof_instance_get_dirty (QofInstance *);
 
-/** \brief Set the dirty flag
-
-Sets this instance AND the collection as dirty.
-*/
-void qof_instance_set_dirty(QofInstance* inst);
-
-/* reset the dirty flag */
-void qof_instance_mark_clean (QofInstance *);
-
 gboolean qof_instance_get_infant(const QofInstance *inst);
 
-/** Get the version number on this instance.  The version number is
- *  used to manage multi-user updates. */
-gint32 qof_instance_get_version (gconstpointer inst);
-
-/** Set the version number on this instance.  The version number is
- *  used to manage multi-user updates. */
-void qof_instance_set_version (gpointer inst, gint32 value);
-/** Copy the version number on this instance.  The version number is
- *  used to manage multi-user updates. */
-void qof_instance_copy_version (gpointer to, gconstpointer from);
+/**
+ * \brief Wrapper for g_object_get
+ */
+void qof_instance_get (const QofInstance *inst, const gchar *first_param, ...);
 
-/** Get the instance version_check number */
-guint32 qof_instance_get_version_check (gconstpointer inst);
-/** Set the instance version_check number */
-void qof_instance_set_version_check (gpointer inst, guint32 value);
-/** copy the instance version_check number */
-void qof_instance_copy_version_check (gpointer to, gconstpointer from);
+/**
+ * \brief Wrapper for g_object_set
+ * Group setting multiple parameters in a single begin/commit/rollback
+ */
+void qof_instance_set (QofInstance *inst, const gchar *first_param, ...);
 
 /** get the instance tag number
     used for kvp management in sql backends. */
 guint32 qof_instance_get_idata (gconstpointer inst);
-void qof_instance_set_idata(gpointer inst, guint32 idata);
 
 /**
  * Returns a displayable name for this object.  The returned string must be freed by the caller.
diff --git a/src/libqof/qof/test/test-kvp_frame.c b/src/libqof/qof/test/test-kvp_frame.c
index 6267f70..ce35637 100644
--- a/src/libqof/qof/test/test-kvp_frame.c
+++ b/src/libqof/qof/test/test-kvp_frame.c
@@ -41,18 +41,22 @@ void test_suite_kvp_frame ( void );
 typedef struct
 {
     KvpFrame *frame;
+    GSList *hdlrs;
 } Fixture;
 
 static void
 setup( Fixture *fixture, gconstpointer pData )
 {
     fixture->frame = kvp_frame_new();
+    fixture->hdlrs = NULL;
 }
 
 static void
 teardown( Fixture *fixture, gconstpointer pData )
 {
     kvp_frame_delete( fixture->frame );
+    g_slist_free_full (fixture->hdlrs, test_free_log_handler);
+    test_clear_error_list ();
 }
 
 extern KvpFrame* ( *p_get_trailer_make )( KvpFrame *frame, const char *key_path, char **end_key );
@@ -67,6 +71,7 @@ static void
 setup_static( Fixture *fixture, gconstpointer pData )
 {
     fixture->frame = kvp_frame_new();
+    fixture->hdlrs = NULL;
     init_static_test_pointers();
     g_assert( p_get_trailer_make && p_kvp_value_glist_to_string &&
               p_get_or_make && p_kvp_frame_get_frame_or_null_slash_trash &&
@@ -77,6 +82,8 @@ static void
 teardown_static( Fixture *fixture, gconstpointer pData )
 {
     kvp_frame_delete( fixture->frame );
+    g_slist_free_full (fixture->hdlrs, test_free_log_handler);
+    test_clear_error_list ();
     p_get_trailer_make = NULL;
     p_kvp_value_glist_to_string = NULL;
     p_get_or_make = NULL;
@@ -84,21 +91,19 @@ teardown_static( Fixture *fixture, gconstpointer pData )
     p_get_trailer_or_null = NULL;
 }
 
-static void
-test_kvp_frame_new_delete( void )
+static GncGUID*
+populate_frame (KvpFrame *frame)
 {
-    KvpFrame *frame;
+    GList *list = NULL;
     Timespec ts;
     GncGUID *guid;
+    GDate gdate;
 
     ts.tv_sec = 1;
     ts.tv_nsec = 1;
-    guid = guid_malloc();
-    guid_new( guid );
-
-    frame = kvp_frame_new();
-    g_assert( frame );
-    g_assert( kvp_frame_is_empty( frame ) );
+    guid = guid_malloc ();
+    guid_new (guid);
+    g_date_set_dmy (&gdate, 26, 1, 1957);
 
     kvp_frame_set_gint64( frame, "gint64-type", 100 );
     kvp_frame_set_double( frame, "double-type", 3.14159 );
@@ -106,14 +111,37 @@ test_kvp_frame_new_delete( void )
     kvp_frame_set_timespec( frame, "timespec-type", ts );
     kvp_frame_set_string( frame, "string-type", "abcdefghijklmnop" );
     kvp_frame_set_guid( frame, "guid-type", guid );
+    kvp_frame_set_value_nc (frame, "gdate-type", kvp_value_new_gdate (gdate));
     kvp_frame_set_frame( frame, "frame-type", kvp_frame_new() );
 
+    list = g_list_prepend (list, kvp_value_new_guid (guid));
+    list = g_list_prepend (list, kvp_value_new_string ("qrstuvwxyz"));
+    list = g_list_prepend (list, kvp_value_new_timespec (ts));
+    list = g_list_prepend (list, kvp_value_new_numeric (gnc_numeric_create (256, 120)));
+    list = g_list_prepend (list, kvp_value_new_double (0.4342944819));
+    list = g_list_prepend (list, kvp_value_new_gint64 (0x1f2e3d4c5b6a79LL));
+    kvp_frame_set_value (frame, "list-type", kvp_value_new_glist_nc (list));
+
+    return guid;
+}
+
+static void
+test_kvp_frame_new_delete( void )
+{
+    KvpFrame *frame;
+    GncGUID *guid;
+
+    frame = kvp_frame_new();
+    g_assert( frame );
+    g_assert( kvp_frame_is_empty( frame ) );
+
+    guid = populate_frame (frame);
+
     g_assert( !kvp_frame_is_empty( frame ) );
 
     kvp_frame_delete( frame );
     g_assert( frame );
-
-    guid_free( guid );
+    guid_free (guid);
 }
 
 static void
@@ -1465,6 +1493,203 @@ test_get_trailer_or_null( Fixture *fixture, gconstpointer pData )
     g_assert_cmpstr( last_key, == , "test2" );
 }
 
+static void
+test_kvp_frame_get_gvalue (Fixture *fixture, gconstpointer pData)
+{
+    KvpFrame *frame = fixture->frame;
+    GValue *value;
+    Timespec ts = {1, 1};
+    GncGUID *guid = populate_frame (frame);
+    GDate date;
+    gchar *log_domain = "qof.kvp";
+    gint log_level = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
+    gchar *msg1 = "[gvalue_from_kvp_value()] Error! Attempt to transfer KvpFrame!";
+    gchar *msg2 = "[gvalue_from_kvp_value()] Error! Invalid KVP Transfer Request!";
+#undef _func
+    TestErrorStruct *check1 = test_error_struct_new (log_domain, log_level,
+							msg1);
+    TestErrorStruct *check2 = test_error_struct_new (log_domain, log_level,
+							msg2);
+    fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check1,
+						 (GLogFunc)test_list_handler);
+    test_add_error (check1);
+    test_add_error (check2);
+
+    g_date_clear (&date, 1);
+    g_date_set_dmy (&date, 26, 1, 1957);
+
+    value = kvp_frame_get_gvalue (frame, "gint64-type");
+    g_assert (value != NULL);
+    g_assert (G_VALUE_HOLDS_INT64 (value));
+    g_assert_cmpint (g_value_get_int64 (value), ==, 100);
+    gnc_gvalue_free (value);
+
+    value = kvp_frame_get_gvalue (frame, "double-type");
+    g_assert (value != NULL);
+    g_assert (G_VALUE_HOLDS_DOUBLE (value));
+    g_assert_cmpfloat (g_value_get_double (value), ==, 3.14159);
+    gnc_gvalue_free (value);
+
+    value = kvp_frame_get_gvalue (frame, "numeric-type");
+    g_assert (value != NULL);
+    g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_NUMERIC);
+    g_assert (gnc_numeric_zero_p (*(gnc_numeric*)g_value_get_boxed (value)));
+    gnc_gvalue_free (value);
+
+    value = kvp_frame_get_gvalue (frame, "timespec-type");
+    g_assert (value != NULL);
+    g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_TIMESPEC);
+    g_assert (timespec_equal (&ts, (Timespec*)g_value_get_boxed (value)));
+    gnc_gvalue_free (value);
+
+    value = kvp_frame_get_gvalue (frame, "string-type");
+    g_assert (value != NULL);
+    g_assert (G_VALUE_HOLDS_STRING (value));
+    g_assert_cmpstr (g_value_get_string (value), ==, "abcdefghijklmnop");
+    gnc_gvalue_free (value);
+
+    value = kvp_frame_get_gvalue (frame, "guid-type");
+    g_assert (value != NULL);
+    g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_GUID);
+    g_assert (guid_equal (guid, (GncGUID*)g_value_get_boxed (value)));
+    gnc_gvalue_free (value);
+
+    value = kvp_frame_get_gvalue (frame, "gdate-type");
+    g_assert (value != NULL);
+    g_assert_cmpint (G_VALUE_TYPE (value), ==, G_TYPE_DATE);
+    g_assert_cmpint (g_date_compare (&date, (GDate*)g_value_get_boxed (value)), ==, 0);
+    gnc_gvalue_free (value);
+
+    value = kvp_frame_get_gvalue (frame, "frame-type");
+    g_assert (value == NULL);
+    g_assert_cmpint (check1->hits, ==, 1);
+    g_assert_cmpint (check2->hits, ==, 1);
+
+    value = kvp_frame_get_gvalue (frame, "list-type");
+    g_assert (value != NULL);
+    g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_VALUE_LIST);
+    {
+	GList *list = (GList*)g_value_get_boxed (value);
+	GValue *value = NULL;
+
+	value = (GValue*)(list->data);
+	g_assert (G_VALUE_HOLDS_INT64 (value));
+	g_assert (g_value_get_int64 (value) == 0x1f2e3d4c5b6a79LL);
+	list = g_list_next (list);
+
+	value = (GValue*)(list->data);
+	g_assert (G_VALUE_HOLDS_DOUBLE (value));
+	g_assert_cmpfloat (g_value_get_double (value), ==, 0.4342944819);
+	list = g_list_next (list);
+
+	value = (GValue*)(list->data);
+	g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_NUMERIC);
+	g_assert (gnc_numeric_eq (*(gnc_numeric*)g_value_get_boxed (value),
+				  gnc_numeric_create (256, 120)));
+	list = g_list_next (list);
+
+	value = (GValue*)(list->data);
+	g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_TIMESPEC);
+	g_assert (timespec_equal (&ts, (Timespec*)g_value_get_boxed (value)));
+	list = g_list_next (list);
+
+	value = (GValue*)(list->data);
+	g_assert (G_VALUE_HOLDS_STRING (value));
+	g_assert_cmpstr (g_value_get_string (value), ==, "qrstuvwxyz");
+	list = g_list_next (list);
+
+	value = (GValue*)(list->data);
+	g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_GUID);
+	g_assert (guid_equal (guid, (GncGUID*)g_value_get_boxed (value)));
+	list = g_list_next (list);
+
+	g_assert (list == NULL);
+
+    }
+    gnc_gvalue_free (value);
+}
+
+static void
+test_kvp_frame_set_gvalue (Fixture *fixture, gconstpointer pData)
+{
+/* Bit of a shortcut: We'll use kvp_frame_get_item to make our KvpItem
+ * and feed it into a new frame; something of a round-trip test.
+ */
+    KvpFrame *o_frame = fixture->frame;
+    KvpFrame *n_frame = kvp_frame_new ();
+    GValue *value;
+    GList *o_list, *n_list;
+
+    populate_frame (o_frame);
+
+    value = kvp_frame_get_gvalue (o_frame, "gint64-type");
+    g_assert (value != NULL);
+    kvp_frame_set_gvalue (n_frame, "gint64-type", value);
+    g_assert_cmpint (kvp_frame_get_gint64 (o_frame, "gint64-type"), ==,
+		     kvp_frame_get_gint64 (n_frame, "gint64-type"));
+
+    value = kvp_frame_get_gvalue (o_frame, "double-type");
+    g_assert (value != NULL);
+    kvp_frame_set_gvalue (n_frame, "double-type", value);
+    g_assert_cmpint (kvp_frame_get_double (o_frame, "double-type"), ==,
+		     kvp_frame_get_double (n_frame, "double-type"));
+
+    value = kvp_frame_get_gvalue (o_frame, "numeric-type");
+    g_assert (value != NULL);
+    kvp_frame_set_gvalue (n_frame, "numeric-type", value);
+    g_assert (gnc_numeric_equal (kvp_frame_get_numeric (o_frame, "numeric-type"),
+				 kvp_frame_get_numeric (n_frame, "numeric-type")));
+
+    value = kvp_frame_get_gvalue (o_frame, "timespec-type");
+    g_assert (value != NULL);
+    kvp_frame_set_gvalue (n_frame, "timespec-type", value);
+    {
+	Timespec o_ts = kvp_frame_get_timespec (o_frame, "timespec-type");
+	Timespec n_ts = kvp_frame_get_timespec (n_frame, "timespec-type");
+	g_assert (timespec_equal (&o_ts, &n_ts));
+    }
+
+    value = kvp_frame_get_gvalue (o_frame, "string-type");
+    g_assert (value != NULL);
+    kvp_frame_set_gvalue (n_frame, "string-type", value);
+    g_assert_cmpstr (kvp_frame_get_string (o_frame, "string-type"), ==,
+		     kvp_frame_get_string (n_frame, "string-type"));
+
+    value = kvp_frame_get_gvalue (o_frame, "gdate-type");
+    g_assert (value != NULL);
+    kvp_frame_set_gvalue (n_frame, "gdate-type", value);
+    {
+	GDate o_date = kvp_value_get_gdate (kvp_frame_get_slot (o_frame,
+								"gdate-type"));
+	GDate n_date = kvp_value_get_gdate (kvp_frame_get_slot (n_frame,
+								"gdate-type"));
+	g_assert_cmpint (g_date_compare (&o_date, &n_date), ==, 0);
+    }
+
+    value = kvp_frame_get_gvalue (o_frame, "guid-type");
+    g_assert (value != NULL);
+    kvp_frame_set_gvalue (n_frame, "guid-type", value);
+    g_assert (guid_equal (kvp_frame_get_guid (o_frame, "guid-type"),
+			  kvp_frame_get_guid (n_frame, "guid-type")));
+
+    value = kvp_frame_get_gvalue (o_frame, "list-type");
+    g_assert (value != NULL);
+    kvp_frame_set_gvalue (n_frame, "list-type", value);
+    o_list = kvp_value_get_glist (kvp_frame_get_slot (o_frame, "list_type"));
+    n_list = kvp_value_get_glist (kvp_frame_get_slot (n_frame, "list_type"));
+
+    g_assert_cmpint (g_list_length (o_list), ==, g_list_length (n_list));
+    while (o_list && n_list)
+    {
+	g_assert_cmpint (kvp_value_compare ((KvpValue*)o_list->data,
+					    (KvpValue*)n_list->data), ==, 0);
+	o_list = g_list_next (o_list);
+	n_list = g_list_next (n_list);
+    }
+    kvp_frame_delete (n_frame);
+}
+
+
 void
 test_suite_kvp_frame( void )
 {
@@ -1492,4 +1717,6 @@ test_suite_kvp_frame( void )
     GNC_TEST_ADD( suitename, "get or make", Fixture, NULL, setup_static, test_get_or_make, teardown_static );
     GNC_TEST_ADD( suitename, "kvp frame get frame or null slash trash", Fixture, NULL, setup_static, test_kvp_frame_get_frame_or_null_slash_trash, teardown_static );
     GNC_TEST_ADD( suitename, "get trailer or null", Fixture, NULL, setup_static, test_get_trailer_or_null, teardown_static );
+    GNC_TEST_ADD ( suitename, "kvp frame get gvalue", Fixture, NULL, setup, test_kvp_frame_get_gvalue, teardown);
+    GNC_TEST_ADD ( suitename, "kvp frame set gvalue", Fixture, NULL, setup, test_kvp_frame_set_gvalue, teardown);
 }
diff --git a/src/libqof/qof/test/test-qofbook.c b/src/libqof/qof/test/test-qofbook.c
index 475a5f2..e6bd41b 100644
--- a/src/libqof/qof/test/test-qofbook.c
+++ b/src/libqof/qof/test/test-qofbook.c
@@ -365,99 +365,80 @@ test_book_increment_and_format_counter ( Fixture *fixture, gconstpointer pData )
 }
 
 static void
-test_book_kvp_changed( Fixture *fixture, gconstpointer pData )
-{
-    g_test_message( "Testing book is marked dirty after kvp_changed" );
-    g_assert( !qof_instance_is_dirty (QOF_INSTANCE (fixture->book)) );
-    qof_book_kvp_changed( fixture->book );
-    g_assert( qof_instance_is_dirty (QOF_INSTANCE (fixture->book)) );
-}
-
-static void
 test_book_use_trading_accounts( Fixture *fixture, gconstpointer pData )
 {
-    const char *slot_path;
-
-    /* create correct slot path */
-    slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/", OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_TRADING_ACCOUNTS, NULL );
-    g_assert( slot_path != NULL );
-
-    g_test_message( "Testing when no trading accounts are used" );
-    g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
-
-    g_test_message( "Testing with incorrect slot path and correct value - t" );
-    qof_book_set_string_option( fixture->book, OPTION_NAME_TRADING_ACCOUNTS, "t" );
     g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
 
     g_test_message( "Testing with existing trading accounts set to true - t" );
-    qof_book_set_string_option( fixture->book, slot_path, "t" );
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "trading-accts", "t",
+		      NULL);
     g_assert( qof_book_use_trading_accounts( fixture-> book ) == TRUE );
 
     g_test_message( "Testing with existing trading accounts and incorrect value - tt" );
-    qof_book_set_string_option( fixture->book, slot_path, "tt" );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "trading-accts", "tt",
+		      NULL);
     g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
+    qof_book_commit_edit (fixture->book);
 
 }
 
 static void
 test_book_get_num_days_autofreeze( Fixture *fixture, gconstpointer pData )
 {
-    const char *slot_path;
-
-    /* create correct slot path */
-    slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/", OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_AUTO_READONLY_DAYS, NULL );
-    g_assert( slot_path != NULL );
-
     g_test_message( "Testing default: No auto-freeze days are set" );
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
 
-    g_test_message( "Testing with incorrect slot path and some correct value - 17" );
-    kvp_frame_set_double(qof_book_get_slots(fixture->book), OPTION_NAME_AUTO_READONLY_DAYS, 17);
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
 
-    g_test_message( "Testing when setting this correctly with some correct value - 17" );
-    kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 17);
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "autoreadonly-days", (gdouble)17,
+		      NULL);
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == TRUE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 17 );
 
     g_test_message( "Testing when setting this correctly to zero again" );
-    kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 0);
+
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "autoreadonly-days", (gdouble)0,
+		      NULL);
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
 
-    g_test_message( "Testing when setting this correctly with some correct value - 32" );
-    kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 32);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "autoreadonly-days", (gdouble)32,
+		      NULL);
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == TRUE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 32 );
 
+    qof_book_commit_edit (fixture->book);
 }
 
 static void
 test_book_use_split_action_for_num_field( Fixture *fixture, gconstpointer pData )
 {
-    const char *slot_path;
-
-    /* create correct slot path */
-    slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/",
-                                            OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_NUM_FIELD_SOURCE, NULL );
-    g_assert( slot_path != NULL );
-
     g_test_message( "Testing default: No selection has been specified" );
     g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == FALSE );
 
-    g_test_message( "Testing with incorrect slot path and correct value - t" );
-    qof_book_set_string_option( fixture->book, OPTION_NAME_NUM_FIELD_SOURCE, "t" );
-    g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == FALSE );
-
     g_test_message( "Testing with existing use split action for num set to true - t" );
-    qof_book_set_string_option( fixture->book, slot_path, "t" );
+
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "split-action-num-field", "t",
+		      NULL);
     g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == TRUE );
 
     g_test_message( "Testing with existing use split action for num and incorrect value - tt" );
-    qof_book_set_string_option( fixture->book, slot_path, "tt" );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "split-action-num-field", "tt",
+		      NULL);
     g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == FALSE );
+    qof_book_commit_edit (fixture->book);
 }
 
 static void
@@ -775,7 +756,6 @@ test_suite_qofbook ( void )
     GNC_TEST_ADD( suitename, "get counter", Fixture, NULL, setup, test_book_get_counter, teardown );
     GNC_TEST_ADD( suitename, "get counter format", Fixture, NULL, setup, test_book_get_counter_format, teardown );
     GNC_TEST_ADD( suitename, "increment and format counter", Fixture, NULL, setup, test_book_increment_and_format_counter, teardown );
-    GNC_TEST_ADD( suitename, "kvp changed", Fixture, NULL, setup, test_book_kvp_changed, teardown );
     GNC_TEST_ADD( suitename, "use trading accounts", Fixture, NULL, setup, test_book_use_trading_accounts, teardown );
     GNC_TEST_ADD( suitename, "get autofreeze days", Fixture, NULL, setup, test_book_get_num_days_autofreeze, teardown );
     GNC_TEST_ADD( suitename, "use split action for num field", Fixture, NULL, setup, test_book_use_split_action_for_num_field, teardown );
diff --git a/src/register/ledger-core/split-register-model-save.c b/src/register/ledger-core/split-register-model-save.c
index b22bdee..e95816f 100644
--- a/src/register/ledger-core/split-register-model-save.c
+++ b/src/register/ledger-core/split-register-model-save.c
@@ -674,10 +674,9 @@ gnc_template_register_save_xfrm_cell (BasicCell * cell,
     }
 
     acctGUID = xaccAccountGetGUID (acct);
-    kvpf = xaccSplitGetSlots (sd->split);
-    kvp_frame_set_slot_path (kvpf, kvp_value_new_guid(acctGUID),
-                             GNC_SX_ID, GNC_SX_ACCOUNT, NULL);
-
+    qof_instance_set (QOF_INSTANCE (sd->split),
+		      "sx-account", acctGUID,
+		      NULL);
     template_acc = xaccAccountLookup (&info->template_account,
                                       gnc_get_current_book ());
 
@@ -700,10 +699,9 @@ gnc_template_register_save_debcred_cell (BasicCell * cell,
 {
     SRSaveData *sd = save_data;
     SplitRegister *reg = user_data;
-    kvp_frame *kvpf;
-    const char *value;
+    const char *credit_formula, *debit_formula;
     char *error_loc;
-    gnc_numeric new_amount;
+    gnc_numeric credit_amount, debit_amount;
     gboolean parse_result;
 
     g_return_if_fail (gnc_basic_cell_has_name (cell, FDEBT_CELL) ||
@@ -712,54 +710,37 @@ gnc_template_register_save_debcred_cell (BasicCell * cell,
     if (sd->handled_dc)
         return;
 
-    kvpf = xaccSplitGetSlots (sd->split);
-
-    DEBUG ("kvp_frame before: %s\n", kvp_frame_to_string (kvpf));
-
     /* amountStr = gnc_numeric_to_string (new_amount); */
 
-    value = gnc_table_layout_get_cell_value (reg->table->layout, FCRED_CELL);
-    kvp_frame_set_slot_path (kvpf, kvp_value_new_string (value),
-                             GNC_SX_ID,
-                             GNC_SX_CREDIT_FORMULA,
-                             NULL);
-
+    credit_formula = gnc_table_layout_get_cell_value (reg->table->layout,
+						      FCRED_CELL);
     /* If the value can be parsed into a numeric result (without any
      * further variable definitions), store that numeric value
      * additionally in the kvp. Otherwise store a zero numeric
      * there.*/
-    parse_result = gnc_exp_parser_parse_separate_vars(value, &new_amount, &error_loc, NULL);
+    parse_result = gnc_exp_parser_parse_separate_vars(credit_formula,
+						      &credit_amount,
+						      &error_loc, NULL);
     if (!parse_result)
-    {
-        new_amount = gnc_numeric_zero();
-    }
-    kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_amount),
-                             GNC_SX_ID,
-                             GNC_SX_CREDIT_NUMERIC,
-                             NULL);
-
-    value = gnc_table_layout_get_cell_value (reg->table->layout, FDEBT_CELL);
+        credit_amount = gnc_numeric_zero();
 
-    kvp_frame_set_slot_path (kvpf,
-                             kvp_value_new_string (value),
-                             GNC_SX_ID,
-                             GNC_SX_DEBIT_FORMULA,
-                             NULL);
+    debit_formula = gnc_table_layout_get_cell_value (reg->table->layout,
+						     FDEBT_CELL);
 
     /* If the value can be parsed into a numeric result, store that
      * numeric value additionally. See above comment.*/
-    parse_result = gnc_exp_parser_parse_separate_vars(value, &new_amount, &error_loc, NULL);
+    parse_result = gnc_exp_parser_parse_separate_vars(debit_formula,
+						      &debit_amount,
+						      &error_loc, NULL);
     if (!parse_result)
-    {
-        new_amount = gnc_numeric_zero();
-    }
-    kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_amount),
-                             GNC_SX_ID,
-                             GNC_SX_DEBIT_NUMERIC,
-                             NULL);
-
-    DEBUG ("kvp_frame  after: %s\n", kvp_frame_to_string (kvpf));
-
+        debit_amount = gnc_numeric_zero();
+
+    qof_instance_set (QOF_INSTANCE (sd->split),
+		      "sx-credit-formula", credit_formula,
+		      "sx-credit-numeric", &credit_amount,
+		      "sx-debit-formula", debit_formula,
+		      "sx-debit-numeric", &debit_amount,
+		      NULL);
     /* set the amount to an innocuous value */
     /* Note that this marks the split dirty */
     xaccSplitSetValue (sd->split, gnc_numeric_create (0, 1));
@@ -773,24 +754,13 @@ gnc_template_register_save_shares_cell (BasicCell * cell,
                                         gpointer user_data)
 {
     SRSaveData *sd = save_data;
-    kvp_frame *kvpf;
     char *sharesStr = "(x + y)/42";
 
     g_return_if_fail (gnc_basic_cell_has_name (cell, SHRS_CELL));
-
-    kvpf = xaccSplitGetSlots (sd->split);
-
     /* FIXME: shares cells are numeric by definition. */
-    DEBUG ("kvp_frame before: %s\n", kvp_frame_to_string (kvpf));
-
-    /* sharesStr = gnc_numeric_to_string( sharesStr ); */
-    kvp_frame_set_slot_path (kvpf,
-                             kvp_value_new_string (sharesStr),
-                             GNC_SX_ID,
-                             GNC_SX_SHARES,
-                             NULL);
-
-    DEBUG ("kvp_frame  after: %s\n", kvp_frame_to_string (kvpf));
+    qof_instance_set (QOF_INSTANCE (sd->split),
+		      "sx-shares", sharesStr,
+		      NULL);
 
     /* set the shares to an innocuous value */
     /* Note that this marks the split dirty */
diff --git a/src/register/ledger-core/split-register-model.c b/src/register/ledger-core/split-register-model.c
index 5af4a3b..503c9ba 100644
--- a/src/register/ledger-core/split-register-model.c
+++ b/src/register/ledger-core/split-register-model.c
@@ -2091,31 +2091,23 @@ gnc_template_register_get_xfrm_entry (VirtualLocation virt_loc,
     static char *name = NULL;
 
     SplitRegister *reg = user_data;
-    kvp_frame *kvpf;
     Split *split;
+    Account *account;
+    GncGUID *guid = NULL;
 
     split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
     if (!split)
         return NULL;
-
-    kvpf = xaccSplitGetSlots (split);
-
+    /* Caller either uses the return as a temporary in a boolean
+     * expression or g_strdups it, so we keep it static and free the
+     * old one on every call to avoid leaks. Ugly, but it works.
+     */
     g_free (name);
-
-    if (kvpf)
-    {
-        Account *account;
-        GncGUID *guid;
-
-        guid = kvp_value_get_guid(
-                   kvp_frame_get_slot_path(kvpf, "sched-xaction", "account", NULL));
-
-        account = xaccAccountLookup (guid, gnc_get_current_book ());
-
-        name = account ? gnc_get_account_name_for_register (account) : NULL;
-    }
-    else
-        name = NULL;
+    qof_instance_get (QOF_INSTANCE (split),
+		      "sx-account", &guid,
+		      NULL);
+    account = xaccAccountLookup (guid, gnc_get_current_book ());
+    name = account ? gnc_get_account_name_for_register (account) : NULL;
 
     return name;
 }
@@ -2128,10 +2120,13 @@ gnc_template_register_get_fdebt_entry (VirtualLocation virt_loc,
 {
     SplitRegister *reg = user_data;
     Split *split = gnc_split_register_get_split(reg, virt_loc.vcell_loc);
-    kvp_frame *kvpf = xaccSplitGetSlots(split);
+    char *formula = NULL;
 
-    return kvp_value_get_string(
-               kvp_frame_get_slot_path (kvpf, "sched-xaction", "debit-formula", NULL));
+    qof_instance_get (QOF_INSTANCE (split),
+		      "sx-debit-formula", &formula,
+		      NULL);
+
+    return formula;
 }
 
 static char *
@@ -2155,14 +2150,15 @@ gnc_template_register_get_fcred_entry (VirtualLocation virt_loc,
                                        gpointer user_data)
 {
     SplitRegister *reg = user_data;
-    kvp_frame *kvpf;
-    Split *split;
+    Split *split = gnc_split_register_get_split(reg, virt_loc.vcell_loc);
+    char *formula = NULL;
 
-    split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
-    kvpf = xaccSplitGetSlots (split);
+    qof_instance_get (QOF_INSTANCE (split),
+		      "sx-credit-formula", &formula,
+		      NULL);
+
+    return formula;
 
-    return kvp_value_get_string(
-               kvp_frame_get_slot_path (kvpf, "sched-xaction", "credit-formula", NULL));
 }
 
 static char *
@@ -2194,8 +2190,13 @@ gnc_template_register_get_debcred_entry (VirtualLocation virt_loc,
         gboolean *conditionally_changed,
         gpointer user_data)
 {
+    PERR("The function called always returned either NULL or an empty string "
+	 "while issuing dire warnings about how incorrect it is. That code "
+	 "has been removed and the function if called raises this error and "
+	 "returns NULL");
+    return NULL;
+#if 0
     SplitRegister *reg = user_data;
-    kvp_frame *kvpf;
     Split *split;
 
     split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
@@ -2241,6 +2242,7 @@ gnc_template_register_get_debcred_entry (VirtualLocation virt_loc,
     }
 
     return NULL;
+#endif
 }
 
 static void
diff --git a/src/report/report-gnome/gnc-plugin-page-report.c b/src/report/report-gnome/gnc-plugin-page-report.c
index 8878177..828f4b5 100644
--- a/src/report/report-gnome/gnc-plugin-page-report.c
+++ b/src/report/report-gnome/gnc-plugin-page-report.c
@@ -1778,8 +1778,6 @@ gnc_plugin_page_report_print_cb( GtkAction *action, GncPluginPageReport *report
     g_free (job_name);
 }
 
-#define KVP_OWNER_EXPORT_PDF_DIRNAME "export-pdf-directory"
-
 static void
 gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *report )
 {
@@ -1787,7 +1785,6 @@ gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *rep
     gchar *job_name = report_create_jobname(priv);
     GncInvoice *invoice;
     GncOwner *owner = NULL;
-    KvpFrame *kvp = NULL;
 
     // Do we have an invoice report?
     invoice = lookup_invoice(priv);
@@ -1797,20 +1794,19 @@ gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *rep
         owner = (GncOwner*) gncInvoiceGetOwner(invoice);
         if (owner)
         {
+	    QofInstance *inst = qofOwnerGetOwner (owner);
+	    gchar *dirname = NULL;
+	    qof_instance_get (inst, "export-pdf-dir", &dirname, NULL);
             // Yes. In the kvp, look up the key for the Export-PDF output
             // directory. If it exists, prepend this to the job name so that
             // we can export to PDF.
-            kvp = gncOwnerGetSlots(owner);
-            if (kvp)
-            {
-                const char *dirname = kvp_frame_get_string(kvp, KVP_OWNER_EXPORT_PDF_DIRNAME);
-                if (dirname && g_file_test(dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
-                {
-                    gchar *tmp = g_build_filename(dirname, job_name, NULL);
-                    g_free(job_name);
-                    job_name = tmp;
-                }
-            }
+	    if (dirname && g_file_test(dirname,
+				       G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
+	    {
+		gchar *tmp = g_build_filename(dirname, job_name, NULL);
+		g_free(job_name);
+		job_name = tmp;
+	    }
         }
     }
 
@@ -1818,10 +1814,12 @@ gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *rep
 
     gnc_html_print(priv->html, job_name, TRUE);
 
-    if (owner && kvp)
+    if (owner)
     {
-        // As this is an invoice report with some owner, we will try to look up the
-        // chosen output directory from the print settings and store it again in the owner kvp.
+	/* As this is an invoice report with some owner, we will try
+	 * to look up the chosen output directory from the print
+	 * settings and store it again in the owner kvp.
+	 */
         GtkPrintSettings *print_settings = gnc_print_get_settings();
         if (print_settings &&
 	    gtk_print_settings_has_key(print_settings,
@@ -1832,15 +1830,10 @@ gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *rep
             // Only store the directory if it exists.
             if (g_file_test(dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
             {
-                QofInstance *qofinstance = qofOwnerGetOwner(owner);
-                if (qofinstance)
-		{
-		    gncOwnerBeginEdit(owner);
-		    kvp_frame_set_string(kvp, KVP_OWNER_EXPORT_PDF_DIRNAME,
-					 dirname);
-                    qof_instance_set_dirty(qofinstance);
-		    qof_commit_edit (qofinstance);
-		}
+                QofInstance *inst = qofOwnerGetOwner(owner);
+                gncOwnerBeginEdit(owner);
+		qof_instance_set (inst, "export-pdf-dir", dirname);
+		gncOwnerCommitEdit(owner);
             }
         }
     }
diff --git a/test-templates/Makefile.decl b/test-templates/Makefile.decl
index dcc69c1..0f163a3 100644
--- a/test-templates/Makefile.decl
+++ b/test-templates/Makefile.decl
@@ -23,7 +23,7 @@ endif
 # test-nonrecursive: run tests only in cwd
 test-nonrecursive: ${TEST_PROGS}
 if !PLATFORM_WIN32
-	@test -z "${TEST_PROGS}" || MALLOC_CHECK_=2 MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) ${GTESTER} --verbose ${TEST_PROGS}
+	@test -z "${TEST_PROGS}" || MALLOC_CHECK_=2 MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) ${TESTS_ENVIRONMENT} ${GTESTER} --verbose ${TEST_PROGS}
 endif
 
 # test-report: run tests in subdirs and generate report

commit ae98012d0c03c1fc6732c7cb82bf52050e3789bf
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Wed May 7 18:08:34 2014 +0200

    Revert "Merge branch 'private-kvp'"
    
    This reverts commit f49983b8012197933c793fe94994ac5afa1d8d75, reversing
    changes made to acad5a02bbc04cb17b33c89ed36d839416db8f10.

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4fd491b..f4d0905 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -404,6 +404,7 @@ src/import-export/import-backend.c
 src/import-export/import-commodity-matcher.c
 src/import-export/import-format-dialog.c
 src/import-export/import-main-matcher.c
+src/import-export/import-match-map.c
 src/import-export/import-match-picker.c
 src/import-export/import-parse.c
 src/import-export/import-settings.c
diff --git a/src/app-utils/business-helpers.c b/src/app-utils/business-helpers.c
index 618e01e..f4c75fa 100644
--- a/src/app-utils/business-helpers.c
+++ b/src/app-utils/business-helpers.c
@@ -33,7 +33,7 @@ GncTaxTable* gnc_business_get_default_tax_table (QofBook *book, GncOwnerType own
     GNCOptionDB *odb;
 
     odb = gnc_option_db_new_for_type (GNC_ID_BOOK);
-    qof_book_load_options (book, gnc_option_db_load_from_kvp, odb);
+    gnc_option_db_load_from_kvp (odb, qof_book_get_slots (book));
 
     switch (ownertype)
     {
diff --git a/src/app-utils/gnc-accounting-period.c b/src/app-utils/gnc-accounting-period.c
index e7dd8e7..3c17ac9 100644
--- a/src/app-utils/gnc-accounting-period.c
+++ b/src/app-utils/gnc-accounting-period.c
@@ -102,13 +102,15 @@ get_fy_end(void)
 {
     QofBook *book;
     KvpFrame *book_frame;
-    GDate *date = NULL;
+    gint64 month, day;
 
     book = gnc_get_current_book();
-    qof_instance_get (QOF_INSTANCE (book),
-		      "fy-end", &date,
-		      NULL);
-    return date;
+    book_frame = qof_book_get_slots(book);
+    month = kvp_frame_get_gint64(book_frame, "/book/fyear_end/month");
+    day = kvp_frame_get_gint64(book_frame, "/book/fyear_end/day");
+    if (g_date_valid_dmy(day, month, 2005 /* not leap year */))
+        return g_date_new_dmy(day, month, G_DATE_BAD_YEAR);
+    return NULL;
 }
 
 time64
diff --git a/src/app-utils/gnc-sx-instance-model.c b/src/app-utils/gnc-sx-instance-model.c
index bfe2701..744c274 100644
--- a/src/app-utils/gnc-sx-instance-model.c
+++ b/src/app-utils/gnc-sx-instance-model.c
@@ -176,9 +176,10 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
 {
     GHashTable *var_hash = (GHashTable*)var_hash_data;
     GList *split_list;
+    kvp_frame *kvpf;
+    kvp_value *kvp_val;
     Split *s;
-    gchar *credit_formula = NULL;
-    gchar *debit_formula = NULL;
+    char *str;
     gnc_commodity *first_cmdty = NULL;
 
     split_list = xaccTransGetSplitList(txn);
@@ -190,16 +191,16 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
     for ( ; split_list; split_list = split_list->next)
     {
         gnc_commodity *split_cmdty = NULL;
-        GncGUID *acct_guid = NULL;
+        GncGUID *acct_guid;
         Account *acct;
 
         s = (Split*)split_list->data;
-
-        qof_instance_get (QOF_INSTANCE (s),
-			  "sx-account", &acct_guid,
-			  "sx-credit-formula", &credit_formula,
-			  "sx-debit-formula", &debit_formula,
-			  NULL);
+        kvpf = xaccSplitGetSlots(s);
+        kvp_val = kvp_frame_get_slot_path(kvpf,
+                                          GNC_SX_ID,
+                                          GNC_SX_ACCOUNT,
+                                          NULL);
+        acct_guid = kvp_value_get_guid(kvp_val);
         acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
         split_cmdty = xaccAccountGetCommodity(acct);
         if (first_cmdty == NULL)
@@ -225,16 +226,31 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
         }
 
         // existing... ------------------------------------------
-	if (credit_formula && strlen(credit_formula) != 0)
-	{
-	    gnc_sx_parse_vars_from_formula(credit_formula, var_hash, NULL);
-	}
-	if (debit_formula && strlen(debit_formula) != 0)
-	{
-	    gnc_sx_parse_vars_from_formula(debit_formula, var_hash, NULL);
-	}
-	g_free (credit_formula);
-	g_free (debit_formula);
+        kvp_val = kvp_frame_get_slot_path(kvpf,
+                                          GNC_SX_ID,
+                                          GNC_SX_CREDIT_FORMULA,
+                                          NULL);
+        if (kvp_val != NULL)
+        {
+            str = kvp_value_get_string(kvp_val);
+            if (str && strlen(str) != 0)
+            {
+                gnc_sx_parse_vars_from_formula(str, var_hash, NULL);
+            }
+        }
+
+        kvp_val = kvp_frame_get_slot_path(kvpf,
+                                          GNC_SX_ID,
+                                          GNC_SX_DEBIT_FORMULA,
+                                          NULL);
+        if (kvp_val != NULL)
+        {
+            str = kvp_value_get_string(kvp_val);
+            if (str && strlen(str) != 0)
+            {
+                gnc_sx_parse_vars_from_formula(str, var_hash, NULL);
+            }
+        }
     }
 
     return 0;
@@ -884,15 +900,31 @@ typedef struct _SxTxnCreationData
 } SxTxnCreationData;
 
 static gboolean
-_get_template_split_account(const SchedXaction* sx,
-			    const Split *template_split,
-			    Account **split_acct,
-			    GList **creation_errors)
+_get_template_split_account(const SchedXaction* sx, const Split *template_split, Account **split_acct, GList **creation_errors)
 {
-    GncGUID *acct_guid = NULL;
-    qof_instance_get (QOF_INSTANCE (template_split),
-		      "sx-account", &acct_guid,
-		      NULL);
+    GncGUID *acct_guid;
+    kvp_frame *split_kvpf;
+    kvp_value *kvp_val;
+
+    split_kvpf = xaccSplitGetSlots(template_split);
+    /* contains the guid of the split's actual account. */
+    kvp_val = kvp_frame_get_slot_path(split_kvpf,
+                                      GNC_SX_ID,
+                                      GNC_SX_ACCOUNT,
+                                      NULL);
+    if (kvp_val == NULL)
+    {
+        GString *err = g_string_new("");
+        g_string_printf(err, "Null account kvp value for SX [%s], cancelling creation.",
+                        xaccSchedXactionGetName(sx));
+        g_critical("%s", err->str);
+        if (creation_errors != NULL)
+            *creation_errors = g_list_append(*creation_errors, err);
+        else
+            g_string_free(err, TRUE);
+        return FALSE;
+    }
+    acct_guid = kvp_value_get_guid( kvp_val );
     *split_acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
     if (*split_acct == NULL)
     {
@@ -914,34 +946,34 @@ _get_template_split_account(const SchedXaction* sx,
 }
 
 static void
-_get_sx_formula_value(const SchedXaction* sx,
-		      const Split *template_split,
-		      gnc_numeric *numeric,
-		      GList **creation_errors,
-		      const char *formula_key,
-		      const char* numeric_key,
-		      GHashTable *variable_bindings)
+_get_sx_formula_value(const SchedXaction* sx, const Split *template_split, gnc_numeric *numeric, GList **creation_errors, const char *formula_key, const char* numeric_key, GHashTable *variable_bindings)
 {
-
-    char *formula_str = NULL, *parseErrorLoc = NULL;
-    gnc_numeric *numeric_val = NULL;
-    qof_instance_get (QOF_INSTANCE (template_split),
-		      formula_key, &formula_str,
-		      numeric_key, &numeric_val,
-		      NULL);
-
-    if (numeric_val != NULL &&
-	gnc_numeric_check(*numeric_val) == GNC_ERROR_OK &&
-	!gnc_numeric_zero_p(*numeric_val))
+    kvp_frame *split_kvpf;
+    kvp_value *kvp_val;
+    char *formula_str, *parseErrorLoc;
+
+    split_kvpf = xaccSplitGetSlots(template_split);
+
+    /* First look up the gnc_numeric value in the template split */
+    kvp_val = kvp_frame_get_slot_path(split_kvpf,
+                                      GNC_SX_ID,
+                                      numeric_key,
+                                      NULL);
+    *numeric = kvp_value_get_numeric(kvp_val);
+    if ((gnc_numeric_check(*numeric) == GNC_ERROR_OK)
+            && !gnc_numeric_zero_p(*numeric))
     {
         /* Already a valid non-zero result? Then return and don't
          * parse the string. Luckily we avoid any locale problems with
          * decimal points here! Phew. */
-	numeric->num = numeric_val->num;
-	numeric->denom = numeric_val->denom;
         return;
     }
 
+    kvp_val = kvp_frame_get_slot_path(split_kvpf,
+                                      GNC_SX_ID,
+                                      formula_key,
+                                      NULL);
+    formula_str = kvp_value_get_string(kvp_val);
     if (formula_str != NULL && strlen(formula_str) != 0)
     {
         GHashTable *parser_vars = NULL;
@@ -978,17 +1010,13 @@ _get_sx_formula_value(const SchedXaction* sx,
 static void
 _get_credit_formula_value(GncSxInstance *instance, const Split *template_split, gnc_numeric *credit_num, GList **creation_errors)
 {
-    _get_sx_formula_value(instance->parent->sx, template_split, credit_num,
-			  creation_errors, "sx-credit-formula",
-			  "sx-credit-numeric", instance->variable_bindings);
+    _get_sx_formula_value(instance->parent->sx, template_split, credit_num, creation_errors, GNC_SX_CREDIT_FORMULA, GNC_SX_CREDIT_NUMERIC, instance->variable_bindings);
 }
 
 static void
 _get_debit_formula_value(GncSxInstance *instance, const Split *template_split, gnc_numeric *debit_num, GList **creation_errors)
 {
-    _get_sx_formula_value(instance->parent->sx, template_split, debit_num,
-			  creation_errors, "sx-debit-formula",
-			  "sx-debit-numeric", instance->variable_bindings);
+    _get_sx_formula_value(instance->parent->sx, template_split, debit_num, creation_errors, GNC_SX_DEBIT_FORMULA, GNC_SX_DEBIT_NUMERIC, instance->variable_bindings);
 }
 
 static gboolean
@@ -1007,7 +1035,7 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
        as not finding the approrpiate Accounts and not being able to
        parse the formula|credit/debit strings. */
 
-    new_txn = xaccTransCloneNoKvp(template_txn);
+    new_txn = xaccTransClone(template_txn);
     xaccTransBeginEdit(new_txn);
 
     g_debug("creating template txn desc [%s] for sx [%s]",
@@ -1016,6 +1044,9 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
 
     g_debug("template txn currency is %s", gnc_commodity_get_mnemonic(xaccTransGetCurrency (template_txn)));
 
+    /* clear any copied KVP data */
+    qof_instance_set_slots(QOF_INSTANCE(new_txn), kvp_frame_new());
+
     /* Bug#500427: copy the notes, if any */
     if (xaccTransGetNotes(template_txn) != NULL)
     {
@@ -1059,6 +1090,9 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
             break;
         }
 
+        /* clear out any copied Split frame data. */
+        qof_instance_set_slots(QOF_INSTANCE(copying_split), kvp_frame_new());
+
         split_cmdty = xaccAccountGetCommodity(split_acct);
         if (first_cmdty == NULL)
         {
@@ -1181,10 +1215,13 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
     }
 
     {
-	qof_instance_set (QOF_INSTANCE (new_txn),
-			  "from-sched-xaction",
-			  xaccSchedXactionGetGUID(creation_data->instance->parent->sx),
-			  NULL);
+        kvp_frame *txn_frame;
+        txn_frame = xaccTransGetSlots(new_txn);
+        kvp_frame_set_guid(txn_frame, "from-sched-xaction",
+		  xaccSchedXactionGetGUID(creation_data->instance->parent->sx));
+/* The transaction was probably marked dirty by xaccTransSetCurrency,
+ * but just in case: */
+	qof_instance_set_dirty (QOF_INSTANCE (new_txn));
     }
 
     xaccTransCommitEdit(new_txn);
@@ -1594,14 +1631,9 @@ create_cashflow_helper(Transaction *template_txn, void *user_data)
             gint gncn_error;
 
             /* Credit value */
-            _get_sx_formula_value(creation_data->sx, template_split,
-				  &credit_num, creation_data->creation_errors,
-				  "sx-credit-formula", "sx-credit-numeric",
-				  NULL);
+            _get_sx_formula_value(creation_data->sx, template_split, &credit_num, creation_data->creation_errors, GNC_SX_CREDIT_FORMULA, GNC_SX_CREDIT_NUMERIC, NULL);
             /* Debit value */
-            _get_sx_formula_value(creation_data->sx, template_split,
-				  &debit_num, creation_data->creation_errors,
-				  "sx-debit-formula", "sx-debit-numeric", NULL);
+            _get_sx_formula_value(creation_data->sx, template_split, &debit_num, creation_data->creation_errors, GNC_SX_DEBIT_FORMULA, GNC_SX_DEBIT_NUMERIC, NULL);
 
             /* The resulting cash flow number: debit minus credit,
              * multiplied with the count factor. */
diff --git a/src/app-utils/option-util.h b/src/app-utils/option-util.h
index 5ad66e2..a37fccb 100644
--- a/src/app-utils/option-util.h
+++ b/src/app-utils/option-util.h
@@ -33,7 +33,7 @@
 
 typedef struct gnc_option GNCOption;
 typedef struct gnc_option_section GNCOptionSection;
-/* typedef struct gnc_option_db GNCOptionDB is in qof-book.h */
+typedef struct gnc_option_db GNCOptionDB;
 
 typedef int GNCOptionDBHandle;
 
diff --git a/src/app-utils/test/Makefile.am b/src/app-utils/test/Makefile.am
index 75d0ab8..3a00263 100644
--- a/src/app-utils/test/Makefile.am
+++ b/src/app-utils/test/Makefile.am
@@ -1,5 +1,3 @@
-include $(top_srcdir)/test-templates/Makefile.decl
-
 TESTS = \
   test-link-module \
   test-load-module \
@@ -54,7 +52,7 @@ check_PROGRAMS = \
   test-print-queries \
   test-sx
 
-EXTRA_DIST += \
+EXTRA_DIST = \
   test-load-module
 
 AM_CPPFLAGS = \
@@ -68,17 +66,3 @@ AM_CPPFLAGS = \
   -I${top_srcdir}/src/libqof/qof \
   ${GUILE_CFLAGS} \
   ${GLIB_CFLAGS}
-
-TEST_PROGS += test-app-utils
-
-noinst_PROGRAMS = ${TEST_PROGS} ${CHECK_PROGS}
-
-test_app_utils_SOURCES = \
-	test-app-utils.c \
-	test-option-util.c
-
-test_app_utils_CFLAGS = \
-	${DEFAULT_INCLUDES} \
-	-I${top_srcdir}/${MODULEPATH}/ \
-	-DTESTPROG=test_app_utils \
-	${GLIB_CFLAGS}
diff --git a/src/app-utils/test/test-app-utils.c b/src/app-utils/test/test-app-utils.c
deleted file mode 100644
index ee0f274..0000000
--- a/src/app-utils/test/test-app-utils.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/********************************************************************
- * test-app-utils.c: GLib g_test test execution file.		    *
- * Copyright 2013 John Ralls <jralls at ceridwen.us>		    *
- *                                                                  *
- * This program is free software; you can redistribute it and/or    *
- * modify it under the terms of the GNU General Public License as   *
- * published by the Free Software Foundation; either version 2 of   *
- * the License, or (at your option) any later version.              *
- *                                                                  *
- * This program is distributed in the hope that it will be useful,  *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
- * GNU General Public License for more details.                     *
- *                                                                  *
- * You should have received a copy of the GNU General Public License*
- * along with this program; if not, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-
-#include <config.h>
-#include <glib.h>
-#include <qof.h>
-#include <libguile.h>
-#include <gnc-module.h>
-
-extern void test_suite_option_util (void);
-
-static void
-guile_main (void *closure, int argc, char **argv)
-{
-    GNCModule mod;
-    int retval;
-    gnc_module_system_init ();
-    mod = gnc_module_load ("gnucash/app-utils", 0);
-
-    test_suite_option_util ();
-    retval = g_test_run ();
-
-    exit (retval);
-}
-
-int
-main (int argc, char *argv[])
-{
-    qof_init (); 			/* Initialize the GObject system */
-    qof_log_init_filename_special ("stderr"); /* Init the log system */
-    g_test_init (&argc, &argv, NULL); 	/* initialize test program */
-    //qof_log_set_level("gnc", G_LOG_LEVEL_DEBUG);
-    g_test_bug_base("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */
-    g_setenv ("GNC_UNINSTALLED", "1", TRUE);
-    scm_boot_guile (argc, argv, guile_main, NULL);
-
-}
diff --git a/src/app-utils/test/test-option-util.c b/src/app-utils/test/test-option-util.c
deleted file mode 100644
index dc99f32..0000000
--- a/src/app-utils/test/test-option-util.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/********************************************************************
- * test-option-util.c: GLib g_test test suite for Split.c.	    *
- * Copyright 2013 John Ralls <jralls at ceridwen.us>		    *
- *                                                                  *
- * This program is free software; you can redistribute it and/or    *
- * modify it under the terms of the GNU General Public License as   *
- * published by the Free Software Foundation; either version 2 of   *
- * the License, or (at your option) any later version.              *
- *                                                                  *
- * This program is distributed in the hope that it will be useful,  *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
- * GNU General Public License for more details.                     *
- *                                                                  *
- * You should have received a copy of the GNU General Public License*
- * along with this program; if not, you can retrieve it from        *
- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html            *
- * or contact:                                                      *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
- ********************************************************************/
-
-#include <config.h>
-#include <glib.h>
-#include <unittest-support.h>
-#include <qofbookslots.h>
-
-#include "../option-util.h"
-
-static const gchar *suitename = "/app-utils/option-util";
-void test_suite_option_util (void);
-
-typedef struct
-{
-    QofBook *book;
-    GSList *hdlrs;
-} Fixture;
-
-/* Expose a mostly-private QofInstance function to load options into
- * the Book.
- */
-extern KvpFrame *qof_instance_get_slots (QofInstance*);
-
-static void
-setup (Fixture *fixture, gconstpointer pData)
-{
-    fixture->book = qof_book_new ();
-    fixture->hdlrs = NULL;
-}
-
-static void
-setup_kvp (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book;
-    KvpFrame *slots;
-    setup (fixture, pData);
-    book = fixture->book;
-    slots = qof_instance_get_slots (QOF_INSTANCE (book));
-    qof_begin_edit (QOF_INSTANCE (book));
-    qof_instance_set (QOF_INSTANCE (book),
-		      "trading-accts", "t",
-		      "split-action-num-field", "t",
-		      "autoreadonly-days", (double)21,
-		      NULL);
-
-    kvp_frame_set_string (slots, "options/Business/Company Name",
-			  "Bogus Company");
-    qof_commit_edit (QOF_INSTANCE (book));
-}
-
-static void
-teardown (Fixture *fixture, gconstpointer pData)
-{
-    qof_book_destroy (fixture->book);
-    g_slist_free_full (fixture->hdlrs, test_free_log_handler);
-    test_clear_error_list();
-}
-
-static void
-test_option_load_from_kvp (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = fixture->book;
-    GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK);
-
-    qof_book_load_options (book, gnc_option_db_load_from_kvp, odb);
-    g_assert (gnc_option_db_lookup_boolean_option (odb, OPTION_SECTION_ACCOUNTS,
- OPTION_NAME_TRADING_ACCOUNTS, FALSE));
-    g_assert_cmpstr (gnc_option_db_lookup_string_option (odb, "Business", "Company Name", FALSE), ==, "Bogus Company");
-    g_assert_cmpfloat (gnc_option_db_lookup_number_option (odb, OPTION_SECTION_ACCOUNTS, OPTION_NAME_AUTO_READONLY_DAYS, FALSE), ==, 21);
-
-    gnc_option_db_destroy (odb);
-}
-
-static void
-test_option_save_to_kvp (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = fixture->book;
-    GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK);
-    KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book));
-
-    g_assert (gnc_option_db_set_boolean_option (odb, OPTION_SECTION_ACCOUNTS,
-						OPTION_NAME_TRADING_ACCOUNTS,
-						TRUE));
-    g_assert (gnc_option_db_set_string_option (odb, "Business", "Company Name",
-					       "Bogus Company"));
-    g_assert (gnc_option_db_set_number_option (odb, OPTION_SECTION_ACCOUNTS,
-					       OPTION_NAME_AUTO_READONLY_DAYS,
-					       17));
-    qof_book_save_options (book, gnc_option_db_save_to_kvp, odb, TRUE);
-    g_assert_cmpstr (kvp_frame_get_string (slots,  "options/Accounts/Use Trading Accounts"), == , "t");
-    g_assert_cmpstr (kvp_frame_get_string (slots, "options/Business/Company Name"), ==, "Bogus Company");
-    g_assert_cmpfloat (kvp_frame_get_double (slots, "options/Accounts/Day Threshold for Read-Only Transactions (red line)"), ==, 17);
-
-    gnc_option_db_destroy (odb);
-}
-
-
-void
-test_suite_option_util (void)
-{
-    GNC_TEST_ADD (suitename, "Option DB Load from KVP", Fixture, NULL, setup_kvp, test_option_load_from_kvp, teardown);
-    GNC_TEST_ADD (suitename, "Option DB Save to KVP", Fixture, NULL, setup, test_option_save_to_kvp, teardown);
-
-}
diff --git a/src/backend/dbi/test/test-dbi-stuff.c b/src/backend/dbi/test/test-dbi-stuff.c
index c0e1d1e..4ac96ae 100644
--- a/src/backend/dbi/test/test-dbi-stuff.c
+++ b/src/backend/dbi/test/test-dbi-stuff.c
@@ -168,9 +168,6 @@ compare_sxs( QofBook* book_1, QofBook* book_2 )
                 compare_single_sx, "Scheduled transaction lists match" );
 }
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance *);
-
 static void
 compare_single_lot( QofInstance* inst, gpointer user_data )
 {
@@ -184,8 +181,8 @@ compare_single_lot( QofInstance* inst, gpointer user_data )
                                 gnc_lot_get_account (lot_2), FALSE ));
     g_assert_cmpint (gnc_lot_is_closed (lot_1), ==, gnc_lot_is_closed (lot_2));
 
-    g_assert (kvp_frame_compare (qof_instance_get_slots (QOF_INSTANCE (lot_1)),
-                                 qof_instance_get_slots (QOF_INSTANCE (lot_2))) == 0);
+    g_assert (kvp_frame_compare (gnc_lot_get_slots (lot_1),
+                                 gnc_lot_get_slots (lot_2)) == 0);
     splits1 = gnc_lot_get_split_list (lot_1);
     splits2 = gnc_lot_get_split_list (lot_2);
     g_assert_cmpint (g_list_length (splits1), ==, g_list_length (splits2));
diff --git a/src/backend/sql/gnc-account-sql.c b/src/backend/sql/gnc-account-sql.c
index 7d6b3a3..fb1ce98 100644
--- a/src/backend/sql/gnc-account-sql.c
+++ b/src/backend/sql/gnc-account-sql.c
@@ -294,14 +294,12 @@ load_all_accounts( GncSqlBackend* be )
         {
             acct_balances_t* balances = (acct_balances_t*)bal->data;
 
-	    qof_instance_increase_editlevel (balances->acct);
             g_object_set( balances->acct,
                           "start-balance", &balances->balance,
                           "start-cleared-balance", &balances->cleared_balance,
                           "start-reconciled-balance", &balances->reconciled_balance,
                           NULL);
 
-	    qof_instance_decrease_editlevel (balances->acct);
         }
         if ( bal_slist != NULL )
         {
@@ -420,9 +418,7 @@ load_account_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, account, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-address-sql.c b/src/backend/sql/gnc-address-sql.c
index a3f3994..a29d4aa 100644
--- a/src/backend/sql/gnc-address-sql.c
+++ b/src/backend/sql/gnc-address-sql.c
@@ -115,9 +115,7 @@ load_address( const GncSqlBackend* be, GncSqlRow* row,
     }
     if ( table_row->gobj_param_name != NULL )
     {
-	qof_instance_increase_editlevel (pObject);
         g_object_set( pObject, table_row->gobj_param_name, addr, NULL );
-	qof_instance_decrease_editlevel (pObject);
     }
     else
     {
diff --git a/src/backend/sql/gnc-backend-sql.c b/src/backend/sql/gnc-backend-sql.c
index 85f2daa..6169388 100644
--- a/src/backend/sql/gnc-backend-sql.c
+++ b/src/backend/sql/gnc-backend-sql.c
@@ -1204,11 +1204,7 @@ const GncSqlColumnTableEntry* table_row )
     s = g_value_get_string( val );
     if ( table_row->gobj_param_name != NULL )
     {
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         g_object_set( pObject, table_row->gobj_param_name, s, NULL );
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
     }
     else
     {
@@ -1312,11 +1308,7 @@ load_int( const GncSqlBackend* be, GncSqlRow* row,
     }
     if ( table_row->gobj_param_name != NULL )
     {
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         g_object_set( pObject, table_row->gobj_param_name, int_value, NULL );
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
     }
     else
     {
@@ -1414,11 +1406,7 @@ load_boolean( const GncSqlBackend* be, GncSqlRow* row,
     }
     if ( table_row->gobj_param_name != NULL )
     {
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         g_object_set( pObject, table_row->gobj_param_name, int_value, NULL );
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
     }
     else
     {
@@ -1511,11 +1499,7 @@ load_int64( const GncSqlBackend* be, GncSqlRow* row,
     }
     if ( table_row->gobj_param_name != NULL )
     {
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         g_object_set( pObject, table_row->gobj_param_name, i64_value, NULL );
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
     }
     else
     {
@@ -1622,11 +1606,7 @@ load_double( const GncSqlBackend* be, GncSqlRow* row,
         }
         if ( table_row->gobj_param_name != NULL )
         {
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
             g_object_set( pObject, table_row->gobj_param_name, d_value, NULL );
-	    if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
         }
         else
         {
@@ -1725,11 +1705,7 @@ load_guid( const GncSqlBackend* be, GncSqlRow* row,
     {
         if ( table_row->gobj_param_name != NULL )
         {
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
             g_object_set( pObject, table_row->gobj_param_name, pGuid, NULL );
-	    if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
         }
         else
         {
@@ -1936,11 +1912,7 @@ load_timespec( const GncSqlBackend* be, GncSqlRow* row,
     {
         if (table_row->gobj_param_name != NULL)
         {
-	if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
             g_object_set( pObject, table_row->gobj_param_name, &ts, NULL );
-	    if (QOF_IS_INSTANCE (pObject))
-	    qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
         }
         else
         {
@@ -2042,11 +2014,7 @@ load_date( const GncSqlBackend* be, GncSqlRow* row,
 	    g_date_time_unref (gdt);
 	    if ( table_row->gobj_param_name != NULL )
 	    {
-		if (QOF_IS_INSTANCE (pObject))
-		    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
 		g_object_set( pObject, table_row->gobj_param_name, date, NULL );
-		if (QOF_IS_INSTANCE (pObject))
-		    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
 	    }
 	    else
 	    {
@@ -2080,12 +2048,7 @@ load_date( const GncSqlBackend* be, GncSqlRow* row,
                     date = g_date_new_dmy( day, month, year );
                     if ( table_row->gobj_param_name != NULL )
                     {
-			if (QOF_IS_INSTANCE (pObject))
-			    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
-                        g_object_set (pObject, table_row->gobj_param_name,
-				      date, NULL);
-			if (QOF_IS_INSTANCE (pObject))
-			    qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
+                        g_object_set( pObject, table_row->gobj_param_name, date, NULL );
                     }
                     else
                     {
@@ -2224,11 +2187,7 @@ load_numeric( const GncSqlBackend* be, GncSqlRow* row,
     {
         if ( table_row->gobj_param_name != NULL )
         {
-	    if (QOF_IS_INSTANCE (pObject))
-		qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
             g_object_set( pObject, table_row->gobj_param_name, &n, NULL );
-	    if (QOF_IS_INSTANCE (pObject))
-		qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
         }
         else
         {
diff --git a/src/backend/sql/gnc-bill-term-sql.c b/src/backend/sql/gnc-bill-term-sql.c
index eaf7243..4846b0f 100644
--- a/src/backend/sql/gnc-bill-term-sql.c
+++ b/src/backend/sql/gnc-bill-term-sql.c
@@ -363,9 +363,7 @@ load_billterm_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, term, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-budget-sql.c b/src/backend/sql/gnc-budget-sql.c
index 4c697c9..59a7efb 100644
--- a/src/backend/sql/gnc-budget-sql.c
+++ b/src/backend/sql/gnc-budget-sql.c
@@ -500,9 +500,7 @@ load_budget_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, budget, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-commodity-sql.c b/src/backend/sql/gnc-commodity-sql.c
index 1f8f556..2389946 100644
--- a/src/backend/sql/gnc-commodity-sql.c
+++ b/src/backend/sql/gnc-commodity-sql.c
@@ -283,9 +283,7 @@ load_commodity_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, commodity, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else if ( setter != NULL )
             {
diff --git a/src/backend/sql/gnc-invoice-sql.c b/src/backend/sql/gnc-invoice-sql.c
index 72c1cd2..8788960 100644
--- a/src/backend/sql/gnc-invoice-sql.c
+++ b/src/backend/sql/gnc-invoice-sql.c
@@ -303,9 +303,7 @@ load_invoice_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, invoice, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-lots-sql.c b/src/backend/sql/gnc-lots-sql.c
index 22c4a70..a6ee240 100644
--- a/src/backend/sql/gnc-lots-sql.c
+++ b/src/backend/sql/gnc-lots-sql.c
@@ -235,9 +235,7 @@ load_lot_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, lot, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-order-sql.c b/src/backend/sql/gnc-order-sql.c
index a7bc177..46b0ae0 100644
--- a/src/backend/sql/gnc-order-sql.c
+++ b/src/backend/sql/gnc-order-sql.c
@@ -220,9 +220,7 @@ load_order_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, order, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-owner-sql.c b/src/backend/sql/gnc-owner-sql.c
index 2e779f0..4b89c54 100644
--- a/src/backend/sql/gnc-owner-sql.c
+++ b/src/backend/sql/gnc-owner-sql.c
@@ -156,9 +156,7 @@ load_owner( const GncSqlBackend* be, GncSqlRow* row,
 
     if ( table_row->gobj_param_name != NULL )
     {
-	qof_instance_increase_editlevel (pObject);
         g_object_set( pObject, table_row->gobj_param_name, &owner, NULL );
-	qof_instance_decrease_editlevel (pObject);
     }
     else
     {
diff --git a/src/backend/sql/gnc-tax-table-sql.c b/src/backend/sql/gnc-tax-table-sql.c
index fbf5d37..21466d4 100644
--- a/src/backend/sql/gnc-tax-table-sql.c
+++ b/src/backend/sql/gnc-tax-table-sql.c
@@ -523,9 +523,7 @@ load_taxtable_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, taxtable, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/sql/gnc-transaction-sql.c b/src/backend/sql/gnc-transaction-sql.c
index 46fc3d9..0ea2189 100644
--- a/src/backend/sql/gnc-transaction-sql.c
+++ b/src/backend/sql/gnc-transaction-sql.c
@@ -415,7 +415,6 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
                           "end-reconciled-balance", &pnew_end_r_bal,
                           NULL );
 
-	    qof_instance_increase_editlevel (balns-acc);
             if ( !gnc_numeric_eq( *pnew_end_bal, balns->end_bal ) )
             {
                 adj = gnc_numeric_sub( balns->end_bal, *pnew_end_bal,
@@ -423,7 +422,6 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
                 balns->start_bal = gnc_numeric_add( balns->start_bal, adj,
                                                     GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                 g_object_set( balns->acc, "start-balance", &balns->start_bal, NULL );
-		qof_instance_decrease_editlevel (balns-acc);
             }
             if ( !gnc_numeric_eq( *pnew_end_c_bal, balns->end_cleared_bal ) )
             {
@@ -441,7 +439,6 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
                                               GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                 g_object_set( balns->acc, "start-reconciled-balance", &balns->start_reconciled_bal, NULL );
             }
-	    qof_instance_decrease_editlevel (balns-acc);
             xaccAccountRecomputeBalance( balns->acc );
             g_free( pnew_end_bal );
             g_free( pnew_end_c_bal );
@@ -1464,9 +1461,7 @@ load_tx_guid( const GncSqlBackend* be, GncSqlRow* row,
         {
             if ( table_row->gobj_param_name != NULL )
             {
-		qof_instance_increase_editlevel (pObject);
                 g_object_set( pObject, table_row->gobj_param_name, tx, NULL );
-		qof_instance_decrease_editlevel (pObject);
             }
             else
             {
diff --git a/src/backend/xml/gnc-account-xml-v2.c b/src/backend/xml/gnc-account-xml-v2.c
index 85d475e..8137147 100644
--- a/src/backend/xml/gnc-account-xml-v2.c
+++ b/src/backend/xml/gnc-account-xml-v2.c
@@ -71,9 +71,6 @@ const gchar *account_version_string = "2.0.0";
 #define act_hidden_string "act:hidden"
 #define act_placeholder_string "act:placeholder"
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance *);
-
 xmlNodePtr
 gnc_account_dom_tree_create(Account *act,
                             gboolean exporting,
@@ -137,7 +134,7 @@ gnc_account_dom_tree_create(Account *act,
         xmlAddChild(ret, text_to_dom_tree(act_description_string, str));
     }
 
-    kf = qof_instance_get_slots (QOF_INSTANCE (act));
+    kf = xaccAccountGetSlots(act);
     if (kf)
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree(act_slots_string, kf);
@@ -373,7 +370,7 @@ account_slots_handler (xmlNodePtr node, gpointer act_pdata)
     struct account_pdata *pdata = act_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, qof_instance_get_slots (QOF_INSTANCE (pdata->account)));
+           (node, xaccAccountGetSlots (pdata->account));
 }
 
 static gboolean
diff --git a/src/backend/xml/gnc-address-xml-v2.c b/src/backend/xml/gnc-address-xml-v2.c
index 1815e0b..2e84319 100644
--- a/src/backend/xml/gnc-address-xml-v2.c
+++ b/src/backend/xml/gnc-address-xml-v2.c
@@ -58,9 +58,6 @@ const gchar *address_version_string = "2.0.0";
 #define addr_email_string	"addr:email"
 #define addr_slots_string	"addr:slots"
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance*);
-
 static void
 maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
 {
@@ -192,7 +189,7 @@ address_slots_handler (xmlNodePtr node, gpointer addr_pdata)
     struct address_pdata *pdata = addr_pdata;
 
     return dom_tree_to_kvp_frame_given
-        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->address)));
+           (node, xaccAccountGetSlots (pdata->address));
 }
 
 static struct dom_tree_handler address_handlers_v2[] =
diff --git a/src/backend/xml/gnc-book-xml-v2.c b/src/backend/xml/gnc-book-xml-v2.c
index 6fcae46..aa7a14f 100644
--- a/src/backend/xml/gnc-book-xml-v2.c
+++ b/src/backend/xml/gnc-book-xml-v2.c
@@ -109,10 +109,10 @@ gnc_book_dom_tree_create(QofBook *book)
     xmlAddChild(ret, guid_to_dom_tree(book_id_string,
                                       qof_book_get_guid(book)));
 
-    if (qof_instance_get_slots (QOF_INSTANCE (book)))
+    if (qof_book_get_slots(book))
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string,
-                             qof_instance_get_slots (QOF_INSTANCE (book)));
+                             qof_book_get_slots(book));
         if (kvpnode)
             xmlAddChild(ret, kvpnode);
     }
@@ -162,10 +162,10 @@ write_book_parts(FILE *out, QofBook *book)
     if (ferror(out) || fprintf(out, "\n") < 0)
         return FALSE;
 
-    if (qof_instance_get_slots (QOF_INSTANCE (book)))
+    if (qof_book_get_slots(book))
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string,
-                             qof_instance_get_slots (QOF_INSTANCE (book)));
+                             qof_book_get_slots(book));
         if (kvpnode)
         {
             xmlElemDump(out, NULL, kvpnode);
@@ -203,7 +203,7 @@ book_slots_handler (xmlNodePtr node, gpointer book_pdata)
 
     /* the below works only because the get is gaurenteed to return
      * a frame, even if its empty */
-    success = dom_tree_to_kvp_frame_given (node, qof_instance_get_slots (QOF_INSTANCE (book)));
+    success = dom_tree_to_kvp_frame_given (node, qof_book_get_slots (book));
 
     g_return_val_if_fail(success, FALSE);
 
diff --git a/src/backend/xml/gnc-entry-xml-v2.c b/src/backend/xml/gnc-entry-xml-v2.c
index 96d0e3b..713bef9 100644
--- a/src/backend/xml/gnc-entry-xml-v2.c
+++ b/src/backend/xml/gnc-entry-xml-v2.c
@@ -92,9 +92,6 @@ const gchar *entry_version_string = "2.0.0";
 #define entry_bill_string "entry:bill"
 #define entry_slots_string "entry:slots"
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance*);
-
 static void
 maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
 {
@@ -678,7 +675,7 @@ entry_slots_handler (xmlNodePtr node, gpointer entry_pdata)
     struct entry_pdata *pdata = entry_pdata;
 
     return dom_tree_to_kvp_frame_given
-        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->entry)));
+           (node, xaccAccountGetSlots (pdata->entry));
 }
 
 static struct dom_tree_handler entry_handlers_v2[] =
diff --git a/src/backend/xml/gnc-invoice-xml-v2.c b/src/backend/xml/gnc-invoice-xml-v2.c
index 901a733..2a9c769 100644
--- a/src/backend/xml/gnc-invoice-xml-v2.c
+++ b/src/backend/xml/gnc-invoice-xml-v2.c
@@ -72,9 +72,6 @@ const gchar *invoice_version_string = "2.0.0";
 #define invoice_tochargeamt_string "invoice:charge-amt"
 #define invoice_slots_string "invoice:slots"
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance *);
-
 static void
 maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
 {
@@ -413,7 +410,7 @@ invoice_slots_handler (xmlNodePtr node, gpointer invoice_pdata)
     struct invoice_pdata *pdata = invoice_pdata;
 
     return dom_tree_to_kvp_frame_given
-           (node, qof_instance_get_slots (QOF_INSTANCE (pdata->invoice)));
+           (node, xaccAccountGetSlots (pdata->invoice));
 }
 
 static struct dom_tree_handler invoice_handlers_v2[] =
diff --git a/src/backend/xml/gnc-job-xml-v2.c b/src/backend/xml/gnc-job-xml-v2.c
index 6a6f513..1ed84df 100644
--- a/src/backend/xml/gnc-job-xml-v2.c
+++ b/src/backend/xml/gnc-job-xml-v2.c
@@ -62,9 +62,6 @@ const gchar *job_version_string = "2.0.0";
 #define job_active_string "job:active"
 #define job_slots_string "job:slots"
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance*);
-
 static xmlNodePtr
 job_dom_tree_create (GncJob *job)
 {
@@ -210,7 +207,7 @@ job_slots_handler (xmlNodePtr node, gpointer job_pdata)
     struct job_pdata *pdata = job_pdata;
 
     return dom_tree_to_kvp_frame_given
-        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->job)));
+           (node, xaccAccountGetSlots (pdata->job));
 }
 
 static struct dom_tree_handler job_handlers_v2[] =
diff --git a/src/backend/xml/gnc-lot-xml-v2.c b/src/backend/xml/gnc-lot-xml-v2.c
index 503e981..f24001a 100644
--- a/src/backend/xml/gnc-lot-xml-v2.c
+++ b/src/backend/xml/gnc-lot-xml-v2.c
@@ -53,8 +53,6 @@ const gchar *lot_version_string = "2.0.0";
 #define gnc_lot_string "gnc:lot"
 #define lot_id_string "lot:id"
 #define lot_slots_string "lot:slots"
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance *);
 
 xmlNodePtr
 gnc_lot_dom_tree_create(GNCLot *lot)
@@ -68,7 +66,7 @@ gnc_lot_dom_tree_create(GNCLot *lot)
 
     xmlAddChild(ret, guid_to_dom_tree(lot_id_string, gnc_lot_get_guid(lot)));
 
-    kf = qof_instance_get_slots (QOF_INSTANCE (lot));
+    kf = gnc_lot_get_slots (lot);
     if (kf)
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree(lot_slots_string, kf);
@@ -114,7 +112,7 @@ lot_slots_handler (xmlNodePtr node, gpointer p)
 
     ENTER("(lot=%p)", pdata->lot);
     success = dom_tree_to_kvp_frame_given
-	(node, qof_instance_get_slots (QOF_INSTANCE (pdata->lot)));
+              (node, gnc_lot_get_slots (pdata->lot));
 
     LEAVE("");
     g_return_val_if_fail(success, FALSE);
diff --git a/src/backend/xml/gnc-order-xml-v2.c b/src/backend/xml/gnc-order-xml-v2.c
index cb5fdfb..c393182 100644
--- a/src/backend/xml/gnc-order-xml-v2.c
+++ b/src/backend/xml/gnc-order-xml-v2.c
@@ -46,7 +46,7 @@
 #include "gnc-order-xml-v2.h"
 #include "gnc-owner-xml-v2.h"
 
-#define _GNC_MOD_NAME   GNC_ID_ORDER
+#define _GNC_MOD_NAME	GNC_ID_ORDER
 
 static QofLogModule log_module = GNC_MOD_IO;
 
@@ -64,9 +64,6 @@ const gchar *order_version_string = "2.0.0";
 #define order_active_string "order:active"
 #define order_slots_string "order:slots"
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance*);
-
 static void
 maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
 {
@@ -251,7 +248,7 @@ order_slots_handler (xmlNodePtr node, gpointer order_pdata)
     struct order_pdata *pdata = order_pdata;
 
     return dom_tree_to_kvp_frame_given
-        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->order)));
+           (node, xaccAccountGetSlots (pdata->order));
 }
 
 static struct dom_tree_handler order_handlers_v2[] =
diff --git a/src/backend/xml/gnc-tax-table-xml-v2.c b/src/backend/xml/gnc-tax-table-xml-v2.c
index 0990e4b..aeff781 100644
--- a/src/backend/xml/gnc-tax-table-xml-v2.c
+++ b/src/backend/xml/gnc-tax-table-xml-v2.c
@@ -67,9 +67,6 @@ const gchar *taxtable_version_string = "2.0.0";
 #define ttentry_type_string "tte:type"
 #define ttentry_amount_string "tte:amount"
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance*);
-
 static void
 maybe_add_guid (xmlNodePtr ptr, const char *tag, GncTaxTable *table)
 {
@@ -385,7 +382,7 @@ taxtable_slots_handler (xmlNodePtr node, gpointer taxtable_pdata)
     struct taxtable_pdata *pdata = taxtable_pdata;
 
     return dom_tree_to_kvp_frame_given
-        (node, qof_instance_get_slots (QOF_INSTANCE (pdata->table)));
+           (node, xaccAccountGetSlots (pdata->table));
 }
 
 static struct dom_tree_handler taxtable_handlers_v2[] =
diff --git a/src/backend/xml/gnc-transaction-xml-v2.c b/src/backend/xml/gnc-transaction-xml-v2.c
index a2a3513..2ccd67a 100644
--- a/src/backend/xml/gnc-transaction-xml-v2.c
+++ b/src/backend/xml/gnc-transaction-xml-v2.c
@@ -49,9 +49,6 @@
 
 const gchar *transaction_version_string = "2.0.0";
 
-/* EFFECTIVE FRIEND FUNCTION */
-extern KvpFrame *qof_instance_get_slots (const QofInstance *);
-
 static void
 add_gnc_num(xmlNodePtr node, const gchar *tag, gnc_numeric num)
 {
@@ -132,7 +129,7 @@ split_to_dom_tree(const gchar *tag, Split *spl)
     }
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree("split:slots",
-                             qof_instance_get_slots (QOF_INSTANCE (spl)));
+                             xaccSplitGetSlots(spl));
         if (kvpnode)
         {
             xmlAddChild(ret, kvpnode);
@@ -195,7 +192,7 @@ gnc_transaction_dom_tree_create(Transaction *trn)
 
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree("trn:slots",
-                             qof_instance_get_slots (QOF_INSTANCE (trn)));
+                             xaccTransGetSlots(trn));
         if (kvpnode)
         {
             xmlAddChild(ret, kvpnode);
@@ -371,7 +368,7 @@ spl_slots_handler(xmlNodePtr node, gpointer data)
     gboolean successful;
 
     successful = dom_tree_to_kvp_frame_given(node,
-                 qof_instance_get_slots (QOF_INSTANCE (pdata->split)));
+                 xaccSplitGetSlots (pdata->split));
     g_return_val_if_fail(successful, FALSE);
 
     return TRUE;
@@ -530,7 +527,7 @@ trn_slots_handler(xmlNodePtr node, gpointer trans_pdata)
     Transaction *trn = pdata->trans;
     gboolean successful;
 
-    successful = dom_tree_to_kvp_frame_given(node, qof_instance_get_slots (QOF_INSTANCE (trn)));
+    successful = dom_tree_to_kvp_frame_given(node, xaccTransGetSlots(trn));
 
     g_return_val_if_fail(successful, FALSE);
 
diff --git a/src/backend/xml/io-gncxml-v2.c b/src/backend/xml/io-gncxml-v2.c
index 43e9590..908bff1 100644
--- a/src/backend/xml/io-gncxml-v2.c
+++ b/src/backend/xml/io-gncxml-v2.c
@@ -2182,7 +2182,7 @@ gnc_xml2_parse_with_subst (FileBackend *fbe, QofBook *book, GHashTable *subst)
                   push_data, GNC_BOOK_XML2_FILE);
 
     if (success)
-	qof_instance_set_dirty (QOF_INSTANCE (book));
+        qof_book_kvp_changed(book);
 
     return success;
 }
diff --git a/src/backend/xml/test/test-xml-account.c b/src/backend/xml/test/test-xml-account.c
index 8055489..b6838e8 100644
--- a/src/backend/xml/test/test-xml-account.c
+++ b/src/backend/xml/test/test-xml-account.c
@@ -144,7 +144,7 @@ node_and_account_equal(xmlNodePtr node, Account *act)
         {
             /* xaccAccountDeleteOldData (act); */
 
-            if (!equals_node_val_vs_kvp_frame(mark, qof_instance_get_slots(QOF_INSTANCE (act))))
+            if (!equals_node_val_vs_kvp_frame(mark, xaccAccountGetSlots(act)))
             {
                 return g_strdup("slots differ");
             }
diff --git a/src/backend/xml/test/test-xml-transaction.c b/src/backend/xml/test/test-xml-transaction.c
index 14edc79..c194397 100644
--- a/src/backend/xml/test/test-xml-transaction.c
+++ b/src/backend/xml/test/test-xml-transaction.c
@@ -306,7 +306,7 @@ node_and_transaction_equal(xmlNodePtr node, Transaction *trn)
         }
         else if (g_strcmp0((char*)mark->name, "trn:slots") == 0)
         {
-            if (!equals_node_val_vs_kvp_frame(mark, qof_instance_get_slots (QOF_INSTANCE (trn))))
+            if (!equals_node_val_vs_kvp_frame(mark, xaccTransGetSlots(trn)))
             {
                 return "slots differ";
             }
diff --git a/src/business/business-gnome/dialog-invoice.c b/src/business/business-gnome/dialog-invoice.c
index c00a5e4..5acee72 100644
--- a/src/business/business-gnome/dialog-invoice.c
+++ b/src/business/business-gnome/dialog-invoice.c
@@ -90,6 +90,8 @@
 #define GNC_PREF_ACCUM_SPLITS    "accumulate-splits"
 #define GNC_PREF_DAYS_IN_ADVANCE "days-in-advance"
 
+#define LAST_POSTED_TO_ACCT "last-posted-to-acct"
+
 void gnc_invoice_window_ok_cb (GtkWidget *widget, gpointer data);
 void gnc_invoice_window_cancel_cb (GtkWidget *widget, gpointer data);
 void gnc_invoice_window_help_cb (GtkWidget *widget, gpointer data);
@@ -679,6 +681,7 @@ gnc_dialog_post_invoice(InvoiceWindow *iw, char *message,
     GList * acct_types = NULL;
     GList * acct_commodities = NULL;
     QofInstance *owner_inst;
+    KvpFrame *kvpf;
     EntryList *entries, *entries_iter;
 
     invoice = iw_get_invoice (iw);
@@ -723,14 +726,12 @@ gnc_dialog_post_invoice(InvoiceWindow *iw, char *message,
     /* Get the due date and posted account */
     *ddue = *postdate;
     *memo = NULL;
-    {
-	GncGUID *guid = NULL;
-	owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
-	qof_instance_get (owner_inst,
-			  "invoice-last-posted-account", &guid,
-			  NULL);
-	*acc = xaccAccountLookup (guid, iw->book);
-    }
+
+    owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
+    kvpf = qof_instance_get_slots (owner_inst);
+    *acc = xaccAccountLookup (kvp_frame_get_guid (kvpf, LAST_POSTED_TO_ACCT),
+                              iw->book);
+
     /* Get the default for the accumulate option */
     *accumulate = gnc_prefs_get_bool(GNC_PREFS_GROUP_INVOICE, GNC_PREF_ACCUM_SPLITS);
 
@@ -761,6 +762,8 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
     Timespec ddue, postdate;
     gboolean accumulate;
     QofInstance *owner_inst;
+    KvpFrame *kvpf;
+    KvpValue *kvp_val;
     const char *text;
     GHashTable *foreign_currs;
     GHashTableIter foreign_currs_iter;
@@ -908,18 +911,14 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
     }
 
 
-    /* Save account as last used account in the owner's
-     * invoice-last-posted-account property.
-     */
+    /* Save account as last used account in the kvp frame of the invoice owner */
     owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
-    {
-	const GncGUID *guid = qof_instance_get_guid (QOF_INSTANCE (acc));
-	qof_begin_edit (owner_inst);
-	qof_instance_set (owner_inst,
-			  "invoice-last-posted-account", guid,
-			  NULL);
-	qof_commit_edit (owner_inst);
-    }
+    kvpf = qof_instance_get_slots (owner_inst);
+    kvp_val = kvp_value_new_guid (qof_instance_get_guid (QOF_INSTANCE (acc)));;
+    qof_begin_edit (owner_inst);
+    kvp_frame_set_slot_nc (kvpf, LAST_POSTED_TO_ACCT, kvp_val);
+    qof_instance_set_dirty (owner_inst);
+    qof_commit_edit (owner_inst);
 
     /* ... post it ... */
     if (is_cust_doc)
diff --git a/src/business/business-gnome/dialog-payment.c b/src/business/business-gnome/dialog-payment.c
index 151f678..b380f3c 100644
--- a/src/business/business-gnome/dialog-payment.c
+++ b/src/business/business-gnome/dialog-payment.c
@@ -452,15 +452,23 @@ gnc_payment_dialog_owner_changed (PaymentWindow *pw)
 {
     Account *last_acct = NULL;
     GncGUID *guid = NULL;
+    KvpValue* value;
+    KvpFrame* slots;
     GncOwner *owner = &pw->owner;
 
     /* If the owner changed, the initial invoice is no longer valid */
     pw->invoice = NULL;
 
     /* Now handle the account tree */
-    qof_instance_get (QOF_INSTANCE (owner),
-		      "payment-last-account", &guid,
-		      NULL);
+    slots = gncOwnerGetSlots(owner);
+    if (slots)
+    {
+        value = kvp_frame_get_slot_path(slots, "payment", "last_acct", NULL);
+        if (value)
+        {
+            guid = kvp_value_get_guid(value);
+        }
+    }
 
     /* refresh the post and acc available accounts, but cleanup first */
     if (pw->acct_types)
@@ -506,17 +514,20 @@ gnc_payment_dialog_post_to_changed (PaymentWindow *pw)
 static void
 gnc_payment_dialog_remember_account (PaymentWindow *pw, Account *acc)
 {
-    GncOwner *owner = &pw->owner;
-    const GncGUID *guid;
+    KvpValue* value;
+    KvpFrame* slots = gncOwnerGetSlots(&pw->owner);
 
     if (!acc) return;
+    if (!slots) return;
+
+    value = kvp_value_new_guid(xaccAccountGetGUID(acc));
+    if (!value) return;
 
-    guid = xaccAccountGetGUID(acc);
-    qof_begin_edit (QOF_INSTANCE (owner));
-    qof_instance_set (QOF_INSTANCE (owner),
-		      "payment-last-account", guid,
-		      NULL);
-    qof_commit_edit (QOF_INSTANCE (owner));
+    xaccAccountBeginEdit (acc);
+    kvp_frame_set_slot_path(slots, value, "payment", "last_acct", NULL);
+    qof_instance_set_dirty (QOF_INSTANCE (acc));
+    xaccAccountCommitEdit (acc);
+    kvp_value_delete(value);
 }
 
 
diff --git a/src/core-utils/gnc-features.c b/src/core-utils/gnc-features.c
index 5b341c9..0336fe2 100644
--- a/src/core-utils/gnc-features.c
+++ b/src/core-utils/gnc-features.c
@@ -67,12 +67,10 @@ static void gnc_features_init ()
                              g_strdup (known_features[i].desc));
 }
 
-static void gnc_features_test_one(gpointer pkey, gpointer value,
-				  gpointer data)
+static void gnc_features_test_one(const gchar *key, KvpValue *value, gpointer data)
 {
-    const gchar *key = (const gchar*)pkey;
-    const gchar *feature_desc = (const gchar*)value;
     GList **unknown_features;
+    gchar *feature_desc;
 
     g_assert(data);
     unknown_features = (GList**) data;
@@ -82,47 +80,54 @@ static void gnc_features_test_one(gpointer pkey, gpointer value,
         return;
 
     /* It is unknown, so add the description to the unknown features list: */
+    feature_desc = kvp_value_get_string(value);
     g_assert(feature_desc);
 
-    *unknown_features = g_list_prepend(*unknown_features,
-				       (gpointer)feature_desc);
+    *unknown_features = g_list_prepend(*unknown_features, feature_desc);
 }
 
 /* Check if the session requires features unknown to this version of GnuCash.
  *
- * Returns a message to display if we found unknown features, NULL if
- * we're okay.
+ * Returns a message to display if we found unknown features, NULL if we're okay.
  */
 gchar *gnc_features_test_unknown (QofBook *book)
 {
-
-    GList* features_list = NULL;
-    GHashTable *features_used = qof_book_get_features (book);
+    KvpFrame *frame = qof_book_get_slots (book);
+    KvpValue *value;
 
     /* Setup the known_features hash table */
     gnc_features_init();
 
-    /* Iterate over the members of this frame for unknown features */
-    g_hash_table_foreach (features_used, &gnc_features_test_one,
-			  &features_list);
-    if (features_list)
+    g_assert(frame);
+    value = kvp_frame_get_value(frame, "features");
+
+    if (value)
     {
-	GList *i;
-	char* msg = g_strdup(_("This Dataset contains features not supported "
-			       "by this version of GnuCash. You must use a "
-			       "newer version of GnuCash in order to support "
-			       "the following features:"
+        GList* features_list = NULL;
+        frame = kvp_value_get_frame(value);
+        g_assert(frame);
+
+        /* Iterate over the members of this frame for unknown features */
+        kvp_frame_for_each_slot(frame, &gnc_features_test_one, &features_list);
+        if (features_list)
+        {
+            GList *i;
+            char* msg = g_strdup(
+                            _("This Dataset contains features not supported by this "
+                              "version of GnuCash. You must use a newer version of "
+                              "GnuCash in order to support the following features:"
                              ));
 
-	for (i = features_list; i; i = i->next)
-	{
-	    char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
-	    g_free (msg);
-	    msg = tmp;
-	}
+            for (i = features_list; i; i = i->next)
+            {
+                char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
+                g_free (msg);
+                msg = tmp;
+            }
 
-	g_list_free(features_list);
-	return msg;
+            g_list_free(features_list);
+            return msg;
+        }
     }
 
     return NULL;
@@ -130,7 +135,9 @@ gchar *gnc_features_test_unknown (QofBook *book)
 
 void gnc_features_set_used (QofBook *book, const gchar *feature)
 {
+    KvpFrame *frame;
     const gchar *description;
+    gchar *kvp_path;
 
     g_return_if_fail (book);
     g_return_if_fail (feature);
@@ -145,7 +152,10 @@ void gnc_features_set_used (QofBook *book, const gchar *feature)
         return;
     }
 
-    qof_book_set_feature (book, feature, description);
+    frame = qof_book_get_slots (book);
+    kvp_path = g_strconcat ("/features/", feature, NULL);
+    kvp_frame_set_string (frame, kvp_path, description);
+    qof_book_kvp_changed (book);
 
 
 }
diff --git a/src/engine/Account.c b/src/engine/Account.c
index 9bc7dda..4b30953 100644
--- a/src/engine/Account.c
+++ b/src/engine/Account.c
@@ -38,20 +38,12 @@
 #include "gnc-glib-utils.h"
 #include "gnc-lot.h"
 #include "gnc-pricedb.h"
-#include "qofinstance-p.h"
 
 static QofLogModule log_module = GNC_MOD_ACCOUNT;
 
 /* The Canonical Account Separator.  Pre-Initialized. */
 static gchar account_separator[8] = ".";
 static gunichar account_uc_separator = ':';
-/* Predefined KVP paths */
-static const char *KEY_ASSOC_INCOME_ACCOUNT = "ofx/associated-income-account";
-#define AB_KEY "hbci"
-#define AB_ACCOUNT_ID "account-id"
-#define AB_ACCOUNT_UID "account-uid"
-#define AB_BANK_CODE "bank-code"
-#define AB_TRANS_RETRIEVAL "trans-retrieval"
 
 enum
 {
@@ -61,48 +53,37 @@ enum
 enum
 {
     PROP_0,
-    PROP_NAME,				/* Table */
-    PROP_FULL_NAME,			/* Constructed */
-    PROP_CODE,				/* Table */
-    PROP_DESCRIPTION,			/* Table */
-    PROP_COLOR,				/* KVP */
-    PROP_NOTES,				/* KVP */
-    PROP_TYPE,				/* Table */
-
-//    PROP_PARENT,			/* Table, Not a property */
-    PROP_COMMODITY,			/* Table */
-    PROP_COMMODITY_SCU,			/* Table */
-    PROP_NON_STD_SCU,			/* Table */
-    PROP_END_BALANCE,			/* Constructed */
-    PROP_END_CLEARED_BALANCE,		/* Constructed */
-    PROP_END_RECONCILED_BALANCE,	/* Constructed */
-
-    PROP_TAX_RELATED,			/* KVP */
-    PROP_TAX_CODE,			/* KVP */
-    PROP_TAX_SOURCE,			/* KVP */
-    PROP_TAX_COPY_NUMBER,		/* KVP */
-
-    PROP_HIDDEN,			/* Table slot exists, but in KVP in memory & xml */
-    PROP_PLACEHOLDER,			/* Table slot exists, but in KVP in memory & xml */
-    PROP_FILTER,			/* KVP */
-    PROP_SORT_ORDER,			/* KVP */
-
-    PROP_LOT_NEXT_ID,			/* KVP */
-    PROP_ONLINE_ACCOUNT,		/* KVP */
-    PROP_OFX_INCOME_ACCOUNT,		/* KVP */
-    PROP_AB_ACCOUNT_ID,			/* KVP */
-    PROP_AB_ACCOUNT_UID,		/* KVP */
-    PROP_AB_BANK_CODE,			/* KVP */
-    PROP_AB_TRANS_RETRIEVAL,		/* KVP */
-
-    PROP_RUNTIME_0,
-    PROP_POLICY,			/* Cached Value */
-    PROP_MARK,				/* Runtime Value */
-    PROP_SORT_DIRTY,			/* Runtime Value */
-    PROP_BALANCE_DIRTY,			/* Runtime Value */
-    PROP_START_BALANCE,			/* Runtime Value */
-    PROP_START_CLEARED_BALANCE,		/* Runtime Value */
-    PROP_START_RECONCILED_BALANCE,	/* Runtime Value */
+    PROP_NAME,
+    PROP_FULL_NAME,
+    PROP_CODE,
+    PROP_DESCRIPTION,
+    PROP_COLOR,
+    PROP_NOTES,
+    PROP_TYPE,
+
+    PROP_COMMODITY,
+    PROP_COMMODITY_SCU,
+    PROP_NON_STD_SCU,
+    PROP_SORT_DIRTY,
+    PROP_BALANCE_DIRTY,
+    PROP_START_BALANCE,
+    PROP_START_CLEARED_BALANCE,
+    PROP_START_RECONCILED_BALANCE,
+    PROP_END_BALANCE,
+    PROP_END_CLEARED_BALANCE,
+    PROP_END_RECONCILED_BALANCE,
+
+    PROP_POLICY,
+    PROP_MARK,
+    PROP_TAX_RELATED,
+    PROP_TAX_CODE,
+    PROP_TAX_SOURCE,
+    PROP_TAX_COPY_NUMBER,
+
+    PROP_HIDDEN,
+    PROP_PLACEHOLDER,
+    PROP_FILTER,
+    PROP_SORT_ORDER,
 };
 
 #define GET_PRIVATE(o)  \
@@ -301,8 +282,6 @@ gnc_account_get_property (GObject         *object,
 {
     Account *account;
     AccountPrivate *priv;
-    const gchar *key;
-    GValue *temp;
 
     g_return_if_fail(GNC_IS_ACCOUNT(object));
 
@@ -398,36 +377,6 @@ gnc_account_get_property (GObject         *object,
     case PROP_SORT_ORDER:
         g_value_set_string(value, xaccAccountGetSortOrder(account));
         break;
-    case PROP_LOT_NEXT_ID:
-	key = "lot-mgmt/next-id";
-        /* Pre-set the value in case the frame is empty */
-	g_value_set_int64 (value, 0);
-	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_ONLINE_ACCOUNT:
-	key = "online_id";
-	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_OFX_INCOME_ACCOUNT:
-	key = KEY_ASSOC_INCOME_ACCOUNT;
-	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_AB_ACCOUNT_ID:
-	key = AB_KEY "/" AB_ACCOUNT_ID;
-	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_AB_ACCOUNT_UID:
-	key = AB_KEY "/" AB_ACCOUNT_UID;
-	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_AB_BANK_CODE:
-	key = AB_KEY "/" AB_BANK_CODE;
-	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_AB_TRANS_RETRIEVAL:
-	key = AB_KEY "/" AB_TRANS_RETRIEVAL;
-	qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -442,13 +391,10 @@ gnc_account_set_property (GObject         *object,
 {
     Account *account;
     gnc_numeric *number;
-    const gchar *key = NULL;
 
     g_return_if_fail(GNC_IS_ACCOUNT(object));
 
     account = GNC_ACCOUNT(object);
-    if (prop_id < PROP_RUNTIME_0)
-	g_assert (qof_instance_get_editlevel(account));
 
     switch (prop_id)
     {
@@ -530,34 +476,6 @@ gnc_account_set_property (GObject         *object,
     case PROP_SORT_ORDER:
         xaccAccountSetSortOrder(account, g_value_get_string(value));
         break;
-    case PROP_LOT_NEXT_ID:
-	key = "lot-mgmt/next-id";
-	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_ONLINE_ACCOUNT:
-	key = "online_id";
-	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_OFX_INCOME_ACCOUNT:
-	key = KEY_ASSOC_INCOME_ACCOUNT;
-	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_AB_ACCOUNT_ID:
-	key = AB_KEY "/" AB_ACCOUNT_ID;
-	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_AB_ACCOUNT_UID:
-	key = AB_KEY "/" AB_ACCOUNT_UID;
-	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_AB_BANK_CODE:
-	key = AB_KEY "/" AB_BANK_CODE;
-	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
-	break;
-    case PROP_AB_TRANS_RETRIEVAL:
-	key = AB_KEY "/" AB_TRANS_RETRIEVAL;
-	qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -915,77 +833,6 @@ gnc_account_class_init (AccountClass *klass)
                           "the sort order to be recalled.",
                           NULL,
                           G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_LOT_NEXT_ID,
-     g_param_spec_int64 ("lot-next-id",
-                         "Lot Next ID",
-                         "Tracks the next id to use in gnc_lot_make_default.",
-                         (gint64)1,
-                         G_MAXINT64,
-                         (gint64)1,
-                         G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_ONLINE_ACCOUNT,
-     g_param_spec_string ("online-id",
-                          "Online Account ID",
-                          "The online account which corresponds to this "
-			  "account for OFX import",
-                          NULL,
-                          G_PARAM_READWRITE));
-
-     g_object_class_install_property(
-       gobject_class,
-       PROP_OFX_INCOME_ACCOUNT,
-        g_param_spec_boxed("ofx-income-account",
-			   "Associated income account",
-			   "Used by the OFX importer.",
-			   GNC_TYPE_GUID,
-			   G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_AB_ACCOUNT_ID,
-     g_param_spec_string ("ab-account-id",
-                          "AQBanking Account ID",
-                          "The AqBanking account which corresponds to this "
-			  "account for AQBanking import",
-                          NULL,
-                          G_PARAM_READWRITE));
-    g_object_class_install_property
-    (gobject_class,
-     PROP_AB_BANK_CODE,
-     g_param_spec_string ("ab-bank-code",
-                          "AQBanking Bank Code",
-                          "The online account which corresponds to this "
-			  "account for AQBanking import",
-                          NULL,
-                          G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_AB_ACCOUNT_UID,
-     g_param_spec_int64 ("ab-account-uid",
-                         "AQBanking Account UID",
-                         "Tracks the next id to use in gnc_lot_make_default.",
-                         (gint64)1,
-                         G_MAXINT64,
-                         (gint64)1,
-                         G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_AB_TRANS_RETRIEVAL,
-     g_param_spec_boxed("ab-trans-retrieval",
-                        "AQBanking Last Transaction Retrieval",
-                        "The time of the last transaction retrieval for this "
-			"account.",
-                        GNC_TYPE_TIMESPEC,
-                        G_PARAM_READWRITE));
-
 }
 
 static void
@@ -4432,80 +4279,6 @@ xaccAccountSetLastNum (Account *acc, const char *num)
     xaccAccountCommitEdit (acc);
 }
 
-static Account *
-GetOrMakeOrphanAccount (Account *root, gnc_commodity * currency)
-{
-    char * accname;
-    Account * acc;
-
-    g_return_val_if_fail (root, NULL);
-
-    /* build the account name */
-    if (!currency)
-    {
-        PERR ("No currency specified!");
-        return NULL;
-    }
-
-    accname = g_strconcat (_("Orphaned Gains"), "-",
-                           gnc_commodity_get_mnemonic (currency), NULL);
-
-    /* See if we've got one of these going already ... */
-    acc = gnc_account_lookup_by_name(root, accname);
-
-    if (acc == NULL)
-    {
-        /* Guess not. We'll have to build one. */
-        acc = xaccMallocAccount (gnc_account_get_book(root));
-        xaccAccountBeginEdit (acc);
-        xaccAccountSetName (acc, accname);
-        xaccAccountSetCommodity (acc, currency);
-        xaccAccountSetType (acc, ACCT_TYPE_INCOME);
-        xaccAccountSetDescription (acc, _("Realized Gain/Loss"));
-        xaccAccountSetNotes (acc,
-                             _("Realized Gains or Losses from "
-                               "Commodity or Trading Accounts "
-                               "that haven't been recorded elsewhere."));
-
-        /* Hang the account off the root. */
-        gnc_account_append_child (root, acc);
-        xaccAccountCommitEdit (acc);
-    }
-
-    g_free (accname);
-
-    return acc;
-}
-
-Account *
-xaccAccountGainsAccount (Account *acc, gnc_commodity *curr)
-{
-    KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (acc));
-    const gchar *curr_name = gnc_commodity_get_unique_name (curr);
-    GncGUID *guid;
-    Account *gains_account;
-
-    frame = kvp_frame_get_frame_slash (frame, "/lot-mgmt/gains-act/");
-    guid = kvp_frame_get_guid (frame, curr_name);
-    if (guid == NULL) /* No gains account for this currency */
-    {
-	gains_account = GetOrMakeOrphanAccount (gnc_account_get_root (acc),
-						curr);
-	guid = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (gains_account));
-	xaccAccountBeginEdit (acc);
-	{
-	    kvp_frame_set_guid (frame, curr_name, guid);
-	    qof_instance_set_dirty (QOF_INSTANCE (acc));
-	}
-	xaccAccountCommitEdit (acc);
-    }
-    else
-	gains_account = xaccAccountLookup (guid,
-					   qof_instance_get_book(acc));
-
-    return gains_account;
-}
-
 /********************************************************************\
 \********************************************************************/
 
@@ -4946,508 +4719,6 @@ xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc,
 }
 
 /* ================================================================ */
-/* The following functions are used by
- * src/import-export/import-backend.c to manipulate the contra-account
- * matching data. See src/import-export/import-backend.c for explanations.
- */
-/* FIXME: These data are stored per-account in KVP and the functions
- * work directly on KVP data structures. This prevents moving KVP to a
- * backend-only abstraction.
- */
-
-
-typedef struct _GncImportMatchMap
-{
-    kvp_frame *	frame;
-    Account *	acc;
-    QofBook *	book;
-} GncImportMatchMap;
-
-#define IMAP_FRAME		"import-map"
-#define IMAP_FRAME_BAYES	"import-map-bayes"
-GncImportMatchMap * gnc_account_create_imap (Account *acc);
-Account* gnc_imap_find_account(GncImportMatchMap *imap, const char* category,
-                               const char *key);
-void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
-                           const char *key, Account *acc);
-Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList* tokens);
-void gnc_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
-                                 Account *acc);
-
-/* Obtain an ImportMatchMap object from an Account or a Book */
-GncImportMatchMap *
-gnc_account_create_imap (Account *acc)
-{
-    GncImportMatchMap *imap;
-    kvp_frame *frame;
-
-    if (!acc) return NULL;
-    frame = qof_instance_get_slots (QOF_INSTANCE (acc));
-    g_return_val_if_fail (frame != NULL, NULL);
-    g_return_val_if_fail (frame != NULL, NULL);
-
-    imap = g_new0(GncImportMatchMap, 1);
-    imap->frame = frame;
-
-    /* Cache the book for easy lookups; store the account/book for
-     * marking dirtiness
-     */
-    imap->acc = acc;
-    imap->book = gnc_account_get_book (acc);
-
-    return imap;
-}
-
-/* Look up an Account in the map */
-Account*
-gnc_imap_find_account (GncImportMatchMap *imap,
-		       const char *category,
-		       const char *key)
-{
-    kvp_value *value;
-    GncGUID * guid;
-
-    if (!imap || !key) return NULL;
-    if (!category)
-    {
-        category = key;
-        key = NULL;
-    }
-
-    value = kvp_frame_get_slot_path (imap->frame, IMAP_FRAME,
-				     category, key, NULL);
-    if (!value) return NULL;
-
-    guid = kvp_value_get_guid (value);
-    return xaccAccountLookup (guid, imap->book);
-}
-
-/* Store an Account in the map */
-void
-gnc_imap_add_account (GncImportMatchMap *imap,
-		      const char *category,
-		      const char *key,
-		      Account *acc)
-{
-    kvp_value *value;
-
-    if (!imap || !key || !acc || (strlen (key) == 0)) return;
-    if (!category)
-    {
-        category = key;
-        key = NULL;
-    }
-    g_return_if_fail (acc != NULL);
-
-    value = kvp_value_new_guid (xaccAccountGetGUID (acc));
-    g_return_if_fail (value != NULL);
-    xaccAccountBeginEdit (imap->acc);
-    kvp_frame_set_slot_path (imap->frame, value, IMAP_FRAME, category, key, NULL);
-    qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
-    xaccAccountCommitEdit (imap->acc);
-    kvp_value_delete (value);
-
-    /* XXX Mark the account (or book) as dirty! */
-}
-
-
-
-
-/*--------------------------------------------------------------------------
- Below here is the bayes transaction to account matching system
---------------------------------------------------------------------------*/
-
-
-struct account_token_count
-{
-    char* account_name;
-    gint64 token_count; /**< occurances of a given token for this account_name */
-};
-
-/** total_count and the token_count for a given account let us calculate the
- * probability of a given account with any single token
- */
-struct token_accounts_info
-{
-    GList *accounts; /**< array of struct account_token_count */
-    gint64 total_count;
-};
-
-/** gpointer is a pointer to a struct token_accounts_info
- * \note Can always assume that keys are unique, reduces code in this function
- */
-static void
-buildTokenInfo(const char *key, kvp_value *value, gpointer data)
-{
-    struct token_accounts_info *tokenInfo = (struct token_accounts_info*)data;
-    struct account_token_count* this_account;
-
-    //  PINFO("buildTokenInfo: account '%s', token_count: '%ld'\n", (char*)key,
-    //			(long)kvp_value_get_gint64(value));
-
-    /* add the count to the total_count */
-    tokenInfo->total_count += kvp_value_get_gint64(value);
-
-    /* allocate a new structure for this account and it's token count */
-    this_account = (struct account_token_count*)
-                   g_new0(struct account_token_count, 1);
-
-    /* fill in the account name and number of tokens found for this account name */
-    this_account->account_name = (char*)key;
-    this_account->token_count = kvp_value_get_gint64(value);
-
-    /* append onto the glist a pointer to the new account_token_count structure */
-    tokenInfo->accounts = g_list_prepend(tokenInfo->accounts, this_account);
-}
-
-/** intermediate values used to calculate the bayes probability of a given account
-  where p(AB) = (a*b)/[a*b + (1-a)(1-b)], product is (a*b),
-  product_difference is (1-a) * (1-b)
- */
-struct account_probability
-{
-    double product; /* product of probabilities */
-    double product_difference; /* product of (1-probabilities) */
-};
-
-/** convert a hash table of account names and (struct account_probability*)
-  into a hash table of 100000x the percentage match value, ie. 10% would be
-  0.10 * 100000 = 10000
- */
-#define PROBABILITY_FACTOR 100000
-static void
-buildProbabilities(gpointer key, gpointer value, gpointer data)
-{
-    GHashTable *final_probabilities = (GHashTable*)data;
-    struct account_probability *account_p = (struct account_probability*)value;
-
-    /* P(AB) = A*B / [A*B + (1-A)*(1-B)]
-     * NOTE: so we only keep track of a running product(A*B*C...)
-     * and product difference ((1-A)(1-B)...)
-     */
-    gint32 probability =
-        (account_p->product /
-         (account_p->product + account_p->product_difference))
-        * PROBABILITY_FACTOR;
-
-    PINFO("P('%s') = '%d'\n", (char*)key, probability);
-
-    g_hash_table_insert(final_probabilities, key, GINT_TO_POINTER(probability));
-}
-
-/** Frees an array of the same time that buildProperties built */
-static void
-freeProbabilities(gpointer key, gpointer value, gpointer data)
-{
-    /* free up the struct account_probability that was allocated
-     * in gnc_account_find_account_bayes()
-     */
-    g_free(value);
-}
-
-/** holds an account name and its corresponding integer probability
-  the integer probability is some factor of 10
- */
-struct account_info
-{
-    char* account_name;
-    gint32 probability;
-};
-
-/** Find the highest probability and the corresponding account name
-    store in data, a (struct account_info*)
-    NOTE: this is a g_hash_table_foreach() function for a hash table of entries
-    key is a  pointer to the account name, value is a gint32, 100000x
-    the probability for this account
-*/
-static void
-highestProbability(gpointer key, gpointer value, gpointer data)
-{
-    struct account_info *account_i = (struct account_info*)data;
-
-    /* if the current probability is greater than the stored, store the current */
-    if (GPOINTER_TO_INT(value) > account_i->probability)
-    {
-        /* Save the new highest probability and the assoaciated account name */
-        account_i->probability = GPOINTER_TO_INT(value);
-        account_i->account_name = key;
-    }
-}
-
-
-#define threshold (.90 * PROBABILITY_FACTOR) /* 90% */
-
-/** Look up an Account in the map */
-Account*
-gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens)
-{
-    struct token_accounts_info tokenInfo; /**< holds the accounts and total
-					   * token count for a single token */
-    GList *current_token;		  /**< pointer to the current
-					   * token from the input GList
-					   * tokens */
-    GList *current_account_token;	  /**< pointer to the struct
-					   * account_token_count */
-    struct account_token_count *account_c; /**< an account name and the number
-					    * of times a token has appeared
-					    * for the account */
-    struct account_probability *account_p; /**< intermediate storage of values
-					    * to compute the bayes probability
-					    * of an account */
-    GHashTable *running_probabilities = g_hash_table_new(g_str_hash,
-							 g_str_equal);
-    GHashTable *final_probabilities = g_hash_table_new(g_str_hash,
-						       g_str_equal);
-    struct account_info account_i;
-    kvp_value* value;
-    kvp_frame* token_frame;
-
-    ENTER(" ");
-
-    /* check to see if the imap is NULL */
-    if (!imap)
-    {
-        PINFO("imap is null, returning null");
-        LEAVE(" ");
-        return NULL;
-    }
-
-    /* find the probability for each account that contains any of the tokens
-     * in the input tokens list
-     */
-    for (current_token = tokens; current_token;
-	 current_token = current_token->next)
-    {
-        /* zero out the token_accounts_info structure */
-        memset(&tokenInfo, 0, sizeof(struct token_accounts_info));
-
-        PINFO("token: '%s'", (char*)current_token->data);
-
-        /* find the slot for the given token off of the source account
-         * for these tokens, search off of the IMAP_FRAME_BAYES path so
-         * we aren't looking from the parent of the entire kvp tree
-         */
-        value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
-                                        (char*)current_token->data, NULL);
-
-        /* if value is null we should skip over this token */
-        if (!value)
-            continue;
-
-        /* convert the slot(value) into a the frame that contains the
-         * list of accounts
-         */
-        token_frame = kvp_value_get_frame(value);
-
-        /* token_frame should NEVER be null */
-        if (!token_frame)
-        {
-            PERR("token '%s' has no accounts", (char*)current_token->data);
-            continue; /* skip over this token */
-        }
-
-        /* process the accounts for this token, adding the account if it
-         * doesn't already exist or adding to the existing accounts token
-         * count if it does
-         */
-        kvp_frame_for_each_slot(token_frame, buildTokenInfo, &tokenInfo);
-
-        /* for each account we have just found, see if the account
-         * already exists in the list of account probabilities, if not
-         * add it
-         */
-        for (current_account_token = tokenInfo.accounts; current_account_token;
-                current_account_token = current_account_token->next)
-        {
-            /* get the account name and corresponding token count */
-            account_c = (struct account_token_count*)current_account_token->data;
-
-            PINFO("account_c->account_name('%s'), "
-                  "account_c->token_count('%ld')/total_count('%ld')",
-                  account_c->account_name, (long)account_c->token_count,
-                  (long)tokenInfo.total_count);
-
-            account_p = g_hash_table_lookup(running_probabilities,
-                                            account_c->account_name);
-
-            /* if the account exists in the list then continue
-             * the running probablities
-             */
-            if (account_p)
-            {
-                account_p->product = (((double)account_c->token_count /
-				      (double)tokenInfo.total_count)
-				      * account_p->product);
-                account_p->product_difference =
-                    ((double)1 - ((double)account_c->token_count /
-                                  (double)tokenInfo.total_count))
-                    * account_p->product_difference;
-                PINFO("product == %f, product_difference == %f",
-                      account_p->product, account_p->product_difference);
-            }
-            else
-            {
-                /* add a new entry */
-                PINFO("adding a new entry for this account");
-                account_p = (struct account_probability*)
-                            g_new0(struct account_probability, 1);
-
-                /* set the product and product difference values */
-                account_p->product = ((double)account_c->token_count /
-                                      (double)tokenInfo.total_count);
-                account_p->product_difference =
-                    (double)1 - ((double)account_c->token_count /
-                                 (double)tokenInfo.total_count);
-
-                PINFO("product == %f, product_difference == %f",
-                      account_p->product, account_p->product_difference);
-
-                /* add the account name and (struct account_probability*)
-                 * to the hash table */
-                g_hash_table_insert(running_probabilities,
-                                    account_c->account_name, account_p);
-            }
-        } /* for all accounts in tokenInfo */
-
-        /* free the data in tokenInfo */
-        for (current_account_token = tokenInfo.accounts; current_account_token;
-                current_account_token = current_account_token->next)
-        {
-            /* free up each struct account_token_count we allocated */
-            g_free((struct account_token_count*)current_account_token->data);
-        }
-
-        g_list_free(tokenInfo.accounts); /* free the accounts GList */
-    }
-
-    /* build a hash table of account names and their final probabilities
-     * from each entry in the running_probabilties hash table
-     */
-    g_hash_table_foreach(running_probabilities, buildProbabilities,
-                         final_probabilities);
-
-    /* find the highest probabilty and the corresponding account */
-    memset(&account_i, 0, sizeof(struct account_info));
-    g_hash_table_foreach(final_probabilities, highestProbability, &account_i);
-
-    /* free each element of the running_probabilities hash */
-    g_hash_table_foreach(running_probabilities, freeProbabilities, NULL);
-
-    /* free the hash tables */
-    g_hash_table_destroy(running_probabilities);
-    g_hash_table_destroy(final_probabilities);
-
-    PINFO("highest P('%s') = '%d'",
-          account_i.account_name ? account_i.account_name : "(null)",
-          account_i.probability);
-
-    /* has this probability met our threshold? */
-    if (account_i.probability >= threshold)
-    {
-        PINFO("found match");
-        LEAVE(" ");
-        return gnc_account_lookup_by_full_name(gnc_book_get_root_account(imap->book),
-                                               account_i.account_name);
-    }
-
-    PINFO("no match");
-    LEAVE(" ");
-
-    return NULL; /* we didn't meet our threshold, return NULL for an account */
-}
-
-
-/** Updates the imap for a given account using a list of tokens */
-void
-gnc_imap_add_account_bayes(GncImportMatchMap *imap,
-			   GList *tokens,
-			   Account *acc)
-{
-    GList *current_token;
-    kvp_value *value;
-    gint64 token_count;
-    char* account_fullname;
-    kvp_value *new_value; /* the value that will be added back into
-			   * the kvp tree */
-
-    ENTER(" ");
-
-    /* if imap is null return */
-    if (!imap)
-    {
-        LEAVE(" ");
-        return;
-    }
-
-    g_return_if_fail (acc != NULL);
-    account_fullname = gnc_account_get_full_name(acc);
-    xaccAccountBeginEdit (imap->acc);
-
-    PINFO("account name: '%s'\n", account_fullname);
-
-    /* process each token in the list */
-    for (current_token = g_list_first(tokens); current_token;
-            current_token = current_token->next)
-    {
-        /* Jump to next iteration if the pointer is not valid or if the
-        	 string is empty. In HBCI import we almost always get an empty
-        	 string, which doesn't work in the kvp loopkup later. So we
-        	 skip this case here. */
-        if (!current_token->data || (*((char*)current_token->data) == '\0'))
-            continue;
-
-        /* start off with no tokens for this account */
-        token_count = 0;
-
-        PINFO("adding token '%s'\n", (char*)current_token->data);
-
-        /* is this token/account_name already in the kvp tree? */
-        value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
-                                        (char*)current_token->data,
-					account_fullname,
-                                        NULL);
-
-        /* if the token/account is already in the tree, read the current
-         * value from the tree and use this for the basis of the value we
-         * are putting back
-         */
-        if (value)
-        {
-            PINFO("found existing value of '%ld'\n",
-                  (long)kvp_value_get_gint64(value));
-
-            /* convert this value back into an integer */
-            token_count += kvp_value_get_gint64(value);
-        }
-
-        /* increment the token count */
-        token_count++;
-
-        /* create a new value */
-        new_value = kvp_value_new_gint64(token_count);
-
-        /* insert the value into the kvp tree at
-         * /imap->frame/IMAP_FRAME/token_string/account_name_string
-         */
-        kvp_frame_set_slot_path(imap->frame, new_value,
-				IMAP_FRAME_BAYES,
-                                (char*)current_token->data,
-				account_fullname,
-				NULL);
-        /* kvp_frame_set_slot_path() copied the value so we
-         * need to delete this one ;-) */
-        kvp_value_delete(new_value);
-    }
-
-    /* free up the account fullname string */
-    qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
-    xaccAccountCommitEdit (imap->acc);
-    g_free(account_fullname);
-
-    LEAVE(" ");
-}
-
-/* ================================================================ */
 /* QofObject function implementation and registration */
 
 static void
diff --git a/src/engine/Account.h b/src/engine/Account.h
index 0e57ac7..3098043 100644
--- a/src/engine/Account.h
+++ b/src/engine/Account.h
@@ -417,17 +417,6 @@ void xaccAccountSortSplits (Account *acc, gboolean force);
  */
 gchar * gnc_account_get_full_name (const Account *account);
 
-/** Retrieve the gains account used by this account for the indicated
- * currency, creating and recording a new one if necessary.
- *
- * FIXME: There is at present no interface to designate an existing
- * account, and the new account name is hard coded to
- * "Orphaned Gains -- CUR"
- *
- * FIXME: There is no provision for creating separate accounts for
- * anything other than currency, e.g. holding period of a security.
- */
-Account * xaccAccountGainsAccount (Account *acc, gnc_commodity *curr);
 /** Set a string that identifies the Finance::Quote backend that
  *  should be used to retrieve online prices.  See price-quotes.scm
  *  for more information
@@ -871,6 +860,8 @@ gboolean xaccAccountGetReconcileChildrenStatus(const Account *account);
  */
 gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor);
 
+#define xaccAccountGetSlots(X) qof_instance_get_slots(QOF_INSTANCE(X))
+
 /** @} */
 
 /** @name Lookup Accounts and Subaccounts by name or code
diff --git a/src/engine/SX-book.c b/src/engine/SX-book.c
index 7440442..57ee618 100644
--- a/src/engine/SX-book.c
+++ b/src/engine/SX-book.c
@@ -150,9 +150,6 @@ sxtg_is_dirty(const QofCollection *col)
     return dirty;
 }
 
-/* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
-extern void qof_instance_mark_clean (QofInstance *);
-
 static void
 sxtg_mark_clean(QofCollection *col)
 {
@@ -375,9 +372,9 @@ gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct)
         for (; splits != NULL; splits = splits->next)
         {
             Split *s = (Split*)splits->data;
-            GncGUID *guid = NULL;
-            qof_instance_get (QOF_INSTANCE (s), "sx-account", &guid, NULL);
-            if (guid_equal(acct_guid, guid))
+            KvpFrame *frame = kvp_frame_get_frame(xaccSplitGetSlots(s), GNC_SX_ID);
+            GncGUID *sx_split_acct_guid = kvp_frame_get_guid(frame, GNC_SX_ACCOUNT);
+            if (guid_equal(acct_guid, sx_split_acct_guid))
             {
                 rtn = g_list_append(rtn, sx);
             }
diff --git a/src/engine/SchedXaction.c b/src/engine/SchedXaction.c
index c794bac..ceb30b0 100644
--- a/src/engine/SchedXaction.c
+++ b/src/engine/SchedXaction.c
@@ -36,7 +36,6 @@
 #include "Transaction.h"
 #include "gnc-engine.h"
 #include "engine-helpers.h"
-#include "qofinstance-p.h"
 
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "gnc.engine.sx"
@@ -44,19 +43,19 @@
 enum
 {
     PROP_0,
-    PROP_NAME,				/* Table */
-    PROP_ENABLED,			/* Table */
-    PROP_START_DATE,			/* Table */
-    PROP_END_DATE,			/* Table */
-    PROP_LAST_OCCURANCE_DATE,		/* Table */
-    PROP_NUM_OCCURANCE,			/* Table */
-    PROP_REM_OCCURANCE,			/* Table */
-    PROP_AUTO_CREATE,			/* Table */
-    PROP_AUTO_CREATE_NOTIFY,		/* Table */
-    PROP_ADVANCE_CREATION_DAYS,		/* Table */
-    PROP_ADVANCE_REMINDER_DAYS,		/* Table */
-    PROP_INSTANCE_COUNT,		/* Table */
-    PROP_TEMPLATE_ACCOUNT		/* Table */
+    PROP_NAME,
+    PROP_ENABLED,
+    PROP_NUM_OCCURANCE,
+    PROP_REM_OCCURANCE,
+    PROP_AUTO_CREATE,
+    PROP_AUTO_CREATE_NOTIFY,
+    PROP_ADVANCE_CREATION_DAYS,
+    PROP_ADVANCE_REMINDER_DAYS,
+    PROP_START_DATE,
+    PROP_END_DATE,
+    PROP_LAST_OCCURANCE_DATE,
+    PROP_INSTANCE_COUNT,
+    PROP_TEMPLATE_ACCOUNT
 };
 
 /* GObject initialization */
@@ -174,8 +173,6 @@ gnc_schedxaction_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_SCHEDXACTION(object));
 
     sx = GNC_SCHEDXACTION(object);
-    g_assert (qof_instance_get_editlevel(sx));
-
     switch (prop_id)
     {
     case PROP_NAME:
@@ -1045,8 +1042,8 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
                  Transaction *parent_trans, QofBook *book)
 {
     Split *split;
-    const gchar *credit_formula;
-    const gchar *debit_formula;
+    KvpFrame *split_frame;
+    KvpValue *tmp_value;
     const GncGUID *acc_guid;
 
     split = xaccMallocSplit(book);
@@ -1062,14 +1059,40 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
     xaccAccountInsertSplit(parent_acct,
                            split);
 
-    credit_formula = gnc_ttsplitinfo_get_credit_formula(s_info);
-    debit_formula = gnc_ttsplitinfo_get_debit_formula(s_info);
+    split_frame = xaccSplitGetSlots(split);
+
+    tmp_value
+    = kvp_value_new_string(gnc_ttsplitinfo_get_credit_formula(s_info));
+
+    kvp_frame_set_slot_path(split_frame,
+                            tmp_value,
+                            GNC_SX_ID,
+                            GNC_SX_CREDIT_FORMULA,
+                            NULL);
+    kvp_value_delete(tmp_value);
+
+    tmp_value
+    = kvp_value_new_string(gnc_ttsplitinfo_get_debit_formula(s_info));
+
+    kvp_frame_set_slot_path(split_frame,
+                            tmp_value,
+                            GNC_SX_ID,
+                            GNC_SX_DEBIT_FORMULA,
+                            NULL);
+
+    kvp_value_delete(tmp_value);
+
     acc_guid = qof_entity_get_guid(QOF_INSTANCE(gnc_ttsplitinfo_get_account(s_info)));
-    qof_instance_set (QOF_INSTANCE (split),
-		      "sx-credit-formula", credit_formula,
-		      "sx-debit-formula", debit_formula,
-		      "sx-account", acc_guid,
-		      NULL);
+
+    tmp_value = kvp_value_new_guid(acc_guid);
+
+    kvp_frame_set_slot_path(split_frame,
+                            tmp_value,
+                            GNC_SX_ID,
+                            GNC_SX_ACCOUNT,
+                            NULL);
+
+    kvp_value_delete(tmp_value);
 
     return split;
 }
diff --git a/src/engine/SchedXaction.h b/src/engine/SchedXaction.h
index c02183e..08031e1 100644
--- a/src/engine/SchedXaction.h
+++ b/src/engine/SchedXaction.h
@@ -304,7 +304,15 @@ void gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData );
 GList *gnc_sx_get_defer_instances( SchedXaction *sx );
 
 /* #defines for KvpFrame strings and QOF */
+#define GNC_SX_ID                    "sched-xaction"
+#define GNC_SX_ACCOUNT               "account"
+#define GNC_SX_CREDIT_FORMULA        "credit-formula"
+#define GNC_SX_DEBIT_FORMULA         "debit-formula"
+#define GNC_SX_CREDIT_NUMERIC        "credit-numeric"
+#define GNC_SX_DEBIT_NUMERIC         "debit-numeric"
 #define GNC_SX_SHARES                "shares"
+#define GNC_SX_AMOUNT                "amnt"
+#define GNC_SX_FROM_SCHED_XACTION    "from-sched-xaction"
 #define GNC_SX_FREQ_SPEC             "scheduled-frequency"
 #define GNC_SX_NAME                  "sched-xname"
 #define GNC_SX_START_DATE            "sched-start-date"
diff --git a/src/engine/Scrub.c b/src/engine/Scrub.c
index 70d1e6c..055e95a 100644
--- a/src/engine/Scrub.c
+++ b/src/engine/Scrub.c
@@ -1133,9 +1133,6 @@ xaccAccountScrubCommodity (Account *account)
 
 /* ================================================================ */
 
-/* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
-extern void qof_instance_set_dirty (QofInstance*);
-
 static void
 xaccAccountDeleteOldData (Account *account)
 {
diff --git a/src/engine/Scrub2.c b/src/engine/Scrub2.c
index d938cae..8c041f5 100644
--- a/src/engine/Scrub2.c
+++ b/src/engine/Scrub2.c
@@ -157,7 +157,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
 
     if (!lot) return;
 
-    ENTER ("lot=%s", gnc_lot_get_title(lot));
+    ENTER ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
 
     for (snode = gnc_lot_get_split_list(lot); snode; snode = snode->next)
     {
@@ -216,7 +216,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
         }
     }
 
-    LEAVE ("lot=%s", gnc_lot_get_title(lot));
+    LEAVE ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
 }
 
 /* ================================================================= */
diff --git a/src/engine/Split.c b/src/engine/Split.c
index 53fa590..b49389f 100644
--- a/src/engine/Split.c
+++ b/src/engine/Split.c
@@ -51,7 +51,6 @@
 #include "gnc-engine.h"
 #include "gnc-lot.h"
 #include "gnc-event.h"
-#include "qofinstance-p.h"
 
 const char *void_former_amt_str = "void-former-amount";
 const char *void_former_val_str = "void-former-value";
@@ -61,40 +60,17 @@ const char *void_former_val_str = "void-former-value";
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = GNC_MOD_ENGINE;
 
-/* KVP key values used for SX info stored Split's slots. */
-#define GNC_SX_ID                    "sched-xaction"
-#define GNC_SX_ACCOUNT               "account"
-#define GNC_SX_CREDIT_FORMULA        "credit-formula"
-#define GNC_SX_DEBIT_FORMULA         "debit-formula"
-#define GNC_SX_CREDIT_NUMERIC        "credit-numeric"
-#define GNC_SX_DEBIT_NUMERIC         "debit-numeric"
-#define GNC_SX_SHARES                "shares"
-
 enum
 {
     PROP_0,
-    PROP_TX,                    /* Table */
-    PROP_ACCOUNT,               /* Table */
-    PROP_MEMO,                  /* Table */
-    PROP_ACTION,                /* Table */
-//    PROP_RECONCILE_STATE,     /* Table */
-    PROP_RECONCILE_DATE,        /* Table */
-    PROP_VALUE,                 /* Table, in 2 fields */
-    PROP_SX_ACCOUNT,            /* KVP */
-    PROP_SX_CREDIT_FORMULA,     /* KVP */
-    PROP_SX_CREDIT_NUMERIC,     /* KVP */
-    PROP_SX_DEBIT_FORMULA,      /* KVP */
-    PROP_SX_DEBIT_NUMERIC,      /* KVP */
-    PROP_SX_SHARES,             /* KVP */
-    PROP_LOT,                   /* KVP */
-    PROP_ONLINE_ACCOUNT,        /* KVP */
-    PROP_LOT_SPLIT,             /* KVP */
-    PROP_PEER_GUID,             /* KVP */
-    PROP_GAINS_SPLIT,           /* KVP */
-    PROP_GAINS_SOURCE,          /* KVP */
-    PROP_RUNTIME_0,
-    PROP_AMOUNT,                /* Runtime */
-
+    PROP_ACTION,
+    PROP_MEMO,
+    PROP_VALUE,
+    PROP_AMOUNT,
+    PROP_RECONCILE_DATE,
+    PROP_TX,
+    PROP_ACCOUNT,
+    PROP_LOT
 };
 
 /* GObject Initialization */
@@ -150,7 +126,6 @@ gnc_split_get_property(GObject         *object,
                        GParamSpec      *pspec)
 {
     Split *split;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_SPLIT(object));
 
@@ -181,50 +156,6 @@ gnc_split_get_property(GObject         *object,
     case PROP_LOT:
         g_value_take_object(value, split->lot);
         break;
-    case PROP_SX_CREDIT_FORMULA:
-        key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA;
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_CREDIT_NUMERIC:
-        key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC;
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_DEBIT_FORMULA:
-        key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA;
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_DEBIT_NUMERIC:
-        key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC;
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_ACCOUNT:
-        key = GNC_SX_ID "/" GNC_SX_ACCOUNT;
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_SHARES:
-        key = GNC_SX_ID "/" GNC_SX_SHARES;
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_ONLINE_ACCOUNT:
-        key = "online_id";
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_LOT_SPLIT:
-        key = "lot-split";
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_PEER_GUID:
-        key = "peer_guid";
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_GAINS_SPLIT:
-        key = "gains-split";
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_GAINS_SOURCE:
-        key = "gains-source";
-        qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
-        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -239,14 +170,10 @@ gnc_split_set_property(GObject         *object,
 {
     Split *split;
     gnc_numeric* number;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_SPLIT(object));
 
     split = GNC_SPLIT(object);
-    if (prop_id < PROP_RUNTIME_0 && split->parent != NULL)
-        g_assert (qof_instance_get_editlevel(split->parent));
-
     switch (prop_id)
     {
     case PROP_ACTION:
@@ -275,50 +202,6 @@ gnc_split_set_property(GObject         *object,
     case PROP_LOT:
         xaccSplitSetLot(split, g_value_get_object(value));
         break;
-    case PROP_SX_CREDIT_FORMULA:
-        key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA;
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_CREDIT_NUMERIC:
-        key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC;
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_DEBIT_FORMULA:
-        key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA;
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_DEBIT_NUMERIC:
-        key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC;
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_ACCOUNT:
-        key = GNC_SX_ID "/" GNC_SX_ACCOUNT;
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_SX_SHARES:
-        key = GNC_SX_ID "/" GNC_SX_SHARES;
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_ONLINE_ACCOUNT:
-        key = "online_id";
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_LOT_SPLIT:
-        key = "lot-split";
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_PEER_GUID:
-        key = "peer_guid";
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_GAINS_SPLIT:
-        key = "gains-split";
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
-    case PROP_GAINS_SOURCE:
-        key = "gains-source";
-        qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
-        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -416,122 +299,6 @@ gnc_split_class_init(SplitClass* klass)
                           "The lot that this split belongs to.",
                           GNC_TYPE_LOT,
                           G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_SX_DEBIT_FORMULA,
-     g_param_spec_string("sx-debit-formula",
-                         "Schedule Transaction Debit Formula",
-                         "The formula used to calculate the actual debit "
-                         "amount when a real split is generated from this "
-                         "SX split.",
-                         NULL,
-                         G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_SX_DEBIT_NUMERIC,
-     g_param_spec_boxed("sx-debit-numeric",
-                        "Scheduled Transaction Debit Numeric",
-                        "Numeric value to plug into the Debit Formula when a "
-                        "real split is generated from this SX split.",
-                        GNC_TYPE_NUMERIC,
-                        G_PARAM_READWRITE));
-
-     g_object_class_install_property
-    (gobject_class,
-     PROP_SX_CREDIT_FORMULA,
-     g_param_spec_string("sx-credit-formula",
-                         "Schedule Transaction Credit Formula",
-                         "The formula used to calculate the actual credit "
-                         "amount when a real split is generated from this "
-                         "SX split.",
-                         NULL,
-                         G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_SX_CREDIT_NUMERIC,
-     g_param_spec_boxed("sx-credit-numeric",
-                        "Scheduled Transaction Credit Numeric",
-                        "Numeric value to plug into the Credit Formula when a "
-                        "real split is generated from this SX split.",
-                        GNC_TYPE_NUMERIC,
-                        G_PARAM_READWRITE));
-/* FIXME: PROP_SX_SHARES should be stored as a gnc_numeric, but the function
- * which uses it, gnc_template_register_save_shares_cell, stores a
- * phony string. This is maintained until backwards compatibility can
- * be established.
- */
-    g_object_class_install_property
-    (gobject_class,
-     PROP_SX_SHARES,
-     g_param_spec_string("sx-shares",
-                        "Scheduled Transaction Shares",
-                        "Numeric value of shares to insert in a new split when "
-                        "it's generated from this SX split.",
-                        NULL,
-                        G_PARAM_READWRITE));
-
-     g_object_class_install_property
-    (gobject_class,
-     PROP_SX_ACCOUNT,
-     g_param_spec_boxed("sx-account",
-                        "Scheduled Transaction Account",
-                        "The target account for a scheduled transaction split.",
-                        GNC_TYPE_GUID,
-                        G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_ONLINE_ACCOUNT,
-     g_param_spec_string ("online-id",
-                          "Online Account ID",
-                          "The online account which corresponds to this "
-                          "account for OFX/HCBI import",
-                          NULL,
-                          G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_LOT_SPLIT,
-     g_param_spec_int64 ("lot-split",
-                         "Lot Split",
-                         "Indicates that the split was divided into two "
-                         "splits in order to balance a lot capital gains "
-                         "transaction. Contains a timestamp of the action.",
-                         G_MININT64, G_MAXINT64, 0,
-                         G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_PEER_GUID,
-     g_param_spec_boxed ("peer-guid",
-                          "Peer GUID",
-                          "The other split in the division.",
-                          GNC_TYPE_GUID,
-                          G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_GAINS_SPLIT,
-     g_param_spec_boxed ("gains-split",
-                          "Gains Split",
-                          "The capital gains split associated with this "
-                          "split when this split represents the proceeds "
-                          "from the sale of a commodity inside a Lot.",
-                          GNC_TYPE_GUID,
-                          G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_GAINS_SOURCE,
-     g_param_spec_boxed ("gains-source",
-                          "Gains Source",
-                          "The source split for which this split this is "
-                          "the gains split. ",
-                          GNC_TYPE_GUID,
-                          G_PARAM_READWRITE));
 }
 
 /********************************************************************\
@@ -639,7 +406,7 @@ xaccDupeSplit (const Split *s)
 }
 
 Split *
-xaccSplitCloneNoKvp (const Split *s)
+xaccSplitClone (const Split *s)
 {
     Split *split = g_object_new (GNC_TYPE_SPLIT, NULL);
 
@@ -657,8 +424,10 @@ xaccSplitCloneNoKvp (const Split *s)
     split->gains = GAINS_STATUS_UNKNOWN;
     split->gains_split = NULL;
 
-    qof_instance_init_data(&split->inst, GNC_ID_SPLIT,
-                           qof_instance_get_book(s));
+    qof_instance_init_data(&split->inst, GNC_ID_SPLIT, qof_instance_get_book(s));
+    kvp_frame_delete(split->inst.kvp_data);
+    split->inst.kvp_data = kvp_frame_copy(s->inst.kvp_data);
+
     xaccAccountInsertSplit(s->acc, split);
     if (s->lot)
     {
@@ -668,11 +437,6 @@ xaccSplitCloneNoKvp (const Split *s)
     return split;
 }
 
-void
-xaccSplitCopyKvp (const Split *from, Split *to)
-{
-    to->inst.kvp_data = kvp_frame_copy(from->inst.kvp_data);
-}
 
 /*################## Added for Reg2 #################*/
 
@@ -1190,6 +954,26 @@ get_commodity_denom(const Split * s)
     }
 }
 
+/********************************************************************
+ * xaccSplitGetSlots
+ ********************************************************************/
+
+KvpFrame *
+xaccSplitGetSlots (const Split * s)
+{
+    return qof_instance_get_slots(QOF_INSTANCE(s));
+}
+/* Used for testing only: _get_random_split in test-engine-stuff.c */
+void
+xaccSplitSetSlots_nc(Split *s, KvpFrame *frm)
+{
+    if (!s || !frm) return;
+    xaccTransBeginEdit(s->parent);
+    qof_instance_set_slots(QOF_INSTANCE(s), frm);
+    xaccTransCommitEdit(s->parent);
+
+}
+
 /********************************************************************\
 \********************************************************************/
 
@@ -2331,7 +2115,7 @@ gboolean xaccSplitRegister (void)
         { SPLIT_ACCT_FULLNAME, SPLIT_ACCT_FULLNAME, no_op, NULL },
         { SPLIT_CORR_ACCT_NAME, SPLIT_CORR_ACCT_NAME, no_op, NULL },
         { SPLIT_CORR_ACCT_CODE, SPLIT_CORR_ACCT_CODE, no_op, NULL },
-        { SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL },
+        { SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)xaccSplitGetSlots, NULL },
         { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)xaccSplitGetBook, NULL },
         {
             QOF_PARAM_GUID, QOF_TYPE_GUID,
diff --git a/src/engine/Split.h b/src/engine/Split.h
index cc512d1..d240bd8 100644
--- a/src/engine/Split.h
+++ b/src/engine/Split.h
@@ -144,6 +144,20 @@ GNCLot *      xaccSplitGetLot (const Split *split);
 /** Assigns the split to a specific Lot */
 void xaccSplitSetLot(Split* split, GNCLot* lot);
 
+
+/** Returns the KvpFrame slots of this split for direct editing.
+ *
+ * Split slots are used to store arbitrary strings, numbers, and
+ * structures which aren't members of the transaction struct.  See
+ * kvp_doc.txt for reserved slot names.
+ */
+KvpFrame *xaccSplitGetSlots(const Split *split);
+
+/** Set the KvpFrame slots of this split to the given frm by directly
+ * using the frm pointer (i.e. non-copying). */
+void xaccSplitSetSlots_nc(Split *s, KvpFrame *frm);
+
+
 /** The memo is an arbitrary string associated with a split.  It is
  * intended to hold a short (zero to forty character) string that is
  * displayed by the GUI along with this split.  Users typically type
diff --git a/src/engine/SplitP.h b/src/engine/SplitP.h
index 2832dc8..93f0ed5 100644
--- a/src/engine/SplitP.h
+++ b/src/engine/SplitP.h
@@ -146,8 +146,7 @@ struct _SplitClass
  */
 void  xaccFreeSplit (Split *split);    /* frees memory */
 
-Split *xaccSplitCloneNoKvp (const Split *s);
-void xaccSplitCopyKvp (const Split *from, Split *to);
+Split * xaccSplitClone (const Split *s);
 
 Split *xaccDupeSplit (const Split *s);
 void mark_split (Split *s);
diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c
index 5146826..2df9f84 100644
--- a/src/engine/Transaction.c
+++ b/src/engine/Transaction.c
@@ -184,7 +184,6 @@ const char *assoc_uri_str = "assoc_uri";
 #define TRANS_TXN_TYPE_KVP       "trans-txn-type"
 #define TRANS_READ_ONLY_REASON   "trans-read-only"
 #define TRANS_REVERSED_BY        "reversed-by"
-#define GNC_SX_FROM              "from-sched-xaction"
 
 #define ISO_DATELENGTH 32 /* length of an iso 8601 date string. */
 
@@ -194,14 +193,11 @@ static QofLogModule log_module = GNC_MOD_ENGINE;
 enum
 {
     PROP_0,
-    PROP_CURRENCY,	/* Table */
-    PROP_NUM,		/* Table */
-    PROP_POST_DATE,	/* Table */
-    PROP_ENTER_DATE,	/* Table */
-    PROP_DESCRIPTION,	/* Table */
-    PROP_INVOICE,	/* KVP */
-    PROP_SX_TXN,	/* KVP */
-    PROP_ONLINE_ACCOUNT,/* KVP */
+    PROP_NUM,
+    PROP_DESCRIPTION,
+    PROP_CURRENCY,
+    PROP_POST_DATE,
+    PROP_ENTER_DATE
 };
 
 void
@@ -307,9 +303,6 @@ gnc_transaction_get_property(GObject* object,
                              GParamSpec* pspec)
 {
     Transaction* tx;
-    KvpFrame *frame;
-    gchar *key;
-    GValue *temp;
 
     g_return_if_fail(GNC_IS_TRANSACTION(object));
 
@@ -331,18 +324,6 @@ gnc_transaction_get_property(GObject* object,
     case PROP_ENTER_DATE:
         g_value_set_boxed(value, &tx->date_entered);
         break;
-    case PROP_INVOICE:
-	key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
-	qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
-	break;
-    case PROP_SX_TXN:
-	key = GNC_SX_FROM;
-	qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
-	break;
-    case PROP_ONLINE_ACCOUNT:
-	key = "online_id";
-	qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -356,14 +337,10 @@ gnc_transaction_set_property(GObject* object,
                              GParamSpec* pspec)
 {
     Transaction* tx;
-    KvpFrame *frame;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_TRANSACTION(object));
 
     tx = GNC_TRANSACTION(object);
-    g_assert (qof_instance_get_editlevel(tx));
-
     switch (prop_id)
     {
     case PROP_NUM:
@@ -381,18 +358,6 @@ gnc_transaction_set_property(GObject* object,
     case PROP_ENTER_DATE:
         xaccTransSetDateEnteredTS(tx, g_value_get_boxed(value));
         break;
-    case PROP_INVOICE:
-	key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
-	qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
-	break;
-    case PROP_SX_TXN:
-	key = GNC_SX_FROM;
-	qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
-	break;
-    case PROP_ONLINE_ACCOUNT:
-	key = "online_id";
-	qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -461,36 +426,6 @@ gnc_transaction_class_init(TransactionClass* klass)
                         "The date the transaction was entered.",
                         GNC_TYPE_TIMESPEC,
                         G_PARAM_READWRITE));
-
-     g_object_class_install_property(
-       gobject_class,
-        PROP_INVOICE,
-        g_param_spec_boxed("invoice",
-			   "Invoice attached to lot",
-			   "Used by GncInvoice",
-			   GNC_TYPE_GUID,
-			   G_PARAM_READWRITE));
-
-     g_object_class_install_property(
-       gobject_class,
-        PROP_SX_TXN,
-        g_param_spec_boxed("from-sched-xaction",
-			   "From Scheduled Transaction",
-			   "Used by Scheduled Transastions to record the "
-			   "originating template transaction for created "
-			   "transactions",
-			   GNC_TYPE_GUID,
-			   G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_ONLINE_ACCOUNT,
-     g_param_spec_string ("online-id",
-                          "Online Account ID",
-                          "The online account which corresponds to this "
-			  "account for OFX/HCBI import",
-                          NULL,
-                          G_PARAM_READWRITE));
 }
 
 /********************************************************************\
@@ -597,8 +532,9 @@ xaccTransSortSplits (Transaction *trans)
  * This routine is prone to programmer snafu if not used correctly.
  * It is used only by the edit-rollback code.
  */
-static Transaction *
-dupe_trans (const Transaction *from)
+/* Actually, it *is* public, and used by Period.c */
+Transaction *
+xaccDupeTransaction (const Transaction *from)
 {
     Transaction *to;
     GList *node;
@@ -635,11 +571,10 @@ dupe_trans (const Transaction *from)
 
 /********************************************************************\
  * Use this routine to externally duplicate a transaction.  It creates
- * a full fledged transaction with unique guid, splits, etc. and
- * writes it to the database.
+ * a full fledged transaction with unique guid, splits, etc.
 \********************************************************************/
 Transaction *
-xaccTransCloneNoKvp (const Transaction *from)
+xaccTransClone (const Transaction *from)
 {
     Transaction *to;
     Split *split;
@@ -658,13 +593,14 @@ xaccTransCloneNoKvp (const Transaction *from)
 
     to->orig            = NULL;
 
-    qof_instance_init_data (&to->inst, GNC_ID_TRANS,
-			    qof_instance_get_book(from));
+    qof_instance_init_data (&to->inst, GNC_ID_TRANS, qof_instance_get_book(from));
+    kvp_frame_delete (to->inst.kvp_data);
+    to->inst.kvp_data    = kvp_frame_copy (from->inst.kvp_data);
 
     xaccTransBeginEdit(to);
     for (node = from->splits; node; node = node->next)
     {
-        split = xaccSplitCloneNoKvp(node->data);
+        split = xaccSplitClone(node->data);
         split->parent = to;
         to->splits = g_list_append (to->splits, split);
     }
@@ -675,28 +611,11 @@ xaccTransCloneNoKvp (const Transaction *from)
     return to;
 }
 
-Transaction *
-xaccTransClone (const Transaction *from)
-{
-    Transaction *to = xaccTransCloneNoKvp (from);
-    int i = 0;
-    int length = g_list_length (from->splits);
-
-    xaccTransBeginEdit (to);
-    to->inst.kvp_data = kvp_frame_copy (from->inst.kvp_data);
-    g_assert (g_list_length (to->splits) == length);
-    for (i = 0; i < length; ++i)
-	xaccSplitCopyKvp (g_list_nth_data (from->splits, i),
-			    g_list_nth_data (to->splits, i));
-    xaccTransCommitEdit (to);
-    return to;
-}
-
 /*################## Added for Reg2 #################*/
 
 /********************************************************************\
  * Copy a transaction to the 'clipboard' transaction using
- *  dupe_trans. The 'clipboard' transaction must never
+ *  xaccDupeTransaction. The 'clipboard' transaction must never
  *  be dereferenced.
 \********************************************************************/
 Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
@@ -706,7 +625,7 @@ Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
     if (!from_trans)
         return NULL;
 
-    to_trans = dupe_trans(from_trans);
+    to_trans = xaccDupeTransaction(from_trans);
     return to_trans;
 }
 
@@ -723,7 +642,7 @@ xaccTransCopyOnto(const Transaction *from_trans, Transaction *to_trans)
 /********************************************************************\
  * This function explicitly must robustly handle some unusual input.
  *
- *  'from_trans' may be a duped trans (see dupe_trans), so its
+ *  'from_trans' may be a duped trans (see xaccDupeTransaction), so its
  *   splits may not really belong to the accounts that they say they do.
  *
  *  'from_acc' need not be a valid account. It may be an already freed
@@ -1390,7 +1309,7 @@ xaccTransBeginEdit (Transaction *trans)
 
     /* Make a clone of the transaction; we will use this
      * in case we need to roll-back the edit. */
-    trans->orig = dupe_trans (trans);
+    trans->orig = xaccDupeTransaction (trans);
 }
 
 /********************************************************************\
@@ -2696,7 +2615,6 @@ xaccTransFindSplitByAccount(const Transaction *trans, const Account *acc)
     return NULL;
 }
 
-
 /********************************************************************\
 \********************************************************************/
 /* QofObject function implementation */
@@ -2858,7 +2776,6 @@ _utest_trans_fill_functions (void)
     func->trans_on_error = trans_on_error;
     func->trans_cleanup_commit = trans_cleanup_commit;
     func->xaccTransScrubGainsDate = xaccTransScrubGainsDate;
-    func->dupe_trans = dupe_trans;
     return func;
 }
 
diff --git a/src/engine/Transaction.h b/src/engine/Transaction.h
index e26ac08..8091dba 100644
--- a/src/engine/Transaction.h
+++ b/src/engine/Transaction.h
@@ -156,12 +156,6 @@ void          xaccTransDestroy (Transaction *trans);
  */
 Transaction * xaccTransClone (const Transaction *t);
 
-/**
- The xaccTransCloneNoKvp() method will create a complete copy of an
- existing transaction except that the KVP slots will be empty.
- */
-Transaction * xaccTransCloneNoKvp (const Transaction *t);
-
 /** Equality.
  *
  * @param ta First transaction to compare
@@ -229,7 +223,7 @@ Transaction * xaccTransLookup (const GncGUID *guid, QofBook *book);
 /*################## Added for Reg2 #################*/
 
 /** Copy a transaction to the 'clipboard' transaction using
- *  dupe_transaction. The 'clipboard' transaction must never
+ *  xaccDupeTransaction. The 'clipboard' transaction must never
  *  be dereferenced.
  */
 Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans);
@@ -755,6 +749,8 @@ void xaccTransDump (const Transaction *trans, const char *tag);
 #define xaccTransGetGUID(X)      qof_entity_get_guid(QOF_INSTANCE(X))
 /** \deprecated */
 #define xaccTransReturnGUID(X) (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
+/** \deprecated */
+#define xaccTransGetSlots(X)     qof_instance_get_slots (QOF_INSTANCE(X))
 
 #endif /* XACC_TRANSACTION_H */
 /** @} */
diff --git a/src/engine/TransactionP.h b/src/engine/TransactionP.h
index 87b89bf..d7935e8 100644
--- a/src/engine/TransactionP.h
+++ b/src/engine/TransactionP.h
@@ -186,7 +186,6 @@ typedef struct
     void (*trans_on_error)(Transaction*, QofBackendError);
     void (*trans_cleanup_commit)(Transaction*);
     void (*xaccTransScrubGainsDate)(Transaction*);
-    Transaction *(*dupe_trans)(const Transaction*);
 
 } TransTestFunctions;
 
diff --git a/src/engine/cap-gains.c b/src/engine/cap-gains.c
index b7ea3f1..e73bdfc 100644
--- a/src/engine/cap-gains.c
+++ b/src/engine/cap-gains.c
@@ -216,6 +216,150 @@ xaccAccountFindLatestOpenLot (Account *acc, gnc_numeric sign,
 }
 
 /* ============================================================== */
+/* Similar to GetOrMakeAccount, but different in important ways */
+
+static Account *
+GetOrMakeLotOrphanAccount (Account *root, gnc_commodity * currency)
+{
+    char * accname;
+    Account * acc;
+
+    g_return_val_if_fail (root, NULL);
+
+    /* build the account name */
+    if (!currency)
+    {
+        PERR ("No currency specified!");
+        return NULL;
+    }
+
+    accname = g_strconcat (_("Orphaned Gains"), "-",
+                           gnc_commodity_get_mnemonic (currency), NULL);
+
+    /* See if we've got one of these going already ... */
+    acc = gnc_account_lookup_by_name(root, accname);
+
+    if (acc == NULL)
+    {
+        /* Guess not. We'll have to build one. */
+        acc = xaccMallocAccount (gnc_account_get_book(root));
+        xaccAccountBeginEdit (acc);
+        xaccAccountSetName (acc, accname);
+        xaccAccountSetCommodity (acc, currency);
+        xaccAccountSetType (acc, ACCT_TYPE_INCOME);
+        xaccAccountSetDescription (acc, _("Realized Gain/Loss"));
+        xaccAccountSetNotes (acc,
+                             _("Realized Gains or Losses from "
+                               "Commodity or Trading Accounts "
+                               "that haven't been recorded elsewhere."));
+
+        /* Hang the account off the root. */
+        gnc_account_append_child (root, acc);
+        xaccAccountCommitEdit (acc);
+    }
+
+    g_free (accname);
+
+    return acc;
+}
+
+/* ============================================================== */
+
+void
+xaccAccountSetDefaultGainAccount (Account *acc, const Account *gain_acct)
+{
+    KvpFrame *cwd;
+    KvpValue *vvv;
+    const char * cur_name;
+    gnc_commodity *acc_comm;
+
+    if (!acc || !gain_acct) return;
+
+    cwd = xaccAccountGetSlots (acc);
+    cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
+
+    /* Accounts are indexed by thier unique currency name */
+    acc_comm = xaccAccountGetCommodity(acc);
+    cur_name = gnc_commodity_get_unique_name (acc_comm);
+
+    xaccAccountBeginEdit (acc);
+    vvv = kvp_value_new_guid (xaccAccountGetGUID (gain_acct));
+    kvp_frame_set_slot_nc (cwd, cur_name, vvv);
+    qof_instance_set_slots(QOF_INSTANCE(acc), acc->inst.kvp_data);
+    xaccAccountCommitEdit (acc);
+}
+
+/* ============================================================== */
+
+Account *
+xaccAccountGetDefaultGainAccount (const Account *acc, const gnc_commodity * currency)
+{
+    Account *gain_acct = NULL;
+    KvpFrame *cwd;
+    KvpValue *vvv;
+    GncGUID * gain_acct_guid;
+    const char * cur_name;
+
+    if (!acc || !currency) return NULL;
+
+    cwd = xaccAccountGetSlots (acc);
+    cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
+
+    /* Accounts are indexed by thier unique currency name */
+    cur_name = gnc_commodity_get_unique_name (currency);
+    vvv = kvp_frame_get_slot (cwd, cur_name);
+    gain_acct_guid = kvp_value_get_guid (vvv);
+
+    gain_acct = xaccAccountLookup (gain_acct_guid, qof_instance_get_book(acc));
+    return gain_acct;
+}
+
+/* ============================================================== */
+/* Functionally identical to the following:
+ *   if (!xaccAccountGetDefaultGainAccount()) {
+ *               xaccAccountSetDefaultGainAccount (); }
+ * except that it saves a few cycles.
+ */
+
+static Account *
+GetOrMakeGainAcct (Account *acc, gnc_commodity * currency)
+{
+    Account *gain_acct = NULL;
+    KvpFrame *cwd;
+    KvpValue *vvv;
+    GncGUID * gain_acct_guid;
+    const char * cur_name;
+
+    cwd = xaccAccountGetSlots (acc);
+    cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
+
+    /* Accounts are indexed by thier unique currency name */
+    cur_name = gnc_commodity_get_unique_name (currency);
+    vvv = kvp_frame_get_slot (cwd, cur_name);
+    gain_acct_guid = kvp_value_get_guid (vvv);
+
+    gain_acct = xaccAccountLookup (gain_acct_guid, qof_instance_get_book(acc));
+
+    /* If there is no default place to put gains/losses
+     * for this account, then create such a place */
+    if (NULL == gain_acct)
+    {
+        Account *root;
+
+        xaccAccountBeginEdit (acc);
+        root = gnc_account_get_root(acc);
+        gain_acct = GetOrMakeLotOrphanAccount (root, currency);
+
+        vvv = kvp_value_new_guid (xaccAccountGetGUID (gain_acct));
+        kvp_frame_set_slot_nc (cwd, cur_name, vvv);
+        qof_instance_set_slots(QOF_INSTANCE(acc), acc->inst.kvp_data);
+        xaccAccountCommitEdit (acc);
+
+    }
+    return gain_acct;
+}
+
+/* ============================================================== */
 
 Split *
 xaccSplitAssignToLot (Split *split, GNCLot *lot)
@@ -397,18 +541,22 @@ xaccSplitAssignToLot (Split *split, GNCLot *lot)
         ts = xaccSplitRetDateReconciledTS (split);
         xaccSplitSetDateReconciledTS (new_split, &ts);
 
-        /* Set the lot-split and peer_guid properties on the two
-         * splits to indicate that they're linked. 
+        /* We do not copy the KVP tree, as it seems like a dangerous
+         * thing to do.  If the user wants to access stuff in the 'old'
+         * kvp tree from the 'new' split, they shoudl follow the
+         * 'split-lot' pointers.  Yes, this is complicated, but what
+         * else can one do ??
+         */
+        /* Add kvp markup to indicate that these two splits used
+         * to be one before being 'split'
          */
-        qof_instance_set (QOF_INSTANCE (split),
-                          "lot-split", now,
-                          "peer_guid", xaccSplitGetGUID (new_split),
-                          NULL);
+        gnc_kvp_bag_add (split->inst.kvp_data, "lot-split", now,
+                         "peer_guid", xaccSplitGetGUID (new_split),
+                         NULL);
 
-        qof_instance_set (QOF_INSTANCE (new_split),
-                          "lot-split", now,
-                          "peer_guid", xaccSplitGetGUID (split),
-                          NULL);
+        gnc_kvp_bag_add (new_split->inst.kvp_data, "lot-split", now,
+                         "peer_guid", xaccSplitGetGUID (split),
+                         NULL);
 
         xaccAccountInsertSplit (acc, new_split);
         xaccTransAppendSplit (trans, new_split);
@@ -485,14 +633,15 @@ xaccSplitAssign (Split *split)
 Split *
 xaccSplitGetCapGainsSplit (const Split *split)
 {
+    KvpValue *val;
     GncGUID *gains_guid;
     Split *gains_split;
 
     if (!split) return NULL;
 
-    qof_instance_get (QOF_INSTANCE (split),
-                      "gains-split", &gains_guid,
-                      NULL);
+    val = kvp_frame_get_slot (split->inst.kvp_data, "gains-split");
+    if (!val) return NULL;
+    gains_guid = kvp_value_get_guid (val);
     if (!gains_guid) return NULL;
 
     /* Both splits will be in the same collection, so search there. */
@@ -507,14 +656,15 @@ xaccSplitGetCapGainsSplit (const Split *split)
 Split *
 xaccSplitGetGainsSourceSplit (const Split *split)
 {
+    KvpValue *val;
     GncGUID *source_guid;
     Split *source_split;
 
     if (!split) return NULL;
 
-    qof_instance_get (QOF_INSTANCE (split),
-                      "gains-source", &source_guid,
-                      NULL);
+    val = kvp_frame_get_slot (split->inst.kvp_data, "gains-source");
+    if (!val) return NULL;
+    source_guid = kvp_value_get_guid (val);
     if (!source_guid) return NULL;
 
     /* Both splits will be in the same collection, so search there. */
@@ -547,7 +697,8 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
     currency = split->parent->common_currency;
 
     ENTER ("(split=%p gains=%p status=0x%x lot=%s)", split,
-           split->gains_split, split->gains, gnc_lot_get_title(lot));
+           split->gains_split, split->gains,
+           kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
 
     /* Make sure the status flags and pointers are initialized */
     xaccSplitDetermineGainStatus(split);
@@ -791,7 +942,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
                     (FALSE == gnc_commodity_equiv (currency,
                                                    xaccAccountGetCommodity(gain_acc))))
             {
-                gain_acc = xaccAccountGainsAccount (lot_acc, currency);
+                gain_acc = GetOrMakeGainAcct (lot_acc, currency);
             }
 
             xaccAccountBeginEdit (gain_acc);
@@ -814,18 +965,17 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
             xaccSplitSetMemo (lot_split, _("Realized Gain/Loss"));
             xaccSplitSetMemo (gain_split, _("Realized Gain/Loss"));
 
-            /* For the new transaction, set the split properties indicating
+            /* For the new transaction, install KVP markup indicating
              * that this is the gains transaction that corresponds
              * to the gains source.
              */
             xaccTransBeginEdit (base_txn);
-            qof_instance_set (QOF_INSTANCE (split),
-                              "gains-split", xaccSplitGetGUID (lot_split),
-                              NULL);
+            kvp_frame_set_guid (split->inst.kvp_data, "gains-split",
+                                xaccSplitGetGUID (lot_split));
+            qof_instance_set_dirty (QOF_INSTANCE (split));
             xaccTransCommitEdit (base_txn);
-            qof_instance_set (QOF_INSTANCE (lot_split),
-                              "gains-source", xaccSplitGetGUID (split),
-                              NULL);
+            kvp_frame_set_guid (lot_split->inst.kvp_data, "gains-source",
+                                xaccSplitGetGUID (split));
 
         }
         else
@@ -881,7 +1031,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
             xaccSplitSetAmount (gain_split, negvalue);
             xaccSplitSetValue (gain_split, negvalue);
 
-            /* Some short-cuts to help avoid the above property lookup. */
+            /* Some short-cuts to help avoid the above kvp lookup. */
             split->gains = GAINS_STATUS_CLEAN;
             split->gains_split = lot_split;
             lot_split->gains = GAINS_STATUS_GAINS;
diff --git a/src/engine/cap-gains.h b/src/engine/cap-gains.h
index 76792bd..62c8f83 100644
--- a/src/engine/cap-gains.h
+++ b/src/engine/cap-gains.h
@@ -124,6 +124,25 @@ GNCLot * xaccAccountFindLatestOpenLot (Account *acc,
                                        gnc_numeric sign,
                                        gnc_commodity *currency);
 
+/** The xaccAccountGetDefaultGainAccount() routine will return
+ *   the account to which realized gains/losses may be posted.
+ *   Because gains may be in different currencies, one must
+ *   specify the currency type in which the gains will be posted.
+ *   This routine does nothing more than return the value of
+ *   the "/lot-mgmt/gains-act/XXX" key, where XXX is the unique
+ *   currency name.  IOf there is no default account for this
+ *   currency, NULL will be returned.
+ */
+Account * xaccAccountGetDefaultGainAccount (const Account *acc, const gnc_commodity * currency);
+
+/** The xaccAccountSetDefaultGainAccount() routine can be used
+ *   to set the account to which realized gains/losses will be
+ *   posted by default. This routine does nothing more than set
+ *   value of the "/lot-mgmt/gains-act/XXX" key, where XXX is the
+ *   unique currency name of the currency of gains account.
+ */
+void xaccAccountSetDefaultGainAccount (Account *acc, const Account *gains_acct);
+
 /** The xaccSplitGetCapGainsSplit() routine returns the split
  *  that records the cap gains for this split.  It returns NULL
  *  if not found.  This routine does nothing more than search for
diff --git a/src/engine/engine.i b/src/engine/engine.i
index 8fe362f..49cfc23 100644
--- a/src/engine/engine.i
+++ b/src/engine/engine.i
@@ -140,18 +140,10 @@ functions. */
 
 QofSession * qof_session_new (void);
 QofBook * qof_session_get_book (QofSession *session);
-/* This horror is to permit the scheme options in
- * src/app-utils/options.scm to read and write the book's KVP (another
- * horror) directly. It should be refactored into book functions that
- * handle the KVP access.
- */
-%inline {
-  KvpFrame *qof_book_get_slots (QofBook *book);
-  extern KvpFrame *qof_instance_get_slots (QofInstance*);
-  KvpFrame *qof_book_get_slots (QofBook *book) {
-       return qof_instance_get_slots (QOF_INSTANCE (book));
-  }
-}
+
+// TODO: Maybe unroll
+void qof_book_kvp_changed (QofBook *book);
+
 // TODO: Unroll/remove
 const char *qof_session_get_url (QofSession *session);
 
@@ -181,6 +173,7 @@ SplitList * qof_query_run_subquery (QofQuery *q, const QofQuery *q);
 %include <qofbookslots.h>
 %include <qofbook.h>
 
+KvpFrame* qof_book_get_slots(QofBook* book);
 %ignore GNC_DENOM_AUTO;
 %ignore GNCNumericErrorCodes;
 %ignore GNC_ERROR_OK;
diff --git a/src/engine/gnc-budget.c b/src/engine/gnc-budget.c
index 7e255b7..ae1e2e3 100644
--- a/src/engine/gnc-budget.c
+++ b/src/engine/gnc-budget.c
@@ -22,31 +22,29 @@
  *                                                                  *
 \********************************************************************/
 
-#include <config.h>
+#include "config.h"
 #include <glib.h>
 #include <glib/gprintf.h>
 #include <glib/gi18n.h>
 #include <time.h>
-#include <qof.h>
-#include <qofbookslots.h>
-#include <gnc-gdate-utils.h>
-#include <qofinstance-p.h>
+#include "qof.h"
+#include "qofbookslots.h"
 
 #include "Account.h"
 
 #include "gnc-budget.h"
 #include "gnc-commodity.h"
+#include "gnc-gdate-utils.h"
 
 static QofLogModule log_module = GNC_MOD_ENGINE;
 
 enum
 {
     PROP_0,
-    PROP_NAME,			/* Table */
-    PROP_DESCRIPTION,		/* Table */
-    PROP_NUM_PERIODS,		/* Table */
-    PROP_RUNTIME_0,
-    PROP_RECURRENCE,		/* Cached pointer; Recurrence table holds budget guid */
+    PROP_NAME,
+    PROP_DESCRIPTION,
+    PROP_NUM_PERIODS,
+    PROP_RECURRENCE,
 };
 
 struct budget_s
@@ -158,9 +156,6 @@ gnc_budget_set_property( GObject* object,
     g_return_if_fail(GNC_IS_BUDGET(object));
 
     budget = GNC_BUDGET(object);
-    if (prop_id < PROP_RUNTIME_0)
-	g_assert (qof_instance_get_editlevel(budget));
-
     switch ( prop_id )
     {
     case PROP_NAME:
@@ -631,23 +626,31 @@ gnc_budget_get_default (QofBook *book)
 {
     QofCollection *col;
     GncBudget *bgt = NULL;
-    const GncGUID *default_budget_guid = NULL;
+    kvp_value *kvp_default_budget;
+    const GncGUID *default_budget_guid;
 
     g_return_val_if_fail(book, NULL);
 
     /* See if there is a budget selected in the KVP perferences */
 
-    qof_instance_get (QOF_INSTANCE (book),
-		      "default-budget", &default_budget_guid,
-		      NULL);
-    if (default_budget_guid != NULL)
+    kvp_default_budget = kvp_frame_get_slot_path(qof_book_get_slots (book),
+                         KVP_OPTION_PATH,
+                         OPTION_SECTION_BUDGETING,
+                         OPTION_NAME_DEFAULT_BUDGET,
+                         NULL);
+
+    if (kvp_default_budget != NULL )
     {
-	col = qof_book_get_collection(book, GNC_ID_BUDGET);
-	bgt = (GncBudget *) qof_collection_lookup_entity(col,
-							 default_budget_guid);
+        default_budget_guid = kvp_value_get_guid(kvp_default_budget);
+        if (default_budget_guid != NULL)
+        {
+            col = qof_book_get_collection(book, GNC_ID_BUDGET);
+            bgt = (GncBudget *) qof_collection_lookup_entity(col,
+                    default_budget_guid);
+        }
     }
 
-    /* Revert to 2.2.x behavior if the book has no default budget. */
+    /* Revert to 2.2.x behavior if there is no defined budget in KVP */
 
     if ( bgt == NULL )
     {
diff --git a/src/engine/gnc-commodity.c b/src/engine/gnc-commodity.c
index 851bba5..77c643b 100644
--- a/src/engine/gnc-commodity.c
+++ b/src/engine/gnc-commodity.c
@@ -23,7 +23,7 @@
  *                                                                  *
  *******************************************************************/
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -33,7 +33,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <regex.h>
-#include <qofinstance-p.h>
 
 #include "gnc-commodity.h"
 #include "gnc-prefs.h"
@@ -48,16 +47,16 @@ static QofLogModule log_module = GNC_MOD_COMMODITY;
 enum
 {
     PROP_0,
-    PROP_NAMESPACE,	/* Table */
-    PROP_FULL_NAME,	/* Table */
-    PROP_MNEMONIC,	/* Table */
-    PROP_PRINTNAME,	/* Constructed */
-    PROP_CUSIP,		/* Table */
-    PROP_FRACTION,	/* Table */
-    PROP_UNIQUE_NAME,	/* Constructed */
-    PROP_QUOTE_FLAG,	/* Table */
-    PROP_QUOTE_SOURCE,	/* Table */
-    PROP_QUOTE_TZ,	/* Table */
+    PROP_NAMESPACE,
+    PROP_FULL_NAME,
+    PROP_MNEMONIC,
+    PROP_PRINTNAME,
+    PROP_CUSIP,
+    PROP_FRACTION,
+    PROP_UNIQUE_NAME,
+    PROP_QUOTE_FLAG,
+    PROP_QUOTE_SOURCE,
+    PROP_QUOTE_TZ,
 };
 
 struct gnc_commodity_s
@@ -699,7 +698,6 @@ gnc_commodity_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_COMMODITY(object));
 
     commodity = GNC_COMMODITY(object);
-    g_assert (qof_instance_get_editlevel(commodity));
 
     switch (prop_id)
     {
diff --git a/src/engine/gnc-engine.h b/src/engine/gnc-engine.h
index 4522e1e..f4943fb 100644
--- a/src/engine/gnc-engine.h
+++ b/src/engine/gnc-engine.h
@@ -251,16 +251,5 @@ void gnc_engine_add_commit_error_callback( EngineCommitErrorCallback cb, gpointe
 
 void gnc_engine_signal_commit_error( QofBackendError errcode );
 
-/** STRING CONSTANTS **********************************************
- * Used to declare constant KVP keys used in more than one class
- */
-#define GNC_INVOICE_ID    "gncInvoice"
-#define GNC_INVOICE_GUID  "invoice-guid"
-#define GNC_OWNER_ID      "gncOwner"
-#define GNC_OWNER_TYPE    "owner-type"
-#define GNC_OWNER_GUID    "owner-guid"
-#define GNC_SX_ID         "sched-xaction"
-
-
 #endif
 /** @} */
diff --git a/src/engine/gnc-lot.c b/src/engine/gnc-lot.c
index d86f0be..08fdef6 100644
--- a/src/engine/gnc-lot.c
+++ b/src/engine/gnc-lot.c
@@ -39,11 +39,10 @@
  * Copyright (c) 2002,2003 Linas Vepstas <linas at linas.org>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
 #include <glib/gi18n.h>
-#include <qofinstance-p.h>
 
 #include "Account.h"
 #include "AccountP.h"
@@ -64,15 +63,8 @@ struct gnc_lot_s
 enum
 {
     PROP_0,
-//  PROP_ACCOUNT, 	/* Table */
-    PROP_IS_CLOSED,	/* Table */
-
-    PROP_INVOICE,	/* KVP */
-    PROP_OWNER_TYPE,	/* KVP */
-    PROP_OWNER_GUID,	/* KVP */
-
-    PROP_RUNTIME_0,
-    PROP_MARKER,	/* Runtime */
+    PROP_IS_CLOSED,
+    PROP_MARKER
 };
 
 typedef struct LotPrivate
@@ -101,11 +93,6 @@ typedef struct LotPrivate
 
 /* ============================================================= */
 
-static void gnc_lot_set_invoice (GNCLot* lot, GncGUID *guid);
-static GncGUID *gnc_lot_get_invoice (GNCLot* lot);
-
-/* ============================================================= */
-
 /* GObject Initialization */
 G_DEFINE_TYPE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE)
 
@@ -138,9 +125,6 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec*
 {
     GNCLot* lot;
     LotPrivate* priv;
-    KvpFrame *frame;
-    gchar *key;
-    GValue *temp;
 
     g_return_if_fail(GNC_IS_LOT(object));
 
@@ -154,41 +138,18 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec*
     case PROP_MARKER:
         g_value_set_int(value, priv->marker);
         break;
-    case PROP_INVOICE:
-	key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
-	qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
-	break;
-    case PROP_OWNER_TYPE:
-	key = GNC_OWNER_ID"/" GNC_OWNER_TYPE;
-	qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
-	break;
-    case PROP_OWNER_GUID:
-	key = GNC_OWNER_ID "/" GNC_OWNER_GUID;
-	qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
-	break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
     }
 }
 
 static void
-gnc_lot_set_property (GObject* object,
-		      guint prop_id,
-		      const GValue* value,
-		      GParamSpec* pspec)
+gnc_lot_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
 {
     GNCLot* lot;
     LotPrivate* priv;
-    KvpFrame *frame;
-    gchar *key = NULL;
 
     g_return_if_fail(GNC_IS_LOT(object));
 
     lot = GNC_LOT(object);
-    if (prop_id < PROP_RUNTIME_0)
-	g_assert (qof_instance_get_editlevel(lot));
-
     priv = GET_PRIVATE(lot);
     switch (prop_id)
     {
@@ -198,22 +159,7 @@ gnc_lot_set_property (GObject* object,
     case PROP_MARKER:
         priv->marker = g_value_get_int(value);
         break;
-    case PROP_INVOICE:
-	key = GNC_INVOICE_ID"/" GNC_INVOICE_GUID;
-	qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
-	break;
-    case PROP_OWNER_TYPE:
-	key = GNC_OWNER_ID "/" GNC_OWNER_TYPE;
-	qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
-	break;
-    case PROP_OWNER_GUID:
-	key = GNC_OWNER_ID "/" GNC_OWNER_GUID;
-	qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
-	break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-     }
+    }
 }
 
 static void
@@ -247,32 +193,8 @@ gnc_lot_class_init(GNCLotClass* klass)
                          0, G_MAXINT8, 0,
                          G_PARAM_READWRITE));
 
-     g_object_class_install_property(
-       gobject_class,
-        PROP_INVOICE,
-        g_param_spec_boxed("invoice",
-			   "Invoice attached to lot",
-			   "Used by GncInvoice",
-			   GNC_TYPE_GUID,
-			   G_PARAM_READWRITE));
-
-     g_object_class_install_property(
-       gobject_class,
-        PROP_OWNER_TYPE,
-        g_param_spec_int64("owner-type",
-			   "Owning Entity Type of  lot",
-			   "Used by GncOwner",
-			   0, G_MAXINT64, 0,
-			   G_PARAM_READWRITE));
-
-     g_object_class_install_property(
-       gobject_class,
-        PROP_OWNER_GUID,
-        g_param_spec_boxed("owner-guid",
-			   "Owner attached to lot",
-			   "Used by GncOwner",
-			   GNC_TYPE_GUID,
-			   G_PARAM_READWRITE));
+
+
 }
 
 GNCLot *
@@ -411,6 +333,12 @@ gnc_lot_set_closed_unknown(GNCLot* lot)
     }
 }
 
+KvpFrame *
+gnc_lot_get_slots (const GNCLot *lot)
+{
+    return qof_instance_get_slots(QOF_INSTANCE(lot));
+}
+
 SplitList *
 gnc_lot_get_split_list (const GNCLot *lot)
 {
@@ -435,16 +363,14 @@ const char *
 gnc_lot_get_title (const GNCLot *lot)
 {
     if (!lot) return NULL;
-    return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
-				 "/title");
+    return kvp_frame_get_string (gnc_lot_get_slots(lot), "/title");
 }
 
 const char *
 gnc_lot_get_notes (const GNCLot *lot)
 {
     if (!lot) return NULL;
-    return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
-				 "/notes");
+    return kvp_frame_get_string (gnc_lot_get_slots(lot), "/notes");
 }
 
 void
@@ -453,8 +379,7 @@ gnc_lot_set_title (GNCLot *lot, const char *str)
     if (!lot) return;
     qof_begin_edit(QOF_INSTANCE(lot));
     qof_instance_set_dirty(QOF_INSTANCE(lot));
-    kvp_frame_set_str (qof_instance_get_slots(QOF_INSTANCE (lot)),
-		       "/title", str);
+    kvp_frame_set_str (gnc_lot_get_slots(lot), "/title", str);
     gnc_lot_commit_edit(lot);
 }
 
@@ -464,8 +389,7 @@ gnc_lot_set_notes (GNCLot *lot, const char *str)
     if (!lot) return;
     gnc_lot_begin_edit(lot);
     qof_instance_set_dirty(QOF_INSTANCE(lot));
-    kvp_frame_set_str (qof_instance_get_slots (QOF_INSTANCE (lot)),
-		       "/notes", str);
+    kvp_frame_set_str (gnc_lot_get_slots(lot), "/notes", str);
     gnc_lot_commit_edit(lot);
 }
 
@@ -751,20 +675,20 @@ gboolean gnc_lot_register (void)
 GNCLot * gnc_lot_make_default (Account *acc)
 {
     GNCLot * lot;
-    gint64 id = 0;
-    gchar *buff;
+    gint64 id;
+    char buff[200];
 
     lot = gnc_lot_new (qof_instance_get_book(acc));
 
     /* Provide a reasonable title for the new lot */
     xaccAccountBeginEdit (acc);
-    qof_instance_get (QOF_INSTANCE (acc), "lot-next-id", &id, NULL);
-    buff = g_strdup_printf ("%s %" G_GINT64_FORMAT, _("Lot"), id);
-    gnc_lot_set_title (lot, buff);
+    id = kvp_frame_get_gint64 (xaccAccountGetSlots (acc), "/lot-mgmt/next-id");
+    snprintf (buff, 200, ("%s %" G_GINT64_FORMAT), _("Lot"), id);
+    kvp_frame_set_str (gnc_lot_get_slots (lot), "/title", buff);
     id ++;
-    qof_instance_set (QOF_INSTANCE (acc), "lot-next-id", id, NULL);
+    kvp_frame_set_gint64 (xaccAccountGetSlots (acc), "/lot-mgmt/next-id", id);
+    qof_instance_set_dirty (QOF_INSTANCE(acc));
     xaccAccountCommitEdit (acc);
-    g_free (buff);
     return lot;
 }
 
diff --git a/src/engine/gnc-lot.h b/src/engine/gnc-lot.h
index 64e1dfa..1e477e1 100644
--- a/src/engine/gnc-lot.h
+++ b/src/engine/gnc-lot.h
@@ -165,6 +165,11 @@ const char * gnc_lot_get_notes (const GNCLot *);
 void gnc_lot_set_title (GNCLot *, const char *);
 void gnc_lot_set_notes (GNCLot *, const char *);
 
+/** Every lot has a place to hang kvp data.  This routine returns that
+ *     place.
+ * */
+KvpFrame * gnc_lot_get_slots (const GNCLot *);
+
 /** XXX: Document? */
 GNCLot * gnc_lot_make_default (Account * acc);
 
diff --git a/src/engine/gnc-pricedb.c b/src/engine/gnc-pricedb.c
index 23fbae0..54b7385 100644
--- a/src/engine/gnc-pricedb.c
+++ b/src/engine/gnc-pricedb.c
@@ -41,12 +41,12 @@ static GNCPrice *lookup_nearest_in_time(GNCPriceDB *db, const gnc_commodity *c,
 enum
 {
     PROP_0,
-    PROP_COMMODITY,	/* Table */
-    PROP_CURRENCY,	/* Table */
-    PROP_DATE,		/* Table */
-    PROP_SOURCE,	/* Table */
-    PROP_TYPE,		/* Table */
-    PROP_VALUE,		/* Table, 2 fields (numeric) */
+    PROP_COMMODITY,
+    PROP_CURRENCY,
+    PROP_DATE,
+    PROP_SOURCE,
+    PROP_TYPE,
+    PROP_VALUE
 };
 
 /* GObject Initialization */
@@ -123,8 +123,6 @@ gnc_price_set_property(GObject* object, guint prop_id, const GValue* value, GPar
     g_return_if_fail(GNC_IS_PRICE(object));
 
     price = GNC_PRICE(object);
-    g_assert (qof_instance_get_editlevel(price));
-
     switch (prop_id)
     {
     case PROP_SOURCE:
diff --git a/src/engine/gncAddress.c b/src/engine/gncAddress.c
index 103e35a..97bbfd7 100644
--- a/src/engine/gncAddress.c
+++ b/src/engine/gncAddress.c
@@ -25,10 +25,9 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
-#include <qofinstance-p.h>
 
 #include "gncAddress.h"
 #include "gncAddressP.h"
diff --git a/src/engine/gncBillTerm.c b/src/engine/gncBillTerm.c
index 9f2c7b9..835f052 100644
--- a/src/engine/gncBillTerm.c
+++ b/src/engine/gncBillTerm.c
@@ -26,10 +26,9 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
-#include <qofinstance-p.h>
 
 #include "gnc-engine.h"
 #include "gncBillTermP.h"
@@ -193,8 +192,6 @@ gnc_billterm_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_BILLTERM(object));
 
     bt = GNC_BILLTERM(object);
-    g_assert (qof_instance_get_editlevel(bt));
-
     switch (prop_id)
     {
     case PROP_NAME:
diff --git a/src/engine/gncBusiness.h b/src/engine/gncBusiness.h
index 11584b7..b9a960f 100644
--- a/src/engine/gncBusiness.h
+++ b/src/engine/gncBusiness.h
@@ -37,12 +37,6 @@
 #include <glib.h>
 #include "qof.h"
 
-/* KVP key for report PDF directories */
-#define OWNER_EXPORT_PDF_DIRNAME "export-pdf-directory"
-#define LAST_POSTED_TO_ACCT "last-posted-to-acct"
-#define GNC_PAYMENT "payment"
-#define GNC_LAST_ACCOUNT "last_acct"
-
 /* @deprecated backwards-compat definitions */
 #define GNC_BILLTERM_MODULE_NAME GNC_ID_BILLTERM
 #define GNC_CUSTOMER_MODULE_NAME GNC_ID_CUSTOMER
diff --git a/src/engine/gncCustomer.c b/src/engine/gncCustomer.c
index 5d3d7c5..581e97a 100644
--- a/src/engine/gncCustomer.c
+++ b/src/engine/gncCustomer.c
@@ -30,7 +30,6 @@
 
 #include <glib.h>
 #include <string.h>
-#include <qofinstance-p.h>
 
 #include "gnc-commodity.h"
 
@@ -97,10 +96,7 @@ void mark_customer (GncCustomer *customer)
 enum
 {
     PROP_0,
-    PROP_NAME,
-    PROP_PDF_DIRNAME,
-    PROP_LAST_POSTED,
-    PROP_PAYMENT_LAST_ACCT,
+    PROP_NAME
 };
 
 /* GObject Initialization */
@@ -130,7 +126,7 @@ gnc_customer_get_property (GObject         *object,
                            GParamSpec      *pspec)
 {
     GncCustomer *cust;
-    gchar *key;
+
     g_return_if_fail(GNC_IS_CUSTOMER(object));
 
     cust = GNC_CUSTOMER(object);
@@ -139,18 +135,6 @@ gnc_customer_get_property (GObject         *object,
     case PROP_NAME:
         g_value_set_string(value, cust->name);
         break;
-    case PROP_PDF_DIRNAME:
-	key = OWNER_EXPORT_PDF_DIRNAME;
-	qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
-	break;
-    case PROP_LAST_POSTED:
-	key = LAST_POSTED_TO_ACCT;
-	qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
-	break;
-    case PROP_PAYMENT_LAST_ACCT:
-	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
-	qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -160,34 +144,19 @@ gnc_customer_get_property (GObject         *object,
 static void
 gnc_customer_set_property (GObject         *object,
                            guint            prop_id,
-                           const GValue    *value,
+                           const GValue          *value,
                            GParamSpec      *pspec)
 {
     GncCustomer *cust;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_CUSTOMER(object));
 
     cust = GNC_CUSTOMER(object);
-    g_assert (qof_instance_get_editlevel(cust));
-
     switch (prop_id)
     {
     case PROP_NAME:
         gncCustomerSetName(cust, g_value_get_string(value));
         break;
-    case PROP_PDF_DIRNAME:
-	key = OWNER_EXPORT_PDF_DIRNAME;
-	qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
-	break;
-    case PROP_LAST_POSTED:
-	key = LAST_POSTED_TO_ACCT;
-	qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
-	break;
-    case PROP_PAYMENT_LAST_ACCT:
-	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
-	qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -273,39 +242,6 @@ gnc_customer_class_init (GncCustomerClass *klass)
                           "customer name.",
                           NULL,
                           G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_PDF_DIRNAME,
-     g_param_spec_string ("export-pdf-dir",
-                          "Export PDF Directory Name",
-                          "A subdirectory for exporting PDF reports which is "
-			  "appended to the target directory when writing them "
-			  "out. It is retrieved from preferences and stored on "
-			  "each 'Owner' object which prints items after "
-			  "printing.",
-                          NULL,
-                          G_PARAM_READWRITE));
-
-    g_object_class_install_property(
-       gobject_class,
-       PROP_LAST_POSTED,
-       g_param_spec_boxed("invoice-last-posted-account",
-			  "Invoice Last Posted Account",
-			  "The last account to which an invoice belonging to "
-			  "this owner was posted.",
-			  GNC_TYPE_GUID,
-			  G_PARAM_READWRITE));
-
-    g_object_class_install_property(
-       gobject_class,
-       PROP_PAYMENT_LAST_ACCT,
-       g_param_spec_boxed("payment-last-account",
-			  "Payment Last Account",
-			  "The last account to which an payment belonging to "
-			  "this owner was posted.",
-			  GNC_TYPE_GUID,
-			  G_PARAM_READWRITE));
 }
 
 /* Create/Destroy Functions */
@@ -930,6 +866,7 @@ gboolean gncCustomerRegister (void)
             (QofSetterFunc)gncCustomerSetTaxTableOverride
         },
         { CUSTOMER_TERMS, GNC_ID_BILLTERM, (QofAccessFunc)gncCustomerGetTerms, (QofSetterFunc)gncCustomerSetTerms },
+        { CUSTOMER_SLOTS, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL },
         { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncCustomerGetActive, (QofSetterFunc)gncCustomerSetActive },
         { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
         { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
diff --git a/src/engine/gncEmployee.c b/src/engine/gncEmployee.c
index ebfb518..94d7a72 100644
--- a/src/engine/gncEmployee.c
+++ b/src/engine/gncEmployee.c
@@ -26,11 +26,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
 #include <string.h>
-#include <qofinstance-p.h>
 
 #include "Account.h"
 #include "gnc-commodity.h"
@@ -80,19 +79,16 @@ void mark_employee (GncEmployee *employee)
 enum
 {
     PROP_0,
-    PROP_USERNAME,		/* Table */
-    PROP_ID,			/* Table */
-    PROP_LANGUAGE,		/* Table */
-    PROP_ACL,			/* Table */
-    PROP_ACTIVE,		/* Table */
-    PROP_CURRENCY,		/* Table */
-    PROP_CCARD,			/* Table */
-    PROP_WORKDAY,		/* Table (numeric) */
-    PROP_RATE,			/* Table (numeric) */
-    PROP_ADDRESS,		/* Table, 8 fields */
-    PROP_PDF_DIRNAME,		/* KVP */
-    PROP_LAST_POSTED,		/* KVP */
-    PROP_PAYMENT_LAST_ACCT,	/* KVP */
+    PROP_USERNAME,
+    PROP_ID,
+    PROP_ACTIVE,
+    PROP_LANGUAGE,
+    PROP_CURRENCY,
+    PROP_ACL,
+    PROP_ADDRESS,
+    PROP_WORKDAY,
+    PROP_RATE,
+    PROP_CCARD
 };
 
 /* GObject Initialization */
@@ -128,7 +124,6 @@ gnc_employee_get_property (GObject         *object,
                            GParamSpec      *pspec)
 {
     GncEmployee *emp;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_EMPLOYEE(object));
 
@@ -165,18 +160,6 @@ gnc_employee_get_property (GObject         *object,
     case PROP_CCARD:
         g_value_take_object(value, emp->ccard_acc);
         break;
-    case PROP_PDF_DIRNAME:
-	key = OWNER_EXPORT_PDF_DIRNAME;
-	qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
-	break;
-    case PROP_LAST_POSTED:
-	key = LAST_POSTED_TO_ACCT;
-	qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
-	break;
-    case PROP_PAYMENT_LAST_ACCT:
-	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
-	qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -190,13 +173,10 @@ gnc_employee_set_property (GObject         *object,
                            GParamSpec      *pspec)
 {
     GncEmployee *emp;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_EMPLOYEE(object));
 
     emp = GNC_EMPLOYEE(object);
-    g_assert (qof_instance_get_editlevel(emp));
-
     switch (prop_id)
     {
     case PROP_USERNAME:
@@ -229,18 +209,6 @@ gnc_employee_set_property (GObject         *object,
     case PROP_CCARD:
         gncEmployeeSetCCard(emp, g_value_get_object(value));
         break;
-    case PROP_PDF_DIRNAME:
-	key = OWNER_EXPORT_PDF_DIRNAME;
-	qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
-	break;
-    case PROP_LAST_POSTED:
-	key = LAST_POSTED_TO_ACCT;
-	qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
-	break;
-    case PROP_PAYMENT_LAST_ACCT:
-	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
-	qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -399,39 +367,6 @@ gnc_employee_class_init (GncEmployeeClass *klass)
                           "The credit card account for this employee.",
                           GNC_TYPE_ACCOUNT,
                           G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_PDF_DIRNAME,
-     g_param_spec_string ("export-pdf-dir",
-                          "Export PDF Directory Name",
-                          "A subdirectory for exporting PDF reports which is "
-			  "appended to the target directory when writing them "
-			  "out. It is retrieved from preferences and stored on "
-			  "each 'Owner' object which prints items after "
-			  "printing.",
-                          NULL,
-                          G_PARAM_READWRITE));
-
-    g_object_class_install_property(
-       gobject_class,
-       PROP_LAST_POSTED,
-       g_param_spec_boxed("invoice-last-posted-account",
-			  "Invoice Last Posted Account",
-			  "The last account to which an invoice belonging to "
-			  "this owner was posted.",
-			  GNC_TYPE_GUID,
-			  G_PARAM_READWRITE));
-
-    g_object_class_install_property(
-       gobject_class,
-       PROP_PAYMENT_LAST_ACCT,
-       g_param_spec_boxed("payment-last-account",
-			  "Payment Last Account",
-			  "The last account to which an payment belonging to "
-			  "this owner was posted.",
-			  GNC_TYPE_GUID,
-			  G_PARAM_READWRITE));
 }
 
 /* Create/Destroy Functions */
diff --git a/src/engine/gncEntry.c b/src/engine/gncEntry.c
index 173edbc..2593bed 100644
--- a/src/engine/gncEntry.c
+++ b/src/engine/gncEntry.c
@@ -25,10 +25,9 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
-#include <qofinstance-p.h>
 
 #include "gnc-commodity.h"
 
@@ -212,32 +211,7 @@ void mark_entry (GncEntry *entry)
 enum
 {
     PROP_0,
-//  PROP_DATE,		/* Table */
-//  PROP_DATE_ENTERED,	/* Table */
-    PROP_DESCRIPTION,	/* Table */
-//  PROP_ACTION,	/* Table */
-//  PROP_NOTES,		/* Table */
-//  PROP_QUANTITY,	/* Table (numeric) */
-//  PROP_I_ACCT,	/* Table */
-//  PROP_I_PRICE,	/* Table (numeric) */
-//  PROP_I_DISCOUNT,	/* Table (numeric) */
-//  PROP_INVOICE,	/* Table */
-//  PROP_I_DISC_TYPE,	/* Table */
-//  PROP_I_DISC_HOW,	/* Table */
-//  PROP_I_TAXABLE,	/* Table */
-//  PROP_I_TAX_INCL,	/* Table */
-//  PROP_I_TAXTABLE,	/* Table */
-//  PROP_B_ACCT,	/* Table */
-//  PROP_B_PRICE,	/* Table (numeric) */
-//  PROP_BILL,		/* Table */
-//  PROP_B_TAXTABLE_1,	/* Table */
-//  PROP_B_TAX_INCL,	/* Table */
-//  PROP_B_TAXTABLE,	/* Table */
-//  PROP_B_PAYTYPE,	/* Table */
-//  PROP_BILLABLE,	/* Table */
-//  PROP_BILLTO_TYPE,	/* Table */
-//  PROP_BILLTO,	/* Table */
-//  PROP_ORDER,		/* Table */
+    PROP_DESCRIPTION
 };
 
 /* GObject Initialization */
@@ -293,8 +267,6 @@ gnc_entry_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_ENTRY(object));
 
     entry = GNC_ENTRY(object);
-    g_assert (qof_instance_get_editlevel(entry));
-
     switch (prop_id)
     {
     case PROP_DESCRIPTION:
diff --git a/src/engine/gncInvoice.c b/src/engine/gncInvoice.c
index 0198958..9b9fed4 100644
--- a/src/engine/gncInvoice.c
+++ b/src/engine/gncInvoice.c
@@ -27,11 +27,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
 #include <glib/gi18n.h>
-#include <qofinstance-p.h>
 
 #include "Transaction.h"
 #include "Account.h"
@@ -82,6 +81,8 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
 
 #define _GNC_MOD_NAME     GNC_ID_INVOICE
 
+#define GNC_INVOICE_ID    "gncInvoice"
+#define GNC_INVOICE_GUID  "invoice-guid"
 #define GNC_INVOICE_IS_CN "credit-note"
 
 #define SET_STR(obj, member, str) { \
@@ -112,22 +113,7 @@ QofBook * gncInvoiceGetBook(GncInvoice *x)
 enum
 {
     PROP_0,
-//  PROP_ID,		/* Table */
-//  PROP_DATE_OPENED,	/* Table */
-//  PROP_DATE_POSTED,	/* Table */
-    PROP_NOTES,		/* Table */
-//  PROP_ACTIVE,	/* Table */
-//  PROP_CURRENCY,	/* Table */
-//  PROP_OWNER_TYPE,	/* Table */
-//  PROP_OWNER,		/* Table */
-//  PROP_TERMS,		/* Table */
-//  PROP_BILLING_ID,	/* Table */
-//  PROP_POST_TXN,	/* Table */
-//  PROP_POST_LOT,	/* Table */
-//  PROP_POST_ACCOUNT,	/* Table */
-//  PROP_BILLTO_TYPE,	/* Table */
-//  PROP_BILLTO,	/* Table */
-//  PROP_CHARGE_AMOUNT, /* Table, (numeric) */
+    PROP_NOTES
 };
 
 /* GObject Initialization */
@@ -183,8 +169,6 @@ gnc_invoice_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_INVOICE(object));
 
     inv = GNC_INVOICE(object);
-    g_assert (qof_instance_get_editlevel(inv));
-
     switch (prop_id)
     {
     case PROP_NOTES:
@@ -1149,37 +1133,52 @@ qofInvoiceSetJob (GncInvoice *invoice, GncJob *job)
 static void
 gncInvoiceDetachFromLot (GNCLot *lot)
 {
-    if (!lot) return;
+    KvpFrame *kvp;
 
+    if (!lot) return;
     gnc_lot_begin_edit (lot);
-    qof_instance_set (QOF_INSTANCE (lot), "invoice", NULL, NULL);
+    kvp = gnc_lot_get_slots (lot);
+    kvp_frame_set_slot_path (kvp, NULL, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
+    qof_instance_set_dirty (QOF_INSTANCE (lot));
     gnc_lot_commit_edit (lot);
 }
 
 static void
 gncInvoiceAttachToLot (GncInvoice *invoice, GNCLot *lot)
 {
-    GncGUID *guid;
+    KvpFrame *kvp;
+    KvpValue *value;
+
     if (!invoice || !lot)
         return;
 
     if (invoice->posted_lot) return;	/* Cannot reset invoice's lot */
-    guid  = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (invoice));
+
     gnc_lot_begin_edit (lot);
-    qof_instance_set (QOF_INSTANCE (lot), "invoice", guid, NULL);
+    kvp = gnc_lot_get_slots (lot);
+    value = kvp_value_new_guid (qof_instance_get_guid (QOF_INSTANCE(invoice)));
+    kvp_frame_set_slot_path (kvp, value, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
+    qof_instance_set_dirty (QOF_INSTANCE (lot));
     gnc_lot_commit_edit (lot);
+    kvp_value_delete (value);
     gncInvoiceSetPostedLot (invoice, lot);
 }
 
 GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot)
 {
-    GncGUID *guid = NULL;
+    KvpFrame *kvp;
+    KvpValue *value;
+    GncGUID *guid;
     QofBook *book;
 
     if (!lot) return NULL;
 
     book = gnc_lot_get_book (lot);
-    qof_instance_get (QOF_INSTANCE (lot), "invoice", &guid, NULL);
+    kvp = gnc_lot_get_slots (lot);
+    value = kvp_frame_get_slot_path (kvp, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
+    if (!value) return NULL;
+
+    guid = kvp_value_get_guid (value);
     return gncInvoiceLookup(book, guid);
 }
 
@@ -1195,8 +1194,10 @@ gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
     if (invoice->posted_txn) return;	/* Cannot reset invoice's txn */
 
     xaccTransBeginEdit (txn);
-    qof_instance_set (QOF_INSTANCE (txn), "invoice",
-		      qof_instance_get_guid (QOF_INSTANCE (invoice)), NULL);
+    kvp = xaccTransGetSlots (txn);
+    value = kvp_value_new_guid (qof_instance_get_guid(QOF_INSTANCE(invoice)));
+    kvp_frame_set_slot_path (kvp, value, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
+    kvp_value_delete (value);
     xaccTransSetTxnType (txn, TXN_TYPE_INVOICE);
     xaccTransCommitEdit (txn);
     gncInvoiceSetPostedTxn (invoice, txn);
@@ -1205,13 +1206,19 @@ gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
 GncInvoice *
 gncInvoiceGetInvoiceFromTxn (const Transaction *txn)
 {
-    GncGUID *guid = NULL;
+    KvpFrame *kvp;
+    KvpValue *value;
+    GncGUID *guid;
     QofBook *book;
 
     if (!txn) return NULL;
 
     book = xaccTransGetBook (txn);
-    qof_instance_get (QOF_INSTANCE (txn), "invoice", &guid, NULL);
+    kvp = xaccTransGetSlots (txn);
+    value = kvp_frame_get_slot_path (kvp, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
+    if (!value) return NULL;
+
+    guid = kvp_value_get_guid (value);
     return gncInvoiceLookup(book, guid);
 }
 
diff --git a/src/engine/gncInvoice.h b/src/engine/gncInvoice.h
index 4914432..e3e41df 100644
--- a/src/engine/gncInvoice.h
+++ b/src/engine/gncInvoice.h
@@ -268,7 +268,6 @@ GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot);
  */
 static inline GncInvoice * gncInvoiceLookup (const QofBook *book, const GncGUID *guid)
 {
-    if (book == NULL || guid == NULL) return NULL;
     QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_INVOICE, GncInvoice);
 }
 
@@ -306,6 +305,7 @@ QofBook *gncInvoiceGetBook(GncInvoice *x);
 /** deprecated functions */
 #define gncInvoiceGetGUID(x) qof_instance_get_guid(QOF_INSTANCE(x))
 #define gncInvoiceRetGUID(x) (x ? *(qof_instance_get_guid(QOF_INSTANCE(x))) : *(guid_null()))
+#define gncInvoiceLookupDirect(G,B) gncInvoiceLookup((B),&(G))
 
 /** Test support function used by test-dbi-business-stuff.c */
 gboolean gncInvoiceEqual(const GncInvoice *a, const GncInvoice *b);
diff --git a/src/engine/gncJob.c b/src/engine/gncJob.c
index d4200a1..fe7043d 100644
--- a/src/engine/gncJob.c
+++ b/src/engine/gncJob.c
@@ -26,11 +26,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
 #include <string.h>
-#include <qofinstance-p.h>
 
 #include "gnc-features.h"
 #include "gncInvoice.h"
@@ -72,13 +71,7 @@ void mark_job (GncJob *job)
 enum
 {
     PROP_0,
-//  PROP_ID,		/* Table */
-    PROP_NAME,		/* Table */
-//  PROP_REFERENCE,	/* Table */
-//  PROP_ACTIVE,	/* Table */
-//  PROP_OWNER_TYPE,	/* Table */
-//  PROP_OWNER,		/* Table */
-    PROP_PDF_DIRNAME,	/* KVP */
+    PROP_NAME
 };
 
 /* GObject Initialization */
@@ -108,7 +101,6 @@ gnc_job_get_property (GObject         *object,
                       GParamSpec      *pspec)
 {
     GncJob *job;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_JOB(object));
 
@@ -118,10 +110,6 @@ gnc_job_get_property (GObject         *object,
     case PROP_NAME:
         g_value_set_string(value, job->name);
         break;
-    case PROP_PDF_DIRNAME:
-	key = OWNER_EXPORT_PDF_DIRNAME;
-	qof_instance_get_kvp (QOF_INSTANCE (job), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -135,22 +123,15 @@ gnc_job_set_property (GObject         *object,
                       GParamSpec      *pspec)
 {
     GncJob *job;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_JOB(object));
 
     job = GNC_JOB(object);
-    g_assert (qof_instance_get_editlevel(job));
-
     switch (prop_id)
     {
     case PROP_NAME:
         gncJobSetName(job, g_value_get_string(value));
         break;
-    case PROP_PDF_DIRNAME:
-	key = OWNER_EXPORT_PDF_DIRNAME;
-	qof_instance_set_kvp (QOF_INSTANCE (job), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -196,19 +177,6 @@ gnc_job_class_init (GncJobClass *klass)
                           "by the GUI as the job mnemonic.",
                           NULL,
                           G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_PDF_DIRNAME,
-     g_param_spec_string ("export-pdf-dir",
-                          "Export PDF Directory Name",
-                          "A subdirectory for exporting PDF reports which is "
-			  "appended to the target directory when writing them "
-			  "out. It is retrieved from preferences and stored on "
-			  "each 'Owner' object which prints items after "
-			  "printing.",
-                          NULL,
-                          G_PARAM_READWRITE));
 }
 
 /* Create/Destroy Functions */
diff --git a/src/engine/gncOrder.c b/src/engine/gncOrder.c
index 2d36b54..dd613c4 100644
--- a/src/engine/gncOrder.c
+++ b/src/engine/gncOrder.c
@@ -25,11 +25,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
 #include <glib/gi18n.h>
-#include <qofinstance-p.h>
 
 #include "gncEntry.h"
 #include "gncEntryP.h"
@@ -85,14 +84,12 @@ void mark_order (GncOrder *order)
 enum
 {
     PROP_0,
-    PROP_ID,		/* Table */
-    PROP_NOTES,		/* Table */
-    PROP_REFERENCE,	/* Table */
-    PROP_ACTIVE,	/* Table */
-    PROP_DATE_OPENED,	/* Table */
-    PROP_DATE_CLOSED,	/* Table */
-//  PROP_OWNER_TYPE,	/* Table */
-//  PROP_OWNER,		/* Table */
+    PROP_ID,
+    PROP_NOTES,
+    PROP_ACTIVE,
+    PROP_DATE_OPENED,
+    PROP_DATE_CLOSED,
+    PROP_REFERENCE
 };
 
 /* GObject Initialization */
@@ -163,8 +160,6 @@ gnc_order_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_ORDER(object));
 
     order = GNC_ORDER(object);
-    g_assert (qof_instance_get_editlevel(order));
-
     switch (prop_id)
     {
     case PROP_ID:
diff --git a/src/engine/gncOwner.c b/src/engine/gncOwner.c
index 6fa69d4..8a1d0bf 100644
--- a/src/engine/gncOwner.c
+++ b/src/engine/gncOwner.c
@@ -29,12 +29,11 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <string.h>		/* for memcpy() */
-#include <qofinstance-p.h>
 
 #include "gncCustomerP.h"
 #include "gncEmployeeP.h"
@@ -51,6 +50,8 @@
 #define _GNC_MOD_NAME   GNC_ID_OWNER
 
 #define GNC_OWNER_ID    "gncOwner"
+#define GNC_OWNER_TYPE  "owner-type"
+#define GNC_OWNER_GUID  "owner-guid"
 
 GncOwner * gncOwnerNew (void)
 {
@@ -98,36 +99,6 @@ void gncOwnerBeginEdit (GncOwner *owner)
     }
 }
 
-void gncOwnerCommitEdit (GncOwner *owner)
-{
-    if (!owner) return;
-    switch (owner->type)
-    {
-    case GNC_OWNER_NONE :
-    case GNC_OWNER_UNDEFINED :
-        break;
-    case GNC_OWNER_CUSTOMER :
-    {
-        gncCustomerCommitEdit(owner->owner.customer);
-        break;
-    }
-    case GNC_OWNER_JOB :
-    {
-        gncJobCommitEdit(owner->owner.job);
-        break;
-    }
-    case GNC_OWNER_VENDOR :
-    {
-        gncVendorCommitEdit(owner->owner.vendor);
-        break;
-    }
-    case GNC_OWNER_EMPLOYEE :
-    {
-        gncEmployeeCommitEdit(owner->owner.employee);
-        break;
-    }
-    }
-}
 
 void gncOwnerDestroy (GncOwner *owner)
 {
@@ -596,31 +567,52 @@ const GncGUID * gncOwnerGetEndGUID (const GncOwner *owner)
 
 void gncOwnerAttachToLot (const GncOwner *owner, GNCLot *lot)
 {
-     if (!owner || !lot)
+    KvpFrame *kvp;
+    KvpValue *value;
+
+    if (!owner || !lot)
         return;
 
+    kvp = gnc_lot_get_slots (lot);
     gnc_lot_begin_edit (lot);
 
-    qof_instance_set (QOF_INSTANCE (lot),
-		      "owner-type", (gint64)gncOwnerGetType (owner),
-		      "owner-guid", gncOwnerGetGUID (owner),
-		      NULL);
+    value = kvp_value_new_gint64 (gncOwnerGetType (owner));
+    kvp_frame_set_slot_path (kvp, value, GNC_OWNER_ID, GNC_OWNER_TYPE, NULL);
+    kvp_value_delete (value);
+
+    value = kvp_value_new_guid (gncOwnerGetGUID (owner));
+    kvp_frame_set_slot_path (kvp, value, GNC_OWNER_ID, GNC_OWNER_GUID, NULL);
+    qof_instance_set_dirty (QOF_INSTANCE (lot));
     gnc_lot_commit_edit (lot);
+    kvp_value_delete (value);
+
 }
 
 gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner)
 {
-    GncGUID *guid = NULL;
+    KvpFrame *kvp;
+    KvpValue *value;
+    GncGUID *guid;
     QofBook *book;
-    GncOwnerType type = GNC_OWNER_NONE;
+    GncOwnerType type;
 
     if (!lot || !owner) return FALSE;
 
     book = gnc_lot_get_book (lot);
-    qof_instance_get (QOF_INSTANCE (lot),
-		      "owner-type", &type,
-		      "owner-guid", &guid,
-		      NULL);
+    kvp = gnc_lot_get_slots (lot);
+
+    value = kvp_frame_get_slot_path (kvp, GNC_OWNER_ID, GNC_OWNER_TYPE, NULL);
+    if (!value) return FALSE;
+
+    type = kvp_value_get_gint64 (value);
+
+    value = kvp_frame_get_slot_path (kvp, GNC_OWNER_ID, GNC_OWNER_GUID, NULL);
+    if (!value) return FALSE;
+
+    guid = kvp_value_get_guid (value);
+    if (!guid)
+        return FALSE;
+
     switch (type)
     {
     case GNC_OWNER_CUSTOMER:
@@ -648,6 +640,23 @@ gboolean gncOwnerIsValid (const GncOwner *owner)
     return (owner->owner.undefined != NULL);
 }
 
+KvpFrame* gncOwnerGetSlots(GncOwner* owner)
+{
+    if (!owner) return NULL;
+
+    switch (gncOwnerGetType(owner))
+    {
+    case GNC_OWNER_CUSTOMER:
+    case GNC_OWNER_VENDOR:
+    case GNC_OWNER_EMPLOYEE:
+        return qof_instance_get_slots(QOF_INSTANCE(owner->owner.undefined));
+    case GNC_OWNER_JOB:
+        return gncOwnerGetSlots(gncJobGetOwner(gncOwnerGetJob(owner)));
+    default:
+        return NULL;
+    }
+}
+
 gboolean
 gncOwnerLotMatchOwnerFunc (GNCLot *lot, gpointer user_data)
 {
diff --git a/src/engine/gncOwner.h b/src/engine/gncOwner.h
index 0874102..ac987bc 100644
--- a/src/engine/gncOwner.h
+++ b/src/engine/gncOwner.h
@@ -197,6 +197,9 @@ gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner);
 
 gboolean gncOwnerGetOwnerFromTypeGuid (QofBook *book, GncOwner *owner, QofIdType type, GncGUID *guid);
 
+/** Get the kvp-frame from the underlying owner object */
+KvpFrame* gncOwnerGetSlots(GncOwner* owner);
+
 /**
  * Create a lot for a payment to the owner using the other
  * parameters passed in. If a transaction is set, this transaction will be
@@ -304,7 +307,6 @@ void gncOwnerFree (GncOwner *owner);
  * without knowing its type.
  */
 void gncOwnerBeginEdit (GncOwner *owner);
-void gncOwnerCommitEdit (GncOwner *owner);
 void gncOwnerDestroy (GncOwner *owner);
 
 #endif /* GNC_OWNER_H_ */
diff --git a/src/engine/gncTaxTable.c b/src/engine/gncTaxTable.c
index 2c525f4..8650217 100644
--- a/src/engine/gncTaxTable.c
+++ b/src/engine/gncTaxTable.c
@@ -26,10 +26,9 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
-#include <qofinstance-p.h>
 
 #include "gnc-features.h"
 #include "gncTaxTableP.h"
@@ -209,10 +208,9 @@ gncTaxTableRemoveChild (GncTaxTable *table, const GncTaxTable *child)
 enum
 {
     PROP_0,
-    PROP_NAME,		/* Table */
-    PROP_INVISIBLE,	/* Table */
-    PROP_REFCOUNT,	/* Table */
-//  PROP_PARENT,	/* Table */
+    PROP_NAME,
+    PROP_INVISIBLE,
+    PROP_REFCOUNT
 };
 
 /* GObject Initialization */
@@ -274,8 +272,6 @@ gnc_taxtable_set_property (GObject         *object,
     g_return_if_fail(GNC_IS_TAXTABLE(object));
 
     tt = GNC_TAXTABLE(object);
-    g_assert (qof_instance_get_editlevel(tt));
-
     switch (prop_id)
     {
     case PROP_NAME:
diff --git a/src/engine/gncVendor.c b/src/engine/gncVendor.c
index 3ebdb2b..d416db4 100644
--- a/src/engine/gncVendor.c
+++ b/src/engine/gncVendor.c
@@ -26,11 +26,10 @@
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <glib.h>
 #include <string.h>
-#include <qofinstance-p.h>
 
 #include "gnc-commodity.h"
 #include "gncAddressP.h"
@@ -89,20 +88,17 @@ void mark_vendor (GncVendor *vendor)
 enum
 {
     PROP_0,
-    PROP_NAME,			/* Table */
-    PROP_ID,			/* Table */
-    PROP_NOTES,			/* Table */
-    PROP_CURRENCY,		/* Table */
-    PROP_ACTIVE,		/* Table */
-    PROP_TAXTABLE_OVERRIDE,	/* Table */
-    PROP_BILLTERMS,		/* Table */
-    PROP_TAXTABLE,		/* Table */
-    PROP_ADDRESS,		/* Table, 8 fields */
-    PROP_TAX_INCLUDED,		/* Table */
-    PROP_TAX_INCLUDED_STR,	/* Alternate setter for PROP_TAX_INCLUDED */
-    PROP_PDF_DIRNAME,		/* KVP */
-    PROP_LAST_POSTED,		/* KVP */
-    PROP_PAYMENT_LAST_ACCT,	/* KVP */
+    PROP_NAME,
+    PROP_ID,
+    PROP_NOTES,
+    PROP_CURRENCY,
+    PROP_ACTIVE,
+    PROP_TAXTABLE_OVERRIDE,
+    PROP_BILLTERMS,
+    PROP_TAXTABLE,
+    PROP_ADDRESS,
+    PROP_TAX_INCLUDED,
+    PROP_TAX_INCLUDED_STR
 };
 
 /* GObject Initialization */
@@ -138,7 +134,6 @@ gnc_vendor_get_property (GObject         *object,
                          GParamSpec      *pspec)
 {
     GncVendor *vendor;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_VENDOR(object));
 
@@ -178,18 +173,6 @@ gnc_vendor_get_property (GObject         *object,
     case PROP_TAX_INCLUDED_STR:
         g_value_set_string(value, qofVendorGetTaxIncluded(vendor));
         break;
-    case PROP_PDF_DIRNAME:
-	key = OWNER_EXPORT_PDF_DIRNAME;
-	qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
-	break;
-    case PROP_LAST_POSTED:
-	key = LAST_POSTED_TO_ACCT;
-	qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
-	break;
-    case PROP_PAYMENT_LAST_ACCT:
-	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
-	qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -203,13 +186,10 @@ gnc_vendor_set_property (GObject         *object,
                          GParamSpec      *pspec)
 {
     GncVendor *vendor;
-    gchar *key;
 
     g_return_if_fail(GNC_IS_VENDOR(object));
 
     vendor = GNC_VENDOR(object);
-    g_assert (qof_instance_get_editlevel(vendor));
-
     switch (prop_id)
     {
     case PROP_NAME:
@@ -245,18 +225,6 @@ gnc_vendor_set_property (GObject         *object,
     case PROP_TAX_INCLUDED_STR:
         qofVendorSetTaxIncluded(vendor, g_value_get_string(value));
         break;
-    case PROP_PDF_DIRNAME:
-	key = OWNER_EXPORT_PDF_DIRNAME;
-	qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
-	break;
-    case PROP_LAST_POSTED:
-	key = LAST_POSTED_TO_ACCT;
-	qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
-	break;
-    case PROP_PAYMENT_LAST_ACCT:
-	key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
-	qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
-	break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -422,38 +390,6 @@ gnc_vendor_class_init (GncVendorClass *klass)
                          "The tax-included-string property contains a character version of tax-included.",
                          FALSE,
                          G_PARAM_READWRITE));
-    g_object_class_install_property
-    (gobject_class,
-     PROP_PDF_DIRNAME,
-     g_param_spec_string ("export-pdf-dir",
-                          "Export PDF Directory Name",
-                          "A subdirectory for exporting PDF reports which is "
-			  "appended to the target directory when writing them "
-			  "out. It is retrieved from preferences and stored on "
-			  "each 'Owner' object which prints items after "
-			  "printing.",
-                          NULL,
-                          G_PARAM_READWRITE));
-
-    g_object_class_install_property(
-       gobject_class,
-       PROP_LAST_POSTED,
-       g_param_spec_boxed("invoice-last-posted-account",
-			  "Invoice Last Posted Account",
-			  "The last account to which an invoice belonging to "
-			  "this owner was posted.",
-			  GNC_TYPE_GUID,
-			  G_PARAM_READWRITE));
-
-    g_object_class_install_property(
-       gobject_class,
-       PROP_PAYMENT_LAST_ACCT,
-       g_param_spec_boxed("payment-last-account",
-			  "Payment Last Account",
-			  "The last account to which an payment belonging to "
-			  "this owner was posted.",
-			  GNC_TYPE_GUID,
-			  G_PARAM_READWRITE));
 }
 
 /* Create/Destroy Functions */
diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c
index 77086f0..ad35d9b 100644
--- a/src/engine/test-core/test-engine-stuff.c
+++ b/src/engine/test-core/test-engine-stuff.c
@@ -26,7 +26,6 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#include <qofinstance-p.h>
 
 #include "Account.h"
 #include "AccountP.h"
@@ -1340,7 +1339,7 @@ get_random_split(QofBook *book, Account *acct, Transaction *trn)
     else
         g_assert(!gnc_numeric_positive_p(amt)); /* non-positive amt */
 
-    qof_instance_set_slots(QOF_INSTANCE (ret), get_random_kvp_frame());
+    xaccSplitSetSlots_nc(ret, get_random_kvp_frame());
     xaccTransCommitEdit(trn);
 
     return ret;
@@ -1367,7 +1366,7 @@ make_random_changes_to_split (Split *split)
     xaccSplitSetDateReconciledTS (split, ts);
     g_free(ts);
 
-    qof_instance_set_slots (QOF_INSTANCE (split), get_random_kvp_frame());
+    xaccSplitSetSlots_nc (split, get_random_kvp_frame());
 
     /* Don't change share values/prices here, since that would
      * throw transactions out of balance. Do that in the corresponding
@@ -2170,13 +2169,13 @@ make_trans_query (Transaction *trans, TestQueryTypes query_types)
     }
 
     if (query_types & SPLIT_KVP_QT)
-        add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (s)), GNC_ID_SPLIT);
+        add_kvp_query (q, xaccSplitGetSlots (s), GNC_ID_SPLIT);
 
     if (query_types & TRANS_KVP_QT)
-        add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (trans)), GNC_ID_TRANS);
+        add_kvp_query (q, xaccTransGetSlots (trans), GNC_ID_TRANS);
 
     if (query_types & ACCOUNT_KVP_QT)
-        add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (a)), GNC_ID_ACCOUNT);
+        add_kvp_query (q, xaccAccountGetSlots (a), GNC_ID_ACCOUNT);
 
     return q;
 }
diff --git a/src/engine/test/Makefile.am b/src/engine/test/Makefile.am
index 9e1f098..ec7bed0 100644
--- a/src/engine/test/Makefile.am
+++ b/src/engine/test/Makefile.am
@@ -116,7 +116,6 @@ test_engine_SOURCES = \
 	utest-Account.c \
 	utest-Budget.c \
 	utest-Invoice.c \
-	test-engine-kvp-properties.c \
 	dummy.cpp
 
 test_engine_LDADD = \
diff --git a/src/engine/test/test-account-object.c b/src/engine/test/test-account-object.c
index b87bb22..60765b5 100644
--- a/src/engine/test/test-account-object.c
+++ b/src/engine/test/test-account-object.c
@@ -33,7 +33,6 @@
 #include "cashobjects.h"
 #include "test-stuff.h"
 #include "test-engine-stuff.h"
-#include <qofinstance-p.h>
 
 static void
 run_test (void)
@@ -62,9 +61,7 @@ run_test (void)
     /*****/
 
     five = gnc_numeric_create(5, 1);
-    qof_instance_increase_editlevel (acc);
     g_object_set(acc, "start-balance", &five, NULL);
-    qof_instance_decrease_editlevel (acc);
     xaccAccountRecomputeBalance(acc);
     g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
     end2 = xaccAccountGetBalance(acc);
diff --git a/src/engine/test/test-customer.c b/src/engine/test/test-customer.c
index fe8fb2f..02f67df 100644
--- a/src/engine/test/test-customer.c
+++ b/src/engine/test/test-customer.c
@@ -24,11 +24,9 @@
  *
  *********************************************************************/
 
-#include <config.h>
+#include "config.h"
 #include <glib.h>
-#include <qof.h>
-#include <qofinstance-p.h>
-
+#include "qof.h"
 #include "cashobjects.h"
 #include "gncCustomerP.h"
 #include "gncInvoiceP.h"
diff --git a/src/engine/test/test-employee.c b/src/engine/test/test-employee.c
index 1835bbf..03bb066 100644
--- a/src/engine/test/test-employee.c
+++ b/src/engine/test/test-employee.c
@@ -24,11 +24,9 @@
  *
  *********************************************************************/
 
-#include <config.h>
+#include "config.h"
 #include <glib.h>
-#include <qof.h>
-#include <qofinstance-p.h>
-
+#include "qof.h"
 #include "gncEmployeeP.h"
 #include "gncCustomerP.h"
 #include "gncJobP.h"
diff --git a/src/engine/test/test-engine-kvp-properties.c b/src/engine/test/test-engine-kvp-properties.c
deleted file mode 100644
index 8b95526..0000000
--- a/src/engine/test/test-engine-kvp-properties.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/********************************************************************
- * test-engine-kvp-properties.c: GLib g_test test suite for         *
- * KVP-based properties in several engine classes.                  *
- * Copyright 2013 John Ralls <jralls at ceridwen.us>		    *
- *                                                                  *
- * This program is free software; you can redistribute it and/or    *
- * modify it under the terms of the GNU General Public License as   *
- * published by the Free Software Foundation; either version 2 of   *
- * the License, or (at your option) any later version.              *
- *                                                                  *
- * This program is distributed in the hope that it will be useful,  *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
- * GNU General Public License for more details.                     *
- *                                                                  *
- * You should have received a copy of the GNU General Public License*
- * along with this program; if not, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
-\********************************************************************/
-
-/**
- * Test Engine KVP Properties Acceptance testing for KVP Properties
- * added to various engine classes to make private the internals of
- * KVP storage used for a variety of parameters on several engine
- * classes.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <qof.h>
-#include <unittest-support.h>
-#include "../Transaction.h"
-#include "../Split.h"
-#include "../Account.h"
-#include "../SchedXAction.h"
-#include "../gncCustomer.h"
-#include "../gncEmployee.h"
-#include "../gncJob.h"
-#include "../gncVendor.h"
-
-typedef struct
-{
-    union
-    {
-	Account      *acct;
-	Transaction  *trans;
-	Split        *split;
-	GNCLot       *lot;
-	GncCustomer  *cust;
-	GncEmployee  *emp;
-	GncJob       *job;
-	GncVendor    *vend;
-    };
-    GSList *hdlrs;
-} Fixture;
-
-/* Prototype to shut clang up */
-void test_suite_engine_kvp_properties (void);
-
-/* Private QofInstance functions needed for testing */
-extern void qof_instance_mark_clean (QofInstance*);
-
-const gchar *suitename = "/engine/kvp-properties";
-
-static void
-setup_account (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = qof_book_new ();
-    fixture->acct = xaccMallocAccount (book);
-}
-
-static void
-setup_trans (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = qof_book_new ();
-    fixture->trans = xaccMallocTransaction (book);
-}
-
-static void
-setup_split (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = qof_book_new ();
-    fixture->split = xaccMallocSplit (book);
-}
-
-static void
-setup_lot (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = qof_book_new ();
-    fixture->lot = gnc_lot_new (book);
-}
-
-static void
-setup_customer (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = qof_book_new ();
-    fixture->cust = gncCustomerCreate (book);
-}
-
-static void
-setup_employee (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = qof_book_new ();
-    fixture->emp = gncEmployeeCreate (book);
-}
-
-static void
-setup_job (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = qof_book_new ();
-    fixture->job = gncJobCreate (book);
-}
-
-static void
-setup_vendor (Fixture *fixture, gconstpointer pData)
-{
-    QofBook *book = qof_book_new ();
-    fixture->vend = gncVendorCreate (book);
-}
-
-static void
-teardown (Fixture *fixture, gconstpointer pData)
-{
-/* It doesn't actually matter which union member we use here, they're
- * all QofInstances, so this will work for any of them.
- */
-    QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->acct));
-    test_destroy (fixture->acct);
-    test_destroy (book);
-}
-
-static void
-test_account_kvp_properties (Fixture *fixture, gconstpointer pData)
-{
-    gint64 next_id = 12345678909876;
-    gint64 ab_acct_uid = 67890987654321;
-    gint64 next_id_r, ab_acct_uid_r;
-    gchar *online_id = "my online id";
-    gchar *ab_acct_id = "1234-5678-9087";
-    gchar *ab_bank_code = "0032340";
-    gchar *online_id_r, *ab_acct_id_r, *ab_bank_code_r;
-    GncGUID *ofx_income_acct = guid_malloc ();
-    GncGUID *ofx_income_acct_r;
-    Timespec trans_retr = timespec_now ();
-    Timespec *trans_retr_r;
-
-    xaccAccountBeginEdit (fixture->acct);
-    qof_instance_set (QOF_INSTANCE (fixture->acct),
-		      "lot-next-id", next_id,
-		      "online-id", online_id,
-		      "ofx-income-account", ofx_income_acct,
-		      "ab-account-id", ab_acct_id,
-		      "ab-bank-code", ab_bank_code,
-		      "ab-account-uid", ab_acct_uid,
-		      "ab-trans-retrieval", &trans_retr,
-		      NULL);
-
-    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
-    qof_instance_mark_clean (QOF_INSTANCE (fixture->acct));
-
-    qof_instance_get (QOF_INSTANCE (fixture->acct),
-		      "lot-next-id", &next_id_r,
-		      "online-id", &online_id_r,
-		      "ofx-income-account", &ofx_income_acct_r,
-		      "ab-account-id", &ab_acct_id_r,
-		      "ab-bank-code", &ab_bank_code_r,
-		      "ab-account-uid", &ab_acct_uid_r,
-		      "ab-trans-retrieval", &trans_retr_r,
-		      NULL);
-    g_assert_cmpint (next_id, ==, next_id_r);
-    g_assert_cmpstr (online_id, ==, online_id_r);
-    g_assert (guid_equal (ofx_income_acct, ofx_income_acct_r));
-    g_assert_cmpstr (ab_acct_id, ==, ab_acct_id_r);
-    g_assert_cmpstr (ab_bank_code, ==, ab_bank_code_r);
-    g_assert_cmpint (ab_acct_uid, ==, ab_acct_uid_r);
-    g_assert (timespec_equal (&trans_retr, trans_retr_r));
-    g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
-}
-
-static void
-test_trans_kvp_properties (Fixture *fixture, gconstpointer pData)
-{
-    GncGUID *invoice = guid_malloc ();
-    GncGUID *from_sx = guid_malloc ();
-    GncGUID *invoice_r, *from_sx_r;
-    gchar *online_id = "my online id";
-    gchar *online_id_r;
-
-    xaccTransBeginEdit (fixture->trans);
-    qof_instance_set (QOF_INSTANCE (fixture->trans),
-		      "invoice", invoice,
-		      "from-sched-xaction", from_sx,
-		      "online-id", online_id,
-		      NULL);
-
-    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->trans)));
-    qof_instance_mark_clean (QOF_INSTANCE (fixture->trans));
-
-    qof_instance_get (QOF_INSTANCE (fixture->trans),
-		      "invoice", &invoice_r,
-		      "from-sched-xaction", &from_sx_r,
-		      "online-id", &online_id_r,
-		      NULL);
-    g_assert (guid_equal (invoice, invoice_r));
-    g_assert (guid_equal (from_sx, from_sx_r));
-    g_assert_cmpstr (online_id, ==, online_id_r);
-    g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->trans)));
-    guid_free (invoice);
-    guid_free (invoice_r);
-    guid_free (from_sx);
-    guid_free (from_sx_r);
-    g_free (online_id_r);
-}
-
-static void
-test_split_kvp_properties (Fixture *fixture, gconstpointer pData)
-{
-    gchar *debit_formula = "e^xdydx";
-    gchar *credit_formula = "seccostansin";
-    gchar *sx_shares = "43";
-    gchar *online_id = "my_online_id";
-    gchar *debit_formula_r, *credit_formula_r, *sx_shares_r;
-    gchar *online_id_r;
-    GncGUID *sx_account = guid_malloc ();
-    GncGUID *sx_account_r;
-    gnc_numeric debit_numeric = gnc_numeric_create (123, 456);
-    gnc_numeric credit_numeric = gnc_numeric_create (789, 456);
-    gnc_numeric *debit_numeric_r, *credit_numeric_r;
-
-    qof_begin_edit (QOF_INSTANCE (fixture->split));
-    qof_instance_set (QOF_INSTANCE (fixture->split),
-		      "sx-debit-formula", debit_formula,
-		      "sx-debit-numeric", &debit_numeric,
-		      "sx-credit-formula", credit_formula,
-		      "sx-credit-numeric", &credit_numeric,
-		      "sx-account", sx_account,
-		      "sx-shares", sx_shares,
-		      "online-id", online_id,
-		      NULL);
-
-    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->split)));
-    qof_instance_mark_clean (QOF_INSTANCE (fixture->split));
-
-    qof_instance_get (QOF_INSTANCE (fixture->split),
-		      "sx-debit-formula", &debit_formula_r,
-		      "sx-debit-numeric", &debit_numeric_r,
-		      "sx-credit-formula", &credit_formula_r,
-		      "sx-credit-numeric", &credit_numeric_r,
-		      "sx-account", &sx_account_r,
-		      "sx-shares", &sx_shares_r,
-		      "online-id", &online_id_r,
-		      NULL);
-    g_assert_cmpstr (debit_formula, ==, debit_formula_r);
-    g_assert (gnc_numeric_equal (debit_numeric, *debit_numeric_r));
-    g_assert_cmpstr (credit_formula, ==, credit_formula_r);
-    g_assert (gnc_numeric_equal (credit_numeric, *credit_numeric_r));
-    g_assert (guid_equal (sx_account, sx_account_r));
-    g_assert_cmpstr (sx_shares, ==, sx_shares_r);
-    g_assert_cmpstr (online_id, ==, online_id_r);
-    g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->split)));
-    g_free (debit_formula_r);
-    g_free (debit_numeric_r);
-    g_free (credit_formula_r);
-    g_free (credit_numeric_r);
-    qof_begin_edit (QOF_INSTANCE (fixture->split));
-    qof_instance_set (QOF_INSTANCE (fixture->split),
-		      "sx-credit-formula", NULL,
-		      NULL);
-    qof_instance_get (QOF_INSTANCE (fixture->split),
-		      "sx-credit-formula", &credit_numeric_r,
-		      NULL);
-    g_assert (credit_numeric_r == NULL);
-    g_free (sx_shares_r);
-    g_free (online_id_r);
-    guid_free (sx_account);
-    guid_free (sx_account_r);
-}
-
-static void
-test_lot_kvp_properties (Fixture *fixture, gconstpointer pData)
-{
-    GncGUID *invoice = guid_malloc ();
-    GncGUID *invoice_r;
-    gint64 owner_type = 47;
-    gint64 owner_type_r;
-    GncGUID *owner = guid_malloc ();
-    GncGUID *owner_r;
-
-    qof_begin_edit (QOF_INSTANCE (fixture->lot));
-    qof_instance_set (QOF_INSTANCE (fixture->lot),
-		      "invoice", invoice,
-		      "owner-type", owner_type,
-		      "owner-guid", owner,
-		      NULL);
-
-    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->lot)));
-    qof_instance_mark_clean (QOF_INSTANCE (fixture->lot));
-
-    qof_instance_get (QOF_INSTANCE (fixture->lot),
-		      "invoice", &invoice_r,
-		      "owner-type", &owner_type_r,
-		      "owner-guid", &owner_r,
-		      NULL);
-    g_assert (guid_equal (invoice, invoice_r));
-    g_assert_cmpint (owner_type, ==, owner_type_r);
-    g_assert (guid_equal (owner, owner_r));
-    g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->lot)));
-    guid_free (invoice);
-    guid_free (invoice_r);
-    guid_free (owner);
-    guid_free (owner_r);
-}
-
-static void
-test_customer_kvp_properties (Fixture *fixture, gconstpointer pData)
-{
-    gchar *pdf_dir = "/foo/bar/baz";
-    gchar *pdf_dir_r;
-    GncGUID *inv_acct = guid_malloc ();
-    GncGUID *pmt_acct = guid_malloc ();
-    GncGUID *inv_acct_r, *pmt_acct_r;
-
-    qof_begin_edit (QOF_INSTANCE (fixture->cust));
-    qof_instance_set (QOF_INSTANCE (fixture->cust),
-		      "export-pdf-dir", pdf_dir,
-		      "invoice-last-posted-account", inv_acct,
-		      "payment-last-account", pmt_acct,
-		      NULL);
-
-    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->cust)));
-    qof_instance_mark_clean (QOF_INSTANCE (fixture->cust));
-
-    qof_instance_get (QOF_INSTANCE (fixture->cust),
-		      "export-pdf-dir", &pdf_dir_r,
-		      "invoice-last-posted-account", &inv_acct_r,
-		      "payment-last-account", &pmt_acct_r,
-		      NULL);
-
-    g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
-    g_assert (guid_equal (inv_acct, inv_acct_r));
-    g_assert (guid_equal (pmt_acct, pmt_acct_r));
-    guid_free (inv_acct);
-    guid_free (inv_acct_r);
-    guid_free (pmt_acct);
-    guid_free (pmt_acct_r);
-    g_free (pdf_dir_r);
-
-}
-
-static void
-test_employee_kvp_properties (Fixture *fixture, gconstpointer pData)
-{
-    gchar *pdf_dir = "/foo/bar/baz";
-    gchar *pdf_dir_r;
-    GncGUID *inv_acct = guid_malloc ();
-    GncGUID *pmt_acct = guid_malloc ();
-    GncGUID *inv_acct_r, *pmt_acct_r;
-
-    qof_begin_edit (QOF_INSTANCE (fixture->emp));
-    qof_instance_set (QOF_INSTANCE (fixture->emp),
-		      "export-pdf-dir", pdf_dir,
-		      "invoice-last-posted-account", inv_acct,
-		      "payment-last-account", pmt_acct,
-		      NULL);
-
-    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->emp)));
-    qof_instance_mark_clean (QOF_INSTANCE (fixture->emp));
-
-    qof_instance_get (QOF_INSTANCE (fixture->emp),
-		      "export-pdf-dir", &pdf_dir_r,
-		      "invoice-last-posted-account", &inv_acct_r,
-		      "payment-last-account", &pmt_acct_r,
-		      NULL);
-
-    g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
-    g_assert (guid_equal (inv_acct, inv_acct_r));
-    g_assert (guid_equal (pmt_acct, pmt_acct_r));
-    guid_free (inv_acct);
-    guid_free (inv_acct_r);
-    guid_free (pmt_acct);
-    guid_free (pmt_acct_r);
-    g_free (pdf_dir_r);
-
-}
-
-static void
-test_job_kvp_properties (Fixture *fixture, gconstpointer pData)
-{
-    gchar *pdf_dir = "/foo/bar/baz";
-    gchar *pdf_dir_r;
-
-    qof_begin_edit (QOF_INSTANCE (fixture->job));
-    qof_instance_set (QOF_INSTANCE (fixture->job),
-		      "export-pdf-dir", pdf_dir,
-		      NULL);
-
-    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->job)));
-    qof_instance_mark_clean (QOF_INSTANCE (fixture->job));
-
-    qof_instance_get (QOF_INSTANCE (fixture->job),
-		      "export-pdf-dir", &pdf_dir_r,
-		      NULL);
-
-    g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
-    g_free (pdf_dir_r);
-
-}
-
-static void
-test_vendor_kvp_properties (Fixture *fixture, gconstpointer pData)
-{
-    gchar *pdf_dir = "/foo/bar/baz";
-    gchar *pdf_dir_r;
-    GncGUID *inv_acct = guid_malloc ();
-    GncGUID *pmt_acct = guid_malloc ();
-    GncGUID *inv_acct_r, *pmt_acct_r;
-
-    qof_begin_edit (QOF_INSTANCE (fixture->vend));
-    qof_instance_set (QOF_INSTANCE (fixture->vend),
-		      "export-pdf-dir", pdf_dir,
-		      "invoice-last-posted-account", inv_acct,
-		      "payment-last-account", pmt_acct,
-		      NULL);
-
-    g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->vend)));
-    qof_instance_mark_clean (QOF_INSTANCE (fixture->vend));
-
-    qof_instance_get (QOF_INSTANCE (fixture->vend),
-		      "export-pdf-dir", &pdf_dir_r,
-		      "invoice-last-posted-account", &inv_acct_r,
-		      "payment-last-account", &pmt_acct_r,
-		      NULL);
-
-    g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
-    g_assert (guid_equal (inv_acct, inv_acct_r));
-    g_assert (guid_equal (pmt_acct, pmt_acct_r));
-    guid_free (inv_acct);
-    guid_free (inv_acct_r);
-    guid_free (pmt_acct);
-    guid_free (pmt_acct_r);
-    g_free (pdf_dir_r);
-
-}
-
-void test_suite_engine_kvp_properties (void)
-{
-    GNC_TEST_ADD (suitename, "Account", Fixture, NULL, setup_account, test_account_kvp_properties, teardown);
-    GNC_TEST_ADD (suitename, "Transaction", Fixture, NULL, setup_trans, test_trans_kvp_properties, teardown);
-    GNC_TEST_ADD (suitename, "Split", Fixture, NULL, setup_split, test_split_kvp_properties, teardown);
-    GNC_TEST_ADD (suitename, "Lot", Fixture, NULL, setup_lot, test_lot_kvp_properties, teardown);
-    GNC_TEST_ADD (suitename, "Customer", Fixture, NULL, setup_customer, test_customer_kvp_properties, teardown);
-    GNC_TEST_ADD (suitename, "Employee", Fixture, NULL, setup_employee, test_employee_kvp_properties, teardown);
-    GNC_TEST_ADD (suitename, "Job", Fixture, NULL, setup_job, test_job_kvp_properties, teardown);
-    GNC_TEST_ADD (suitename, "Vendor", Fixture, NULL, setup_vendor, test_vendor_kvp_properties, teardown);
-}
diff --git a/src/engine/test/test-engine.c b/src/engine/test/test-engine.c
index 19221b8..508856e 100644
--- a/src/engine/test/test-engine.c
+++ b/src/engine/test/test-engine.c
@@ -31,7 +31,6 @@ extern void test_suite_budget();
 extern void test_suite_gncInvoice();
 extern void test_suite_transaction();
 extern void test_suite_split();
-extern void test_suite_engine_kvp_properties (void);
 
 int
 main (int   argc,
@@ -50,7 +49,6 @@ main (int   argc,
     test_suite_gncInvoice();
     test_suite_transaction();
     test_suite_split();
-    test_suite_engine_kvp_properties ();
 
     return g_test_run( );
 }
diff --git a/src/engine/test/test-job.c b/src/engine/test/test-job.c
index 9791b4f..b90950a 100644
--- a/src/engine/test/test-job.c
+++ b/src/engine/test/test-job.c
@@ -24,11 +24,9 @@
  *
  *********************************************************************/
 
-#include <config.h>
+#include "config.h"
 #include <glib.h>
-#include <qof.h>
-#include <qofinstance-p.h>
-
+#include "qof.h"
 #include "gncJobP.h"
 #include "gncInvoiceP.h"
 #include "gncCustomerP.h"
diff --git a/src/engine/test/test-vendor.c b/src/engine/test/test-vendor.c
index c36ff72..65adf3e 100644
--- a/src/engine/test/test-vendor.c
+++ b/src/engine/test/test-vendor.c
@@ -24,10 +24,8 @@
  *
  *********************************************************************/
 
-#include <config.h>
+#include "config.h"
 #include <glib.h>
-#include <qofinstance-p.h>
-
 #include "gncInvoiceP.h"
 #include "gncCustomerP.h"
 #include "gncJobP.h"
diff --git a/src/engine/test/utest-Account.c b/src/engine/test/utest-Account.c
index f96abf3..2a8fe33 100644
--- a/src/engine/test/utest-Account.c
+++ b/src/engine/test/utest-Account.c
@@ -25,7 +25,6 @@
 #include <unittest-support.h>
 #include <gnc-event.h>
 #include <gnc-gdate-utils.h>
-#include <qofinstance-p.h>
 /* Add specific headers for this class */
 #include "../Account.h"
 #include "../AccountP.h"
@@ -445,11 +444,11 @@ test_gnc_account_name_violations_errmsg ()
     message = gnc_account_name_violations_errmsg (separator, nonames);
     g_assert (message == NULL);
     validation_message = g_strdup_printf (
-        "The separator character \"%s\" is used in one or more account "
-        "names.\n\nThis will result in unexpected behaviour. "
-        "Either change the account names or choose another separator "
-        "character.\n\nBelow you will find the list of invalid account names:\n"
-        "%s", separator, account_list);
+                             "The separator character \"%s\" is used in one or more account "
+                             "names.\n\nThis will result in unexpected behaviour. "
+                             "Either change the account names or choose another separator "
+                             "character.\n\nBelow you will find the list of invalid account names:\n"
+                             "%s", separator, account_list);
     message = gnc_account_name_violations_errmsg (separator, badnames);
     g_assert_cmpstr ( message, == , validation_message);
     g_free (validation_message);
@@ -1357,8 +1356,6 @@ test_xaccAccountOrder ( )
     g_assert (xaccAccountOrder (ab, aa) == 1);
 
     ab = xaccMallocAccount (book);
-    qof_instance_increase_editlevel (aa);
-    qof_instance_increase_editlevel (ab);
     g_object_set (G_OBJECT (aa),
                   "code", "3333",
                   "type", ACCT_TYPE_ASSET,
@@ -1401,8 +1398,6 @@ test_xaccAccountOrder ( )
                   "name", "bar",
                   NULL);
     g_assert_cmpint (xaccAccountOrder (aa, ab), < , 0);
-    qof_instance_decrease_editlevel (aa);
-    qof_instance_decrease_editlevel (ab);
 
     xaccAccountBeginEdit (aa);
     xaccAccountDestroy (aa);
@@ -2162,9 +2157,7 @@ test_xaccAccountType_Stuff (void)
             g_assert_cmpstr (typestr_uc, == , typename);
         g_free (typestr_uc);
 
-	qof_instance_increase_editlevel (acc);
         g_object_set (acc, "type", type, NULL);
-	qof_instance_decrease_editlevel (acc);
         if (type == ACCT_TYPE_STOCK || type == ACCT_TYPE_MUTUAL ||
                 type == ACCT_TYPE_CURRENCY)
             g_assert (xaccAccountIsPriced (acc));
@@ -2408,13 +2401,11 @@ test_gnc_account_merge_children (Fixture *fixture, gconstpointer pData)
     */
     sig4 = test_signal_new (QOF_INSTANCE (div), QOF_EVENT_MODIFY, NULL);
     sig5 = test_signal_new (QOF_INSTANCE (div1), QOF_EVENT_MODIFY, NULL);
-    qof_instance_increase_editlevel (div1);
     g_object_set (div1, "name", "div", NULL);
-    qof_instance_decrease_editlevel (div1);
     gnc_account_merge_children (taxable);
     g_assert_cmpint (gnc_account_n_descendants (taxable), == , taxable_desc - 1);
     test_signal_assert_hits (sig4, 1);
-    test_signal_assert_hits (sig5, 3);
+    test_signal_assert_hits (sig5, 4);
     test_signal_free (sig4);
     test_signal_free (sig5);
     gnc_account_merge_children (expense);
diff --git a/src/engine/test/utest-Split.cpp b/src/engine/test/utest-Split.cpp
index e4165e5..17f062c 100644
--- a/src/engine/test/utest-Split.cpp
+++ b/src/engine/test/utest-Split.cpp
@@ -38,7 +38,7 @@ extern "C"
 #include <TransactionP.h>
 #include <gnc-lot.h>
 #include <gnc-event.h>
-#include <qofinstance-p.h>
+#include <qofbookslots.h>
 
 #ifdef HAVE_GLIB_2_38
 #define _Q "'"
@@ -318,15 +318,15 @@ test_xaccDupeSplit (Fixture *fixture, gconstpointer pData)
     g_assert (split->gains_split != f_split->gains_split);
 
 }
-/* xaccSplitCloneNoKvp
+/* xaccSplitClone
 Split *
-xaccSplitCloneNoKvp (const Split *s)// C: 1 
+xaccSplitClone (const Split *s)// C: 1
 */
 static void
-test_xaccSplitCloneNoKvp (Fixture *fixture, gconstpointer pData)
+test_xaccSplitClone (Fixture *fixture, gconstpointer pData)
 {
     Split *f_split = fixture->split;
-    Split *split = xaccSplitCloneNoKvp (f_split);
+    Split *split = xaccSplitClone (f_split);
 
     g_assert (split != fixture->split);
     g_assert (qof_instance_get_guid (split) != qof_instance_get_guid (f_split));
@@ -339,7 +339,7 @@ test_xaccSplitCloneNoKvp (Fixture *fixture, gconstpointer pData)
     g_assert (split->lot == f_split->lot);
     g_assert_cmpstr (split->memo, ==, f_split->memo);
     g_assert_cmpstr (split->action, ==, f_split->action);
-    g_assert (kvp_frame_is_empty (split->inst.kvp_data));
+    g_assert (kvp_frame_compare (split->inst.kvp_data, f_split->inst.kvp_data) == 0);
     g_assert_cmpint (split->reconciled, ==, f_split->reconciled);
     g_assert (timespec_equal (&(split->date_reconciled), &(f_split->date_reconciled)));
     g_assert (gnc_numeric_equal (split->value, f_split->value));
@@ -417,7 +417,7 @@ xaccSplitEqual(const Split *sa, const Split *sb,// C: 2 in 2 SCM: 1
 static void
 test_xaccSplitEqual (Fixture *fixture, gconstpointer pData)
 {
-    Split *split1 = xaccSplitCloneNoKvp (fixture->split);
+    Split *split1 = xaccSplitClone (fixture->split);
     Split *split2 = xaccDupeSplit (fixture->split);
     gchar *msg01 = "[xaccSplitEqual] one is NULL";
     gchar *msg02 = "[xaccSplitEqual] GUIDs differ";
@@ -468,11 +468,9 @@ test_xaccSplitEqual (Fixture *fixture, gconstpointer pData)
     split1->parent = fixture->split->parent;
     g_assert (xaccSplitEqual (fixture->split, split1, FALSE, TRUE, TRUE) == TRUE);
     /* Now set the GUIDs equal and see that the comparison passes */
-    qof_instance_increase_editlevel (split1->parent);
     g_object_set (G_OBJECT (split1),
                   "guid", qof_instance_get_guid (QOF_INSTANCE(fixture->split)),
                   NULL);
-    qof_instance_increase_editlevel (split1->parent);
     g_assert (xaccSplitEqual (fixture->split, split1, TRUE, TRUE, TRUE) == TRUE);
     g_assert_cmpint (checkA.hits, ==, 3);
     g_assert_cmpint (checkB.hits, ==, 1);
@@ -609,12 +607,10 @@ test_xaccSplitCommitEdit (Fixture *fixture, gconstpointer pData)
     g_assert_cmpint (checkB.hits, ==, 2);
 
     qof_instance_mark_clean (QOF_INSTANCE (fixture->split->parent));
-    qof_instance_increase_editlevel (fixture->split->acc);
     g_object_set (fixture->split->acc,
                   "sort-dirty", FALSE,
                   "balance-dirty", FALSE,
                   NULL);
-    qof_instance_decrease_editlevel (fixture->split->acc);
 
     qof_instance_set_dirty (QOF_INSTANCE (fixture->split));
     xaccSplitCommitEdit (fixture->split);
@@ -784,6 +780,16 @@ test_get_commodity_denom (Fixture *fixture, gconstpointer pData)
     fixture->split->acc = acc;
     g_assert_cmpint (fixture->func->get_commodity_denom (fixture->split), ==, denom);
 }
+/* xaccSplitGetSlots
+KvpFrame *
+xaccSplitGetSlots (const Split * s)// C: 17 in 8
+Simple passthrough, no test.
+*/
+// Not Used
+/* xaccSplitSetSlots_nc
+void
+xaccSplitSetSlots_nc(Split *s, KvpFrame *frm)//
+*/
 /* xaccSplitSetSharePriceAndAmount
 void
 xaccSplitSetSharePriceAndAmount (Split *s, gnc_numeric price, gnc_numeric amt)// C: 1
@@ -1109,9 +1115,8 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
 {
     const char *slot_path;
     Split *split = fixture->split;
-    QofBook *book = xaccSplitGetBook (split);
-    Split *o_split = xaccMallocSplit (book);
-    Transaction *o_txn = xaccMallocTransaction (book);
+    Split *o_split = xaccMallocSplit (xaccSplitGetBook (split));
+    Transaction *o_txn = xaccMallocTransaction (xaccSplitGetBook (split));
     Transaction *txn = split->parent;
 
     g_assert_cmpint (xaccSplitOrder (split, split), ==, 0);
@@ -1150,12 +1155,11 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
      */
 
     /* create correct slot path */
+    slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/",
+                                            OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_NUM_FIELD_SOURCE, NULL );
+    g_assert( slot_path != NULL );
     g_test_message( "Testing with use-split-action-for-num set to true - t" );
-    qof_book_begin_edit (book);
-    qof_instance_set (QOF_INSTANCE (book),
-		      "split-action-num-field", "t",
-		      NULL);
-    qof_book_commit_edit (book);
+    qof_book_set_string_option( xaccSplitGetBook (split), slot_path, "t" );
     g_assert(qof_book_use_split_action_for_num_field(xaccSplitGetBook(split)) == TRUE);
 
     g_assert_cmpint (xaccSplitOrder (split, o_split), ==, -1);
@@ -1167,11 +1171,7 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
     o_split->action = NULL;
     split->action = "foo";
     o_split->parent = NULL;
-    qof_book_begin_edit (book);
-    qof_instance_set (QOF_INSTANCE (book),
-		      "split-action-num-field", "f",
-		      NULL);
-    qof_book_commit_edit (book);
+    qof_book_set_string_option( xaccSplitGetBook (split), slot_path, "f" );
     g_assert(qof_book_use_split_action_for_num_field(xaccSplitGetBook(split)) == FALSE);
     split->parent = NULL;
     /* This should return > 0 because o_split has no memo string */
@@ -1772,6 +1772,7 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
     Split *split2 = xaccMallocSplit (book);
     Account *acc2 = xaccMallocAccount (book);
     KvpValue *kvptrue = kvp_value_new_string ("t");
+    KvpFrame *book_slots = qof_book_get_slots (book);
 
     g_assert (xaccSplitGetOtherSplit (NULL) == NULL);
     g_assert (xaccSplitGetOtherSplit (split1) == NULL);
@@ -1800,11 +1801,9 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
     g_assert (kvp_frame_get_slot (split->inst.kvp_data, "lot-split") == NULL);
     kvp_frame_set_slot (split1->inst.kvp_data, "lot-split", NULL);
     g_assert (kvp_frame_get_slot (split1->inst.kvp_data, "lot-split") == NULL);
-    qof_book_begin_edit (book);
-    qof_instance_set (QOF_INSTANCE (book),
-		      "trading-accts", "t",
-		      NULL);
-    qof_book_commit_edit (book);
+    kvp_frame_set_slot_path (book_slots, kvptrue, KVP_OPTION_PATH,
+                             OPTION_SECTION_ACCOUNTS,
+                             OPTION_NAME_TRADING_ACCOUNTS, NULL);
     g_assert (xaccTransUseTradingAccounts (txn));
     g_assert (xaccSplitGetOtherSplit (split) == NULL);
     split2->acc = acc2;
@@ -1883,7 +1882,7 @@ test_suite_split (void)
     GNC_TEST_ADD_FUNC (suitename, "gnc split set & get property", test_gnc_split_set_get_property);
     GNC_TEST_ADD (suitename, "xaccMallocSplit", Fixture, NULL, setup, test_xaccMallocSplit, teardown);
     GNC_TEST_ADD (suitename, "xaccDupeSplit", Fixture, NULL, setup, test_xaccDupeSplit, teardown);
-    GNC_TEST_ADD (suitename, "xaccSplitCloneNoKvp", Fixture, NULL, setup, test_xaccSplitCloneNoKvp, teardown);
+    GNC_TEST_ADD (suitename, "xaccSplitClone", Fixture, NULL, setup, test_xaccSplitClone, teardown);
     GNC_TEST_ADD (suitename, "mark split", Fixture, NULL, setup, test_mark_split, teardown);
     GNC_TEST_ADD (suitename, "xaccSplitEqualCheckBal", Fixture, NULL, setup, test_xaccSplitEqualCheckBal, teardown);
     GNC_TEST_ADD (suitename, "xaccSplitEqual", Fixture, NULL, setup, test_xaccSplitEqual, teardown);
diff --git a/src/engine/test/utest-Transaction.c b/src/engine/test/utest-Transaction.c
index c2a963f..35330a4 100644
--- a/src/engine/test/utest-Transaction.c
+++ b/src/engine/test/utest-Transaction.c
@@ -1,5 +1,5 @@
 /********************************************************************
- * utest-Transaction.c: GLib g_test test suite for Transaction.c.   *
+ * utest-Transaction.c: GLib g_test test suite for Transaction.c.		    *
  * Copyright 2012 John Ralls <jralls at ceridwen.us>		    *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
@@ -33,6 +33,7 @@
 #include "../gnc-lot.h"
 #include "../gnc-event.h"
 #include <qof.h>
+#include <qofbookslots.h>
 #include <qofbackend-p.h>
 
 #ifdef HAVE_GLIB_2_38
@@ -568,12 +569,12 @@ test_xaccTransSortSplits (Fixture *fixture, gconstpointer pData)
 
     xaccTransCommitEdit (txn);
 }
-/* dupe_trans
-static Transaction *
-dupe_trans (const Transaction *from)// Local: 1:0:0
+/* xaccDupeTransaction
+Transaction *
+xaccDupeTransaction (const Transaction *from)// Local: 1:0:0
 */
 static void
-test_dupe_trans (Fixture *fixture, gconstpointer pData)
+test_xaccDupeTransaction (Fixture *fixture, gconstpointer pData)
 {
     Timespec posted = gnc_dmy2timespec (12, 7, 2011);
     Timespec entered = gnc_dmy2timespec (14, 7, 2011);
@@ -586,7 +587,7 @@ test_dupe_trans (Fixture *fixture, gconstpointer pData)
     kvp_frame_set_string (old->inst.kvp_data, "/foo/bar/baz",
                           "The Great Waldo Pepper");
 
-    new = fixture->func->dupe_trans (old);
+    new = xaccDupeTransaction (old);
 
     g_assert_cmpstr (new->num, ==, old->num);
     g_assert_cmpstr (new->description, ==, old->description);
@@ -1047,14 +1048,14 @@ test_xaccTransGetImbalance_trading (Fixture *fixture,
     Account *acc1 = xaccMallocAccount (book);
     Account *acc2 = xaccMallocAccount (book);
     gnc_numeric value;
+    gchar *trading_account_path = g_strdup_printf("%s/%s/%s", KVP_OPTION_PATH,
+                                  OPTION_SECTION_ACCOUNTS,
+                                  OPTION_NAME_TRADING_ACCOUNTS);
     MonetaryList *mlist;
-    qof_book_begin_edit (book);
-    qof_instance_set (QOF_INSTANCE (book),
-		      "trading-accts", "t",
-		      NULL);
-    qof_book_commit_edit (book);
 
- /* Without trading splits, the list is unbalanced */
+    qof_book_set_string_option( book, trading_account_path, "t" );
+    g_free (trading_account_path);
+    /* Without trading splits, the list is unbalanced */
     mlist = xaccTransGetImbalance (fixture->txn);
     g_assert_cmpint (g_list_length (mlist), ==, 2);
     gnc_monetary_list_free (mlist);
@@ -1134,13 +1135,12 @@ test_xaccTransIsBalanced_trading (Fixture *fixture, gconstpointer pData)
     Split *split2 = xaccMallocSplit (book);
     Account *acc1 = xaccMallocAccount (book);
     Account *acc2 = xaccMallocAccount (book);
+    gchar *trading_account_path = g_strdup_printf("%s/%s/%s", KVP_OPTION_PATH,
+                                  OPTION_SECTION_ACCOUNTS,
+                                  OPTION_NAME_TRADING_ACCOUNTS);
 
-    qof_book_begin_edit (book);
-    qof_instance_set (QOF_INSTANCE (book),
-		      "trading-accts", "t",
-		      NULL);
-    qof_book_commit_edit (book);
-
+    qof_book_set_string_option( book, trading_account_path, "t" );
+    g_free (trading_account_path);
     xaccAccountSetCommodity (acc1, fixture->curr);
     xaccAccountSetCommodity (acc2, fixture->comm);
     xaccAccountSetType (acc1, ACCT_TYPE_TRADING);
@@ -1398,27 +1398,29 @@ void
 xaccTransDestroy (Transaction *trans)// C: 26 in 15 SCM: 4 in 4 Local: 3:0:0
 */
 static void
-test_xaccTransDestroy (Fixture *fixture, gconstpointer pData)
+test_xaccTransDestroy ()
 {
-    Transaction *txn = fixture->txn;
-    QofBook *book = qof_instance_get_book (QOF_INSTANCE (txn));
-    Transaction *dupe = xaccTransClone (txn);
+    QofBook *book = qof_book_new ();
+    Transaction *txn = xaccMallocTransaction (book);
+    Transaction *dupe = xaccDupeTransaction (txn);
 
     xaccTransBeginEdit (txn);
     g_assert (!qof_instance_get_destroying (QOF_INSTANCE (txn)));
-    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
+    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
     xaccTransDestroy (txn);
     g_assert (qof_instance_get_destroying (QOF_INSTANCE (txn)));
-    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
+    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
     xaccTransRollbackEdit (txn);
     qof_book_mark_readonly (book);
     xaccTransBeginEdit (txn);
     xaccTransDestroy (txn);
     g_assert (qof_instance_get_destroying (QOF_INSTANCE (txn)));
-    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
+    g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
     xaccTransRollbackEdit (txn);
 
+    test_destroy (txn);
     test_destroy (dupe);
+    test_destroy (book);
 }
 /* destroy_gains
 static void
@@ -1643,6 +1645,10 @@ test_xaccTransCommitEdit (void)
         xaccTransSetCurrency (txn, curr);
         xaccSplitSetParent (split1, txn);
         xaccSplitSetParent (split2, txn);
+        /* xaccTransCommitEdit doesn't do anything with kvp
+        kvp_frame_set_double (frame, "/qux/quux/corge", 123.456);
+         qof_instance_set_slots (QOF_INSTANCE (txn), frame);
+         */
     }
     /* Setup's done, now test: */
     xaccTransCommitEdit (txn);
@@ -1784,7 +1790,7 @@ static void
 test_xaccTransOrder_num_action (Fixture *fixture, gconstpointer pData)
 {
     Transaction *txnA = fixture->txn;
-    Transaction *txnB = fixture->func->dupe_trans (txnA);
+    Transaction *txnB = xaccDupeTransaction (txnA);
 
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, NULL, NULL), ==, -1);
     g_assert_cmpint (xaccTransOrder_num_action (NULL, NULL, txnA, NULL), ==, 1);
@@ -2036,7 +2042,7 @@ test_suite_transaction (void)
     GNC_TEST_ADD (suitename, "gnc transaction set/get property", Fixture, NULL, setup, test_gnc_transaction_set_get_property, teardown);
     GNC_TEST_ADD (suitename, "xaccMallocTransaction", Fixture, NULL, setup, test_xaccMallocTransaction, teardown);
     GNC_TEST_ADD (suitename, "xaccTransSortSplits", Fixture, NULL, setup, test_xaccTransSortSplits, teardown);
-    GNC_TEST_ADD (suitename, "dupe_trans", Fixture, NULL, setup, test_dupe_trans, teardown);
+    GNC_TEST_ADD (suitename, "xaccDupeTransaction", Fixture, NULL, setup, test_xaccDupeTransaction, teardown);
     GNC_TEST_ADD (suitename, "xaccTransClone", Fixture, NULL, setup, test_xaccTransClone, teardown);
     GNC_TEST_ADD (suitename, "xaccTransCopyFromClipBoard", Fixture, NULL, setup, test_xaccTransCopyFromClipBoard, teardown);
     GNC_TEST_ADD (suitename, "xaccTransCopyFromClipBoard No-Start", Fixture, NULL, setup, test_xaccTransCopyFromClipBoard_no_start, teardown);
@@ -2057,7 +2063,7 @@ test_suite_transaction (void)
 
     GNC_TEST_ADD (suitename, "xaccTransSetCurrency", Fixture, NULL, setup, test_xaccTransSetCurrency, teardown);
     GNC_TEST_ADD_FUNC (suitename, "xaccTransBeginEdit", test_xaccTransBeginEdit);
-    GNC_TEST_ADD (suitename, "xaccTransDestroy", Fixture, NULL, setup, test_xaccTransDestroy, teardown);
+    GNC_TEST_ADD_FUNC (suitename, "xaccTransDestroy", test_xaccTransDestroy);
     GNC_TEST_ADD (suitename, "destroy gains", GainsFixture, NULL, setup_with_gains, test_destroy_gains, teardown_with_gains);
     GNC_TEST_ADD (suitename, "do destroy", GainsFixture, NULL, setup_with_gains, test_do_destroy, teardown_with_gains);
     GNC_TEST_ADD (suitename, "was trans emptied", Fixture, NULL, setup, test_was_trans_emptied, teardown);
diff --git a/src/gnome-utils/dialog-preferences.c b/src/gnome-utils/dialog-preferences.c
index 4e371be..53f2e94 100644
--- a/src/gnome-utils/dialog-preferences.c
+++ b/src/gnome-utils/dialog-preferences.c
@@ -1054,7 +1054,7 @@ gnc_preferences_dialog_create(void)
     GtkWidget *dialog, *notebook, *label, *image;
     GtkWidget *box, *date, *period, *currency;
     GHashTable *prefs_table;
-    GDate* gdate = NULL;
+    GDate* gdate;
     gchar buf[128];
     GtkListStore *store;
     GtkTreePath *path;
@@ -1120,10 +1120,16 @@ gnc_preferences_dialog_create(void)
 
 
     book = gnc_get_current_book();
-    g_date_clear (&fy_end, 1);
-    qof_instance_get (QOF_INSTANCE (book),
-		      "fy-end", &fy_end,
-		      NULL);
+    book_frame = qof_book_get_slots(book);
+    month = kvp_frame_get_gint64(book_frame, "/book/fyear_end/month");
+    day = kvp_frame_get_gint64(book_frame, "/book/fyear_end/day");
+    date_is_valid = g_date_valid_dmy(day, month, 2005 /* not leap year */);
+    if (date_is_valid)
+    {
+        g_date_clear(&fy_end, 1);
+        g_date_set_dmy(&fy_end, day, month, G_DATE_BAD_YEAR);
+    }
+
     box = GTK_WIDGET(gtk_builder_get_object (builder,
                      "pref/" GNC_PREFS_GROUP_ACCT_SUMMARY "/" GNC_PREF_START_PERIOD));
     period = gnc_period_select_new(TRUE);
diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c
index 923c877..4ab4257 100644
--- a/src/gnome-utils/gnc-main-window.c
+++ b/src/gnome-utils/gnc-main-window.c
@@ -3973,21 +3973,20 @@ gnc_book_options_dialog_apply_cb(GNCOptionWin * optionwin,
                                  gpointer user_data)
 {
     GNCOptionDB * options = user_data;
+    kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
     gboolean use_split_action_for_num_before =
         qof_book_use_split_action_for_num_field (gnc_get_current_book ());
     gboolean use_split_action_for_num_after;
-    QofBook *book = gnc_get_current_book ();
 
     if (!options) return;
 
     gnc_option_db_commit (options);
-    qof_book_begin_edit (book);
-    qof_book_save_options (book, gnc_option_db_save_to_kvp, options, TRUE);
+    gnc_option_db_save_to_kvp (options, slots, TRUE);
+    qof_book_kvp_changed (gnc_get_current_book());
     use_split_action_for_num_after =
         qof_book_use_split_action_for_num_field (gnc_get_current_book ());
     if (use_split_action_for_num_before != use_split_action_for_num_after)
         gnc_book_option_num_field_source_change_cb (use_split_action_for_num_after);
-    qof_book_commit_edit (book);
 }
 
 static void
@@ -4003,12 +4002,12 @@ gnc_book_options_dialog_close_cb(GNCOptionWin * optionwin,
 GtkWidget *
 gnc_book_options_dialog_cb (gboolean modal, gchar *title)
 {
-    QofBook *book = gnc_get_current_book ();
+    kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
     GNCOptionDB *options;
     GNCOptionWin *optionwin;
 
     options = gnc_option_db_new_for_type (QOF_ID_BOOK);
-    qof_book_load_options (book, gnc_option_db_load_from_kvp, options);
+    gnc_option_db_load_from_kvp (options, slots);
     gnc_option_db_clean (options);
 
     optionwin = gnc_options_dialog_new_modal (modal,
diff --git a/src/gnome-utils/gnc-tree-util-split-reg.c b/src/gnome-utils/gnc-tree-util-split-reg.c
index d6e5747..88c4ee3 100644
--- a/src/gnome-utils/gnc-tree-util-split-reg.c
+++ b/src/gnome-utils/gnc-tree-util-split-reg.c
@@ -397,20 +397,30 @@ const char *
 gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
 {
     static char *name = NULL;
-    Account *account;
-    GncGUID *guid = NULL;
 
-    /* Callers either g_strdup the return or use it as a temp for comparison,
-       so we keep our static ref and free it on every call. */
-    g_free (name);
+    kvp_frame *kvpf;
 
     if (!split)
         return NULL;
-    qof_instance_get (QOF_INSTANCE (split),
-		      "sx-account", &guid,
-		      NULL);
-    account = xaccAccountLookup (guid, gnc_get_current_book ());
-    name = account ? gnc_get_account_name_for_register (account) : NULL;
+
+    kvpf = xaccSplitGetSlots (split);
+
+    g_free (name);
+
+    if (kvpf)
+    {
+        Account *account;
+        GncGUID *guid;
+
+        guid = kvp_value_get_guid(
+                   kvp_frame_get_slot_path (kvpf, "sched-xaction", "account", NULL));
+
+        account = xaccAccountLookup (guid, gnc_get_current_book ());
+
+        name = account ? gnc_get_account_name_for_register (account) : NULL;
+    }
+    else
+        name = NULL;
 
     return name;
 }
@@ -419,27 +429,20 @@ gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
 const char *
 gnc_tree_util_split_reg_template_get_fdebt_entry (Split *split)
 {
-    gchar *formula = NULL;
+    kvp_frame *kvpf = xaccSplitGetSlots (split);
 
-    g_return_val_if_fail (split != NULL, NULL);
-    qof_instance_get (QOF_INSTANCE (split),
-		      "sx-debit-formula", &formula,
-		      NULL);
-
-    return formula;
+    return kvp_value_get_string(
+               kvp_frame_get_slot_path (kvpf, "sched-xaction", "debit-formula", NULL));
 }
 
+
 const char *
 gnc_tree_util_split_reg_template_get_fcred_entry (Split *split)
 {
-    gchar *formula = NULL;
-
-    g_return_val_if_fail (split != NULL, NULL);
-    qof_instance_get (QOF_INSTANCE (split),
-		      "sx-credit-formula", &formula,
-		      NULL);
+    kvp_frame *kvpf = xaccSplitGetSlots (split);
 
-    return formula;
+    return kvp_value_get_string(
+               kvp_frame_get_slot_path (kvpf, "sched-xaction", "credit-formula", NULL));
 }
 
 
diff --git a/src/gnome-utils/gnc-tree-view-account.c b/src/gnome-utils/gnc-tree-view-account.c
index bde9de5..d1912e5 100644
--- a/src/gnome-utils/gnc-tree-view-account.c
+++ b/src/gnome-utils/gnc-tree-view-account.c
@@ -1730,44 +1730,43 @@ gtva_currency_changed_cb (void)
         gtva_update_column_names (ptr->data);
     }
 }
-/* Retrieve a specified account string property and put the result
- * into the tree column's text property.
- */
+/* This function implements a custom mapping between an account's KVP
+ * and the cell renderer's 'text' property. */
 static void
-account_cell_property_data_func (GtkTreeViewColumn *tree_column,
-				 GtkCellRenderer *cell,
-				 GtkTreeModel *s_model,
-				 GtkTreeIter *s_iter,
-				 gpointer key)
+account_cell_kvp_data_func (GtkTreeViewColumn *tree_column,
+                            GtkCellRenderer *cell,
+                            GtkTreeModel *s_model,
+                            GtkTreeIter *s_iter,
+                            gpointer key)
 {
     Account *account;
-    gchar *string = NULL;
+    kvp_frame * frame;
 
     g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model));
     account = gnc_tree_view_account_get_account_from_iter(s_model, s_iter);
-    qof_instance_get (QOF_INSTANCE (account),
-		      key, &string,
-		      NULL);
-    if (string == NULL)
-	string = "";
+    frame = xaccAccountGetSlots(account);
+
+    g_object_set (G_OBJECT (cell),
+                  "text", kvp_frame_get_string(frame, (gchar *)key),
+                  "xalign", 0.0,
+                  NULL);
 
-    g_object_set (G_OBJECT (cell), "text", string, "xalign", 0.0, NULL);
 }
 
 
 GtkTreeViewColumn *
-gnc_tree_view_account_add_property_column (GncTreeViewAccount *view,
+gnc_tree_view_account_add_kvp_column (GncTreeViewAccount *view,
                                       const gchar *column_title,
-                                      const gchar *propname)
+                                      const gchar *kvp_key)
 {
     GtkCellRenderer *renderer;
     GtkTreeViewColumn *column;
 
     g_return_val_if_fail (GNC_IS_TREE_VIEW_ACCOUNT (view), NULL);
-    g_return_val_if_fail (propname != NULL, NULL);
+    g_return_val_if_fail (kvp_key != NULL, NULL);
 
     column = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), column_title,
-                                           propname, NULL, "Sample text",
+                                           kvp_key, NULL, "Sample text",
                                            -1, -1, NULL);
 
     /* This new kvp column has only had one renderer added to it so
@@ -1776,8 +1775,8 @@ gnc_tree_view_account_add_property_column (GncTreeViewAccount *view,
     g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
 
     gtk_tree_view_column_set_cell_data_func (column, renderer,
-            account_cell_property_data_func,
-            g_strdup(propname), g_free);
+            account_cell_kvp_data_func,
+            g_strdup(kvp_key), g_free);
     return column;
 }
 
diff --git a/src/gnome-utils/gnc-tree-view-account.h b/src/gnome-utils/gnc-tree-view-account.h
index 5088b75..87778cd 100644
--- a/src/gnome-utils/gnc-tree-view-account.h
+++ b/src/gnome-utils/gnc-tree-view-account.h
@@ -203,19 +203,20 @@ void gnc_tree_view_account_notes_edited_cb(Account *account, GtkTreeViewColumn *
 
 /** Add a new column to the set of columns in an account tree view.
  *  This column will be visible as soon as it is added and will
- *  display the contents of the specified account property
+ *  display the contents of the specified KVP slot.
  *
  *  @param view A pointer to an account tree view.
  *
  *  @param column_title The title for this new column.
  *
- *  @param propname The g_object_property name of the desired
- *  value. This must be a string property.
+ *  @param kvp_key The lookup key to use for looking up data in the
+ *  account KVP structures. The value associated with this key is what
+ *  will be displayed in the column.
  */
 GtkTreeViewColumn *
-gnc_tree_view_account_add_property_column (GncTreeViewAccount *view,
-					   const gchar *column_title,
-					   const gchar *propname);
+gnc_tree_view_account_add_kvp_column (GncTreeViewAccount *view,
+                                      const gchar *column_title,
+                                      const gchar *kvp_key);
 
 /** @} */
 
diff --git a/src/gnome-utils/gnc-tree-view-split-reg.c b/src/gnome-utils/gnc-tree-view-split-reg.c
index c1ff190..74d4b98 100644
--- a/src/gnome-utils/gnc-tree-view-split-reg.c
+++ b/src/gnome-utils/gnc-tree-view-split-reg.c
@@ -4801,8 +4801,9 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
             if (viewcol == COL_TRANSFERVOID)
             {
                 Account *template_acc;
-		Account *acct;
                 const GncGUID *acctGUID;
+                kvp_frame *kvpf;
+                Account *acct;
 
                 /* save the account GncGUID into the kvp_data. */
                 view->priv->stop_cell_move = FALSE;
@@ -4821,9 +4822,9 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
                 }
 
                 acctGUID = xaccAccountGetGUID (acct);
-		qof_instance_set (QOF_INSTANCE (split),
-				  "sx-account", acctGUID,
-				  NULL);
+                kvpf = xaccSplitGetSlots (split);
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_guid (acctGUID),
+                             GNC_SX_ID, GNC_SX_ACCOUNT, NULL);
 
                 template_acc = gnc_tree_model_split_reg_get_template_account (model);
 
@@ -4843,11 +4844,20 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
             /* Setup the debit and credit fields */
             if (viewcol == COL_DEBIT)
             {
+                kvp_frame *kvpf;
                 char *error_loc;
                 gnc_numeric new_value;
                 gboolean parse_result;
 
+                kvpf = xaccSplitGetSlots (split);
+
+                DEBUG ("kvp_frame debit before: %s\n", kvp_frame_to_string (kvpf));
+
                 /* Setup the debit formula */
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (new_text),
+                                         GNC_SX_ID,
+                                         GNC_SX_DEBIT_FORMULA,
+                                         NULL);
 
                 /* If the value can be parsed into a numeric result, store that
                  * numeric value additionally. See above comment.*/
@@ -4856,22 +4866,45 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
                 {
                     new_value = gnc_numeric_zero();
                 }
-		qof_instance_set (QOF_INSTANCE (split),
-				  "sx-debit-formula", new_text,
-				  "sx-debit-numeric", &new_value,
-				  "sx-credit-formula", NULL,
-				  "sx-credit-numeric", NULL,
-				  NULL);
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
+                                         GNC_SX_ID,
+                                         GNC_SX_DEBIT_NUMERIC,
+                                         NULL);
+
+                DEBUG ("kvp_frame debit after: %s\n", kvp_frame_to_string (kvpf));
+
+                /* Blank the credit formula */
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (NULL),
+                                         GNC_SX_ID,
+                                         GNC_SX_CREDIT_FORMULA,
+                                         NULL);
+
+                new_value = gnc_numeric_zero();
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
+                                         GNC_SX_ID,
+                                         GNC_SX_CREDIT_NUMERIC,
+                                         NULL);
             }
 
             /* Setup the debit and credit fields */
             if (viewcol == COL_CREDIT)
             {
+                kvp_frame *kvpf;
                 char *error_loc;
                 gnc_numeric new_value;
                 gboolean parse_result;
 
-               /* If the value can be parsed into a numeric result (without any
+                kvpf = xaccSplitGetSlots (split);
+
+                DEBUG ("kvp_frame credit before: %s\n", kvp_frame_to_string (kvpf));
+
+                /* Setup the credit formula */
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (new_text),
+                                             GNC_SX_ID,
+                                             GNC_SX_CREDIT_FORMULA,
+                                             NULL);
+
+                /* If the value can be parsed into a numeric result (without any
                  * further variable definitions), store that numeric value
                  * additionally in the kvp. Otherwise store a zero numeric
                  * there.*/
@@ -4880,12 +4913,24 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
                 {
                     new_value = gnc_numeric_zero();
                 }
-		qof_instance_set (QOF_INSTANCE (split),
-				  "sx-credit-formula", new_text,
-				  "sx-credit-numeric", &new_value,
-				  "sx-debit-formula", NULL,
-				  "sx-debit-numeric", NULL,
-				  NULL);
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
+                                         GNC_SX_ID,
+                                         GNC_SX_CREDIT_NUMERIC,
+                                         NULL);
+
+                DEBUG ("kvp_frame credit after: %s\n", kvp_frame_to_string (kvpf));
+
+                /* Blank the debit formula */
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (NULL),
+                                         GNC_SX_ID,
+                                         GNC_SX_DEBIT_FORMULA,
+                                         NULL);
+
+                new_value = gnc_numeric_zero();
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
+                                         GNC_SX_ID,
+                                         GNC_SX_DEBIT_NUMERIC,
+                                         NULL);
             }
             /* set the amount to an innocuous value */
             xaccSplitSetValue (split, gnc_numeric_create (0, 1));
diff --git a/src/gnome/assistant-hierarchy.c b/src/gnome/assistant-hierarchy.c
index 23b98f8..da0d5af 100644
--- a/src/gnome/assistant-hierarchy.c
+++ b/src/gnome/assistant-hierarchy.c
@@ -1008,17 +1008,18 @@ finish_book_options_helper(GNCOptionWin * optionwin,
                           gpointer user_data)
 {
     GNCOptionDB * options = user_data;
-    QofBook *book = gnc_get_current_book ();
+    kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
     gboolean use_split_action_for_num_before =
-        qof_book_use_split_action_for_num_field (book);
+        qof_book_use_split_action_for_num_field (gnc_get_current_book ());
     gboolean use_split_action_for_num_after;
 
     if (!options) return;
 
     gnc_option_db_commit (options);
-    qof_book_save_options (book, gnc_option_db_save_to_kvp, options, TRUE);
+    gnc_option_db_save_to_kvp (options, slots, TRUE);
+    qof_book_kvp_changed (gnc_get_current_book());
     use_split_action_for_num_after =
-        qof_book_use_split_action_for_num_field (book);
+        qof_book_use_split_action_for_num_field (gnc_get_current_book ());
     if (use_split_action_for_num_before != use_split_action_for_num_after)
         gnc_book_option_num_field_source_change_cb (use_split_action_for_num_after);
 }
@@ -1118,11 +1119,11 @@ book_options_dialog_close_cb(GNCOptionWin * optionwin,
 static void
 assistant_instert_book_options_page (hierarchy_data *data)
 {
+    kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
     GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
 
     data->options = gnc_option_db_new_for_type (QOF_ID_BOOK);
-    qof_book_load_options (gnc_get_current_book (),
-			   gnc_option_db_load_from_kvp, data->options);
+    gnc_option_db_load_from_kvp (data->options, slots);
     gnc_option_db_clean (data->options);
 
     data->optionwin = gnc_options_dialog_new_modal (TRUE, _("New Book Options"));
diff --git a/src/gnome/dialog-sx-editor.c b/src/gnome/dialog-sx-editor.c
index 4b7b95f..b3fb1e8 100644
--- a/src/gnome/dialog-sx-editor.c
+++ b/src/gnome/dialog-sx-editor.c
@@ -549,7 +549,9 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
         int numIters, i;
         GHashTable *vars, *txns;
         GList *splitList = NULL;
-        gchar *credit_formula = NULL, *debit_formula = NULL;
+        char *str;
+        kvp_frame *f;
+        kvp_value *v;
         Split *s;
         Transaction *t;
         gnc_numeric tmp;
@@ -557,10 +559,8 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
         gpointer unusedKey, unusedValue;
 
         unbalanceable = FALSE; /* innocent until proven guilty */
-        vars = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
-				     (GDestroyNotify)gnc_sx_variable_free);
-        txns = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
-				     g_free);
+        vars = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)gnc_sx_variable_free);
+        txns = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
         numIters = NUM_ITERS_NO_VARS;
         /**
          * Plan:
@@ -604,10 +604,10 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
 
             for ( ; splitList; splitList = splitList->next )
             {
-                GncGUID *acct_guid = NULL;
-                Account *acct = NULL;
-                gnc_commodity *split_cmdty = NULL;
-                txnCreditDebitSums *tcds = NULL;
+                GncGUID *acct_guid;
+                Account *acct;
+                gnc_commodity *split_cmdty;
+                txnCreditDebitSums *tcds;
 
                 s = (Split*)splitList->data;
                 t = xaccSplitGetParent( s );
@@ -622,11 +622,14 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
                     g_hash_table_insert( txns, (gpointer)t, (gpointer)tcds );
                 }
 
-		qof_instance_get (QOF_INSTANCE (s),
-				  "sx-account", &acct_guid,
-				  "sx-credit-formula", &credit_formula,
-				  "sx-debit-formula", &debit_formula,
-				  NULL);
+                f = xaccSplitGetSlots( s );
+
+                /* contains the guid of the split's actual account. */
+                v = kvp_frame_get_slot_path(f,
+                                            GNC_SX_ID,
+                                            GNC_SX_ACCOUNT,
+                                            NULL);
+                acct_guid = kvp_value_get_guid( v );
                 acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
                 split_cmdty = xaccAccountGetCommodity(acct);
                 if (base_cmdty == NULL)
@@ -635,48 +638,62 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
                 }
                 multi_commodity |= !gnc_commodity_equal(split_cmdty, base_cmdty);
 
-		if ( g_strcmp0 (credit_formula, "") != 0 &&
-		     gnc_sx_parse_vars_from_formula(credit_formula, vars,
-						    &tmp ) < 0 )
-		{
-		    GString *errStr;
-
-		    errStr = g_string_sized_new( 32 );
-		    g_string_printf( errStr,
-				     _( "Couldn't parse credit formula for "
-					"split \"%s\"." ),
-				     xaccSplitGetMemo( s ) );
-		    gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
-				      errStr->str );
-		    g_string_free( errStr, TRUE );
-
-		    return FALSE;
-		}
-		tcds->creditSum =
-		    gnc_numeric_add( tcds->creditSum, tmp, 100,
-				     (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
-		tmp = gnc_numeric_zero();
-		if ( g_strcmp0 (debit_formula, "") != 0 &&
-		     gnc_sx_parse_vars_from_formula( debit_formula, vars,
-						     &tmp ) < 0 )
-		{
-		    GString *errStr;
-
-		    errStr = g_string_sized_new( 32 );
-		    g_string_printf( errStr,
-				     _( "Couldn't parse debit formula for "
-					"split \"%s\"." ),
-				     xaccSplitGetMemo( s ) );
-		    gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
-				      (gchar*)errStr->str );
-		    g_string_free( errStr, TRUE );
-
-		    return FALSE;
-		}
-		tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
-						  (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
-		tmp = gnc_numeric_zero();
-	    }
+                v = kvp_frame_get_slot_path( f,
+                                             GNC_SX_ID,
+                                             GNC_SX_CREDIT_FORMULA,
+                                             NULL );
+                if ( v
+                        && (str = kvp_value_get_string(v))
+                        && strlen( str ) != 0 )
+                {
+                    if ( gnc_sx_parse_vars_from_formula( str, vars, &tmp ) < 0 )
+                    {
+                        GString *errStr;
+
+                        errStr = g_string_sized_new( 32 );
+                        g_string_printf( errStr,
+                                         _( "Couldn't parse credit formula for "
+                                            "split \"%s\"." ),
+                                         xaccSplitGetMemo( s ) );
+                        gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
+                                          errStr->str );
+                        g_string_free( errStr, TRUE );
+
+                        return FALSE;
+                    }
+                    tcds->creditSum =
+                        gnc_numeric_add( tcds->creditSum, tmp, 100,
+                                         (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
+                    tmp = gnc_numeric_zero();
+                }
+                v = kvp_frame_get_slot_path( f,
+                                             GNC_SX_ID,
+                                             GNC_SX_DEBIT_FORMULA,
+                                             NULL );
+                if ( v
+                        && (str = kvp_value_get_string(v))
+                        && strlen(str) != 0 )
+                {
+                    if ( gnc_sx_parse_vars_from_formula( str, vars, &tmp ) < 0 )
+                    {
+                        GString *errStr;
+
+                        errStr = g_string_sized_new( 32 );
+                        g_string_printf( errStr,
+                                         _( "Couldn't parse debit formula for "
+                                            "split \"%s\"." ),
+                                         xaccSplitGetMemo( s ) );
+                        gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
+                                          (gchar*)errStr->str );
+                        g_string_free( errStr, TRUE );
+
+                        return FALSE;
+                    }
+                    tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
+                                                      (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
+                    tmp = gnc_numeric_zero();
+                }
+            }
 
             g_hash_table_foreach( txns,
                                   check_credit_debit_balance,
diff --git a/src/gnome/dialog-sx-editor2.c b/src/gnome/dialog-sx-editor2.c
index a5c5d61..c9de4dc 100644
--- a/src/gnome/dialog-sx-editor2.c
+++ b/src/gnome/dialog-sx-editor2.c
@@ -546,7 +546,9 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
         int numIters, i;
         GHashTable *vars, *txns;
         GList *splitList = NULL;
-        char *credit_formula = NULL, *debit_formula = NULL;
+        char *str;
+        kvp_frame *f;
+        kvp_value *v;
         Split *s;
         Transaction *t;
         gnc_numeric tmp;
@@ -595,7 +597,7 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
 
             for (; splitList; splitList = splitList->next)
             {
-                GncGUID *acct_guid = NULL;
+                GncGUID *acct_guid;
                 Account *acct;
                 gnc_commodity *split_cmdty;
                 txnCreditDebitSums *tcds;
@@ -613,60 +615,77 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
                     g_hash_table_insert (txns, (gpointer)t, (gpointer)tcds);
                 }
 
-		qof_instance_get (QOF_INSTANCE (s),
-				  "sx-account", &acct_guid,
-				  "sx-credit-formula", &credit_formula,
-				  "sx-debit-formula", &debit_formula,
-				  NULL);
-                acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
-                split_cmdty = xaccAccountGetCommodity(acct);
+                f = xaccSplitGetSlots (s);
+
+                /* contains the guid of the split's actual account. */
+                v = kvp_frame_get_slot_path (f,
+                                            GNC_SX_ID,
+                                            GNC_SX_ACCOUNT,
+                                            NULL);
+                acct_guid = kvp_value_get_guid (v);
+                acct = xaccAccountLookup (acct_guid, gnc_get_current_book ());
+                split_cmdty = xaccAccountGetCommodity (acct);
                 if (base_cmdty == NULL)
                 {
                     base_cmdty = split_cmdty;
                 }
-                multi_commodity |= !gnc_commodity_equal(split_cmdty, base_cmdty);
-
-		if ( g_strcmp0 (credit_formula, "") != 0 &&
-		     gnc_sx_parse_vars_from_formula(credit_formula, vars,
-						    &tmp ) < 0 )
-		{
-		    GString *errStr;
-
-		    errStr = g_string_sized_new( 32 );
-		    g_string_printf( errStr,
-				     _( "Couldn't parse credit formula for "
-					"split \"%s\"." ),
-				     xaccSplitGetMemo( s ) );
-		    gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
-				      errStr->str );
-		    g_string_free( errStr, TRUE );
-
-		    return FALSE;
-		}
-		tcds->creditSum =
-		    gnc_numeric_add( tcds->creditSum, tmp, 100,
-				     (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
-		tmp = gnc_numeric_zero();
-		if ( g_strcmp0 (debit_formula, "") != 0 &&
-		     gnc_sx_parse_vars_from_formula( debit_formula, vars,
-						     &tmp ) < 0 )
-		{
-		    GString *errStr;
-
-		    errStr = g_string_sized_new( 32 );
-		    g_string_printf( errStr,
-				     _( "Couldn't parse debit formula for "
-					"split \"%s\"." ),
-				     xaccSplitGetMemo( s ) );
-		    gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
-				      (gchar*)errStr->str );
-		    g_string_free( errStr, TRUE );
-
-		    return FALSE;
-		}
-		tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
-						  (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
-		tmp = gnc_numeric_zero();
+                multi_commodity |= !gnc_commodity_equal (split_cmdty, base_cmdty);
+
+                v = kvp_frame_get_slot_path (f,
+                                             GNC_SX_ID,
+                                             GNC_SX_CREDIT_FORMULA,
+                                             NULL);
+                if (v
+                        && (str = kvp_value_get_string (v))
+                        && strlen( str ) != 0)
+                {
+                    if (gnc_sx_parse_vars_from_formula (str, vars, &tmp ) < 0)
+                    {
+                        GString *errStr;
+
+                        errStr = g_string_sized_new (32);
+                        g_string_printf (errStr,
+                                         _( "Couldn't parse credit formula for "
+                                            "split \"%s\"."),
+                                         xaccSplitGetMemo (s));
+                        gnc_error_dialog (GTK_WIDGET (sxed->dialog), "%s",
+                                          errStr->str);
+                        g_string_free (errStr, TRUE);
+
+                        return FALSE;
+                    }
+                    tcds->creditSum =
+                        gnc_numeric_add (tcds->creditSum, tmp, 100,
+                                         (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD));
+                    tmp = gnc_numeric_zero();
+                }
+                v = kvp_frame_get_slot_path (f,
+                                             GNC_SX_ID,
+                                             GNC_SX_DEBIT_FORMULA,
+                                             NULL);
+                if (v
+                        && (str = kvp_value_get_string (v))
+                        && strlen(str) != 0 )
+                {
+                    if (gnc_sx_parse_vars_from_formula (str, vars, &tmp ) < 0)
+                    {
+                        GString *errStr;
+
+                        errStr = g_string_sized_new (32);
+                        g_string_printf (errStr,
+                                         _( "Couldn't parse debit formula for "
+                                            "split \"%s\"."),
+                                         xaccSplitGetMemo (s));
+                        gnc_error_dialog (GTK_WIDGET (sxed->dialog), "%s",
+                                          (gchar*)errStr->str);
+                        g_string_free (errStr, TRUE);
+
+                        return FALSE;
+                    }
+                    tcds->debitSum = gnc_numeric_add (tcds->debitSum, tmp, 100,
+                                                      (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD));
+                    tmp = gnc_numeric_zero();
+                }
             }
 
             g_hash_table_foreach (txns,
diff --git a/src/gnome/gnc-plugin-page-register2.c b/src/gnome/gnc-plugin-page-register2.c
index b24793d..c5494e4 100644
--- a/src/gnome/gnc-plugin-page-register2.c
+++ b/src/gnome/gnc-plugin-page-register2.c
@@ -3646,30 +3646,39 @@ gnc_plugin_page_register2_cmd_schedule (GtkAction *action,
     /* If the transaction has a sched-xact KVP frame, then go to the editor
      * for the existing SX; otherwise, do the sx-from-trans dialog. */
     {
-	GncGUID *fromSXId = NULL;
-	SchedXaction *theSX = NULL;
-	GList *sxElts;
-	qof_instance_get (QOF_INSTANCE (trans),
-			  "from-sched-xaction", &fromSXId,
-			  NULL);
-
-	/* Get the correct SX */
-	for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
-	      (!theSX) && sxElts;
-	      sxElts = sxElts->next )
-	{
-	    SchedXaction *sx = (SchedXaction*)sxElts->data;
-	    theSX =
-		((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
-		 ? sx : NULL);
-	}
-
-	if (theSX)
-	{
-	    gnc_ui_scheduled_xaction_editor_dialog_create2 (theSX, FALSE);
-	    LEAVE(" ");
-	    return;
-	}
+        kvp_frame *txn_frame;
+        kvp_value *kvp_val;
+        /* set a kvp-frame element in the transaction indicating and
+         * pointing-to the SX this was created from. */
+        txn_frame = xaccTransGetSlots (trans);
+        if ( txn_frame != NULL )
+        {
+            kvp_val = kvp_frame_get_slot (txn_frame, "from-sched-xaction");
+            if (kvp_val)
+            {
+                GncGUID *fromSXId = kvp_value_get_guid (kvp_val);
+                SchedXaction *theSX = NULL;
+                GList *sxElts;
+
+                /* Get the correct SX */
+                for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
+                        (!theSX) && sxElts;
+                        sxElts = sxElts->next )
+                {
+                    SchedXaction *sx = (SchedXaction*)sxElts->data;
+                    theSX =
+                        ((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
+                          ? sx : NULL);
+                }
+
+                if (theSX)
+                {
+                    gnc_ui_scheduled_xaction_editor_dialog_create2 (theSX, FALSE);
+                    LEAVE(" ");
+                    return;
+                }
+            }
+        }
     }
     gnc_sx_create_from_trans (trans);
     LEAVE(" ");
diff --git a/src/gnome/gnc-split-reg.c b/src/gnome/gnc-split-reg.c
index e5e56ac..b9d198a 100644
--- a/src/gnome/gnc-split-reg.c
+++ b/src/gnome/gnc-split-reg.c
@@ -1387,29 +1387,38 @@ gsr_default_schedule_handler( GNCSplitReg *gsr, gpointer data )
     /* If the transaction has a sched-xact KVP frame, then go to the editor
      * for the existing SX; otherwise, do the sx-from-trans dialog. */
     {
-	GncGUID *fromSXId = NULL;
-	SchedXaction *theSX = NULL;
-	GList *sxElts;
-	qof_instance_get (QOF_INSTANCE (pending_trans),
-			  "from-sched-xaction", &fromSXId,
-			  NULL);
-
-	/* Get the correct SX */
-	for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
-	      (!theSX) && sxElts;
-	      sxElts = sxElts->next )
-	{
-	    SchedXaction *sx = (SchedXaction*)sxElts->data;
-	    theSX =
-		((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
-		 ? sx : NULL);
-	}
-
-	if ( theSX )
-	{
-	    gnc_ui_scheduled_xaction_editor_dialog_create(theSX, FALSE);
-	    return;
-	}
+        kvp_frame *txn_frame;
+        kvp_value *kvp_val;
+        /* set a kvp-frame element in the transaction indicating and
+         * pointing-to the SX this was created from. */
+        txn_frame = xaccTransGetSlots( pending_trans );
+        if ( txn_frame != NULL )
+        {
+            kvp_val = kvp_frame_get_slot( txn_frame, "from-sched-xaction" );
+            if ( kvp_val )
+            {
+                GncGUID *fromSXId = kvp_value_get_guid( kvp_val );
+                SchedXaction *theSX = NULL;
+                GList *sxElts;
+
+                /* Get the correct SX */
+                for ( sxElts = gnc_book_get_schedxactions(gnc_get_current_book())->sx_list;
+                        (!theSX) && sxElts;
+                        sxElts = sxElts->next )
+                {
+                    SchedXaction *sx = (SchedXaction*)sxElts->data;
+                    theSX =
+                        ( ( guid_equal( xaccSchedXactionGetGUID( sx ), fromSXId ) )
+                          ? sx : NULL );
+                }
+
+                if ( theSX )
+                {
+                    gnc_ui_scheduled_xaction_editor_dialog_create(theSX, FALSE);
+                    return;
+                }
+            }
+        }
     }
 
     gnc_sx_create_from_trans(pending_trans);
diff --git a/src/import-export/CMakeLists.txt b/src/import-export/CMakeLists.txt
index 0a21959..5f93071 100644
--- a/src/import-export/CMakeLists.txt
+++ b/src/import-export/CMakeLists.txt
@@ -24,6 +24,7 @@ INCLUDE_DIRECTORIES (${CMAKE_SOURCE_DIR}/src/app-utils)
 SET (libgnc_import_SOURCES
   import-utilities.c
   import-settings.c
+  import-match-map.c
 )
 
 # Add dependency on config.h
@@ -32,6 +33,7 @@ SET_SOURCE_FILES_PROPERTIES (${libgnc_import_SOURCES} PROPERTIES OBJECT_DEPENDS
 SET (libgnc_import_HEADERS
   import-utilities.h
   import-settings.h
+  import-match-map.h
 )
 
 ADD_LIBRARY (gnc-import
diff --git a/src/import-export/Makefile.am b/src/import-export/Makefile.am
index 4230c83..0f07e24 100644
--- a/src/import-export/Makefile.am
+++ b/src/import-export/Makefile.am
@@ -18,11 +18,13 @@ libgncmod_generic_import_la_SOURCES = \
 	import-parse.c \
 	import-utilities.c \
 	import-settings.c \
+	import-match-map.c \
 	import-main-matcher.c \
 	gncmod-generic-import.c
 
 gncincludedir = ${GNC_INCLUDE_DIR}
 gncinclude_HEADERS = \
+  import-match-map.h \
   import-parse.h
 
 noinst_HEADERS = \
@@ -30,6 +32,7 @@ noinst_HEADERS = \
   import-backend.h \
   import-commodity-matcher.h \
   import-main-matcher.h \
+  import-match-map.h \
   import-match-picker.h \
   import-settings.h \
   import-utilities.h
diff --git a/src/import-export/aqb/gnc-ab-kvp.c b/src/import-export/aqb/gnc-ab-kvp.c
index b99390b..074a37b 100644
--- a/src/import-export/aqb/gnc-ab-kvp.c
+++ b/src/import-export/aqb/gnc-ab-kvp.c
@@ -32,105 +32,134 @@
 
 #include "gnc-ab-kvp.h"
 
+#define AB_KEY "hbci"
+#define AB_ACCOUNT_ID "account-id"
+#define AB_ACCOUNT_UID "account-uid"
+#define AB_BANK_CODE "bank-code"
+#define AB_TRANS_RETRIEVAL "trans-retrieval"
+#define AB_TEMPLATES "template-list"
+
 /* This static indicates the debugging module that this .o belongs to.  */
 G_GNUC_UNUSED static QofLogModule log_module = G_LOG_DOMAIN;
 
+static kvp_frame *gnc_ab_get_account_kvp(const Account *a, gboolean create);
 static kvp_frame *gnc_ab_get_book_kvp(QofBook *b, gboolean create);
 
 const gchar *
 gnc_ab_get_account_accountid(const Account *a)
 {
-    gchar *id = NULL;
-    qof_instance_get (QOF_INSTANCE (a),
-		      "ab-account-id", &id,
-		      NULL);
-    return id;
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_ACCOUNT_ID);
+    return kvp_value_get_string(value);
 }
 
 void
 gnc_ab_set_account_accountid(Account *a, const gchar *id)
 {
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
+    kvp_value *value = kvp_value_new_string(id);
     xaccAccountBeginEdit(a);
-    qof_instance_set (QOF_INSTANCE (a),
-		      "ab-account-id", id,
-		      NULL);
+    kvp_frame_set_slot_nc(frame, AB_ACCOUNT_ID, value);
+    qof_instance_set_dirty(QOF_INSTANCE (a));
     xaccAccountCommitEdit(a);
 }
 
 const gchar *
 gnc_ab_get_account_bankcode(const Account *a)
 {
-    gchar *code = NULL;
-    qof_instance_get (QOF_INSTANCE (a),
-		      "ab-bank-code", &code,
-		      NULL);
-    return code;
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_BANK_CODE);
+    return kvp_value_get_string(value);
 }
 
 void
 gnc_ab_set_account_bankcode(Account *a, const gchar *code)
 {
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
+    kvp_value *value = kvp_value_new_string(code);
     xaccAccountBeginEdit(a);
-    qof_instance_set (QOF_INSTANCE (a),
-		      "ab-bank-code", code,
-		      NULL);
+    kvp_frame_set_slot_nc(frame, AB_BANK_CODE, value);
+    qof_instance_set_dirty(QOF_INSTANCE (a));
     xaccAccountCommitEdit(a);
 }
 
 guint32
 gnc_ab_get_account_uid(const Account *a)
 {
-    guint64 uid = 0LL;
-    qof_instance_get (QOF_INSTANCE (a),
-		      "ab-account-uid", &uid,
-		      NULL);
-    return (guint32)uid;
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_ACCOUNT_UID);
+    return (guint32) kvp_value_get_gint64(value);
 }
 
 void
 gnc_ab_set_account_uid(Account *a, guint32 uid)
 {
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
+    kvp_value *value = kvp_value_new_gint64(uid);
     xaccAccountBeginEdit(a);
-    qof_instance_set (QOF_INSTANCE (a),
-		      "ab-account-uid", (guint64)uid,
-		      NULL);
+    kvp_frame_set_slot_nc(frame, AB_ACCOUNT_UID, value);
+    qof_instance_set_dirty(QOF_INSTANCE (a));
     xaccAccountCommitEdit(a);
 }
 
 Timespec
 gnc_ab_get_account_trans_retrieval(const Account *a)
 {
-    Timespec t = {0LL, 0LL};
-    qof_instance_get (QOF_INSTANCE (a),
-		      "ab-trans-retrieval", &t,
-		      NULL);
-    return t;
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_TRANS_RETRIEVAL);
+    return kvp_value_get_timespec(value);
 }
 
 void
 gnc_ab_set_account_trans_retrieval(Account *a, Timespec time)
 {
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
+    kvp_value *value = kvp_value_new_timespec(time);
     xaccAccountBeginEdit(a);
-    qof_instance_set (QOF_INSTANCE (a),
-		      "ab-trans-retrieval", &time,
-		      NULL);
+    kvp_frame_set_slot_nc(frame, AB_TRANS_RETRIEVAL, value);
+    qof_instance_set_dirty(QOF_INSTANCE (a));
     xaccAccountCommitEdit(a);
 }
 
 GList *
 gnc_ab_get_book_template_list(QofBook *b)
 {
-    GList *template_list = NULL;
-    qof_instance_get (QOF_INSTANCE (b),
-		      "ab-templates", &template_list,
-		      NULL);
-    return template_list;
+    kvp_frame *frame = gnc_ab_get_book_kvp(b, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_TEMPLATES);
+    return kvp_value_get_glist(value);
 }
 
 void
 gnc_ab_set_book_template_list(QofBook *b, GList *template_list)
 {
-    qof_instance_set (QOF_INSTANCE (b),
-		      "ab-templates", &template_list,
-		      NULL);
+    kvp_frame *frame = gnc_ab_get_book_kvp(b, TRUE);
+    kvp_value *value = kvp_value_new_glist_nc(template_list);
+    kvp_frame_set_slot_nc(frame, AB_TEMPLATES, value);
+    qof_book_kvp_changed (b);
+}
+
+static kvp_frame *
+gnc_ab_get_account_kvp(const Account *a, gboolean create)
+{
+    kvp_frame *toplevel = xaccAccountGetSlots(a);
+    kvp_frame *result = kvp_frame_get_frame(toplevel, AB_KEY);
+    if (!result && create)
+    {
+        result = kvp_frame_new();
+        kvp_frame_add_frame_nc(toplevel, AB_KEY, result);
+    }
+    return result;
+}
+
+static kvp_frame *
+gnc_ab_get_book_kvp(QofBook *b, gboolean create)
+{
+    kvp_frame *toplevel = qof_book_get_slots(b);
+    kvp_frame *result = kvp_frame_get_frame(toplevel, AB_KEY);
+    if (!result && create)
+    {
+        result = kvp_frame_new();
+        kvp_frame_add_frame_nc(toplevel, AB_KEY, result);
+    }
+    return result;
 }
diff --git a/src/import-export/import-account-matcher.c b/src/import-export/import-account-matcher.c
index 27d7fe3..a828311 100644
--- a/src/import-export/import-account-matcher.c
+++ b/src/import-export/import-account-matcher.c
@@ -114,8 +114,8 @@ build_acct_tree(AccountPickerDialog *picker)
     g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
 
     /* Add our custom column. */
-    col = gnc_tree_view_account_add_property_column (picker->account_tree,
-            _("Account ID"), "online-id");
+    col = gnc_tree_view_account_add_kvp_column (picker->account_tree,
+            _("Account ID"), "online_id");
     g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
 
     gtk_container_add(GTK_CONTAINER(picker->account_tree_sw),
diff --git a/src/import-export/import-backend.c b/src/import-export/import-backend.c
index a372bc4..4e0d34e 100644
--- a/src/import-export/import-backend.c
+++ b/src/import-export/import-backend.c
@@ -44,40 +44,6 @@
 #include "gnc-prefs.h"
 #include "gnc-ui-util.h"
 
-/* Private interface to Account GncImportMatchMap functions */
-
-/** @{
-Obtain an ImportMatchMap object from an Account */
-extern GncImportMatchMap * gnc_account_create_imap (Account *acc);
-/*@}*/
-
-/* Look up an Account in the map */
-extern Account* gnc_imap_find_account(GncImportMatchMap *imap,
-				      const char* category,
-				      const char *key);
-
-/* Store an Account in the map. This mapping is immediatly stored in
-  the underlying kvp frame, regardless of whether the MatchMap is
-  destroyed later or not. */
-extern void gnc_imap_add_account (GncImportMatchMap *imap,
-				  const char *category,
-				  const char *key, Account *acc);
-
-/* Look up an Account in the map from a GList* of pointers to strings(tokens)
-  from the current transaction */
-extern Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap,
-					     GList* tokens);
-
-/* Store an Account in the map. This mapping is immediatly stored in
-  the underlying kvp frame, regardless of whether the MatchMap is
-  destroyed later or not. */
-extern void gnc_imap_add_account_bayes (GncImportMatchMap *imap,
-					GList* tokens,
-					Account *acc);
-
-#define GNCIMPORT_DESC    "desc"
-#define GNCIMPORT_MEMO    "memo"
-#define GNCIMPORT_PAYEE    "payee"
 
 /********************************************************************\
  *   Constants                                                      *
@@ -491,15 +457,6 @@ TransactionGetTokens(GNCImportTransInfo *info)
     /* return the pointer to the GList */
     return tokens;
 }
-/* Destroy an import map. But all stored entries will still continue
- * to exist in the underlying kvp frame of the account.
- */
-static void
-gnc_imap_destroy (GncImportMatchMap *imap)
-{
-    if (!imap) return;
-    g_free (imap);
-}
 
 /* searches using the GNCImportTransInfo through all existing transactions
  * if there is an exact match of the description and memo
@@ -514,7 +471,7 @@ matchmap_find_destination (GncImportMatchMap *matchmap, GNCImportTransInfo *info
 
     g_assert (info);
     tmp_map = ((matchmap != NULL) ? matchmap :
-               gnc_account_create_imap
+               gnc_imap_create_from_account
                (xaccSplitGetAccount
                 (gnc_import_TransInfo_get_fsplit (info))));
 
@@ -584,7 +541,7 @@ matchmap_store_destination (GncImportMatchMap *matchmap,
 
     tmp_matchmap = ((matchmap != NULL) ?
                     matchmap :
-                    gnc_account_create_imap
+                    gnc_imap_create_from_account
                     (xaccSplitGetAccount
                      (gnc_import_TransInfo_get_fsplit (trans_info))));
 
diff --git a/src/import-export/import-backend.h b/src/import-export/import-backend.h
index 99e6421..2978fd5 100644
--- a/src/import-export/import-backend.h
+++ b/src/import-export/import-backend.h
@@ -29,11 +29,11 @@
 #define TRANSACTION_MATCHER_H
 
 #include "Transaction.h"
+#include "import-match-map.h"
 #include "import-settings.h"
 
 typedef struct _transactioninfo GNCImportTransInfo;
 typedef struct _matchinfo GNCImportMatchInfo;
-typedef struct _GncImportMatchMap GncImportMatchMap;
 
 typedef enum _action
 {
diff --git a/src/import-export/import-main-matcher.c b/src/import-export/import-main-matcher.c
index 24b8b63..3793212 100644
--- a/src/import-export/import-main-matcher.c
+++ b/src/import-export/import-main-matcher.c
@@ -44,6 +44,7 @@
 #include "gnc-ui-util.h"
 #include "gnc-engine.h"
 #include "import-settings.h"
+#include "import-match-map.h"
 #include "import-match-picker.h"
 #include "import-backend.h"
 #include "import-account-matcher.h"
diff --git a/src/import-export/import-match-map.h b/src/import-export/import-match-map.h
new file mode 100644
index 0000000..88c6945
--- /dev/null
+++ b/src/import-export/import-match-map.h
@@ -0,0 +1,84 @@
+/********************************************************************\
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+/** @addtogroup Import_Export
+    @{ */
+/** @file import-match-map.h
+    @brief Generic import mapper service, maps strings->accounts
+    *
+    An import mapper service that stores Account Maps for the
+    generic importer.  This allows importers to map various
+    "strings" to Gnucash accounts in a generic manner.
+    @author Copyright (C) 2002,2003 Derek Atkins <derek at ihtfp.com>
+ */
+#ifndef GNC_IMPORT_MATCH_MAP_H
+#define GNC_IMPORT_MATCH_MAP_H
+
+typedef struct _GncImportMatchMap GncImportMatchMap;
+
+#include "Account.h"
+
+/** @{
+Obtain an ImportMatchMap object from an Account or a Book */
+GncImportMatchMap * gnc_imap_create_from_account (Account *acc);
+GncImportMatchMap * gnc_imap_create_from_book (QofBook *book);
+/*@}*/
+
+/** Destroy an import map. But all stored entries will still continue
+ to exist in the underlying kvp frame of the account or book. */
+void gnc_imap_destroy (GncImportMatchMap *imap);
+
+/** Clear an import map -- this removes ALL entries in the map */
+void gnc_imap_clear (GncImportMatchMap *imap);
+
+/** Look up an Account in the map */
+Account* gnc_imap_find_account(GncImportMatchMap *imap, const char* category,
+                               const char *key);
+
+/** Store an Account in the map. This mapping is immediatly stored in
+  the underlying kvp frame, regardless of whether the MatchMap is
+  destroyed later or not. */
+void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
+                           const char *key, Account *acc);
+
+/** Look up an Account in the map from a GList* of pointers to strings(tokens)
+  from the current transaction */
+Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList* tokens);
+
+/** Store an Account in the map. This mapping is immediatly stored in
+  the underlying kvp frame, regardless of whether the MatchMap is
+  destroyed later or not. */
+void gnc_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
+                                 Account *acc);
+
+
+/** @name Some well-known categories
+
+  NOTE: You DO NOT have to use these values in your importer -- these
+  are just "well known" values, not "mandatory" values.  You are free
+  to use these if they apply, map your own fields to these labels, or
+  create your own category strings.
+*/
+/** @{*/
+#define GNCIMPORT_DESC	"desc"
+#define GNCIMPORT_MEMO	"memo"
+#define GNCIMPORT_PAYEE	"payee"
+/**@}*/
+
+#endif /* GNC_IMPORT_MATCH_MAP_H */
+/**@}*/
diff --git a/src/import-export/import-utilities.c b/src/import-export/import-utilities.c
index e55ea20..51b8f53 100644
--- a/src/import-export/import-utilities.c
+++ b/src/import-export/import-utilities.c
@@ -40,36 +40,42 @@
  * Account, Transaction and Split
 \********************************************************************/
 
-const gchar * gnc_import_get_acc_online_id (Account * account)
+const gchar * gnc_import_get_acc_online_id(Account * account)
 {
-    gchar *id = NULL;
-    qof_instance_get (QOF_INSTANCE (account), "online-id", &id, NULL);
-    return id;
+    kvp_frame * frame;
+    frame = xaccAccountGetSlots(account);
+    return kvp_frame_get_string(frame, "online_id");
 }
 
 /* Used in the midst of editing a transaction; make it save the
  * account data. */
-void gnc_import_set_acc_online_id (Account *account, const gchar *id)
+void gnc_import_set_acc_online_id(Account * account,
+                                  const gchar * string_value)
 {
+    kvp_frame * frame;
     g_return_if_fail (account != NULL);
+    frame = xaccAccountGetSlots(account);
     xaccAccountBeginEdit (account);
-    qof_instance_set (QOF_INSTANCE (account), "online-id", &id, NULL);
+    kvp_frame_set_str(frame, "online_id", string_value);
+    qof_instance_set_dirty (QOF_INSTANCE (account));
     xaccAccountCommitEdit (account);
 }
 
-const gchar * gnc_import_get_trans_online_id (Transaction * transaction)
+const gchar * gnc_import_get_trans_online_id(Transaction * transaction)
 {
-    gchar *id = NULL;
-    qof_instance_get (QOF_INSTANCE (transaction), "online-id", &id, NULL);
-    return id;
+    kvp_frame * frame;
+    frame = xaccTransGetSlots(transaction);
+    return kvp_frame_get_string(frame, "online_id");
 }
 /* Not actually used */
-void gnc_import_set_trans_online_id (Transaction *transaction,
-				     const gchar *id)
+void gnc_import_set_trans_online_id(Transaction * transaction,
+                                    const gchar * string_value)
 {
-    g_return_if_fail (transaction != NULL);
+    kvp_frame * frame;
     xaccTransBeginEdit (transaction);
-    qof_instance_set (QOF_INSTANCE (transaction), "online-id", &id, NULL);
+    frame = xaccTransGetSlots(transaction);
+    kvp_frame_set_str (frame, "online_id", string_value);
+    qof_instance_set_dirty (QOF_INSTANCE (transaction));
     xaccTransCommitEdit (transaction);
 }
 
@@ -80,20 +86,23 @@ gboolean gnc_import_trans_has_online_id(Transaction * transaction)
     return (online_id != NULL && strlen(online_id) > 0);
 }
 
-const gchar * gnc_import_get_split_online_id (Split * split)
+const gchar * gnc_import_get_split_online_id(Split * split)
 {
-    gchar *id = NULL;
-    qof_instance_get (QOF_INSTANCE (split), "online-id", &id, NULL);
-    return id;
+    kvp_frame * frame;
+    frame = xaccSplitGetSlots(split);
+    return kvp_frame_get_string(frame, "online_id");
 }
 /* Used several places in a transaction edit where many other
  * parameters are also being set, so individual commits wouldn't be
- * appropriate. Besides, there isn't a function for one.*/
-void gnc_import_set_split_online_id (Split *split, const gchar *id)
+ * appropriate. */
+void gnc_import_set_split_online_id(Split * split,
+                                    const gchar * string_value)
 {
-    g_return_if_fail (split != NULL);
+    kvp_frame * frame;
     xaccTransBeginEdit (xaccSplitGetParent (split));
-    qof_instance_set (QOF_INSTANCE (split), "online-id", &id, NULL);
+    frame = xaccSplitGetSlots(split);
+    kvp_frame_set_str (frame, "online_id", string_value);
+    qof_instance_set_dirty (QOF_INSTANCE (split));
     xaccTransCommitEdit (xaccSplitGetParent (split));
 }
 
diff --git a/src/import-export/log-replay/gnc-log-replay.c b/src/import-export/log-replay/gnc-log-replay.c
index bbd26d7..5577571 100644
--- a/src/import-export/log-replay/gnc-log-replay.c
+++ b/src/import-export/log-replay/gnc-log-replay.c
@@ -45,9 +45,6 @@
 
 #define GNC_PREFS_GROUP "dialogs.log-replay"
 
-/* EFFECTIVE FRIEND FUNCTION */
-void qof_instance_set_guid (gpointer inst, const GncGUID *guid);
-
 /* NW: If you want a new log_module, just define
 a unique string either in gnc-engine.h or
 locally.*/
@@ -438,8 +435,7 @@ static void  process_trans_record(  FILE *log_file)
                             xaccTransBeginEdit(trans);
                         }
 
-                        qof_instance_set_guid (QOF_INSTANCE (trans),
-					       &(record.trans_guid));
+                        xaccTransSetGUID (trans, &(record.trans_guid));
                         /*Fill the transaction info*/
                         if (record.date_entered_present)
                         {
diff --git a/src/import-export/ofx/gnc-ofx-kvp.c b/src/import-export/ofx/gnc-ofx-kvp.c
index 8b6f670..05b26e7 100644
--- a/src/import-export/ofx/gnc-ofx-kvp.c
+++ b/src/import-export/ofx/gnc-ofx-kvp.c
@@ -31,28 +31,39 @@ static const char *KEY_ASSOC_INCOME_ACCOUNT = "ofx/associated-income-account";
 
 Account *gnc_ofx_kvp_get_assoc_account(const Account* investment_account)
 {
+    kvp_frame * acc_frame;
+    kvp_value * kvp_val;
     Account *result = NULL;
-    GncGUID *income_guid= NULL;
+
     g_assert(investment_account);
-    qof_instance_get (QOF_INSTANCE (investment_account),
-		      KEY_ASSOC_INCOME_ACCOUNT, &income_guid,
-		      NULL);
-    return xaccAccountLookup(income_guid,
-			       gnc_account_get_book(investment_account));
+
+    acc_frame = xaccAccountGetSlots(investment_account);
+    kvp_val = kvp_frame_get_slot(acc_frame, KEY_ASSOC_INCOME_ACCOUNT);
+    if (kvp_val != NULL)
+    {
+        result = xaccAccountLookup(kvp_value_get_guid(kvp_val),
+                                   gnc_account_get_book(investment_account));
+    }
+    return result;
 }
 
 void gnc_ofx_kvp_set_assoc_account(Account* investment_account,
                                    const Account *income_account)
 {
+    kvp_frame * acc_frame;
+    kvp_value * kvp_val;
     const GncGUID * income_acc_guid;
 
     g_assert(investment_account);
     g_assert(income_account);
 
+    acc_frame = xaccAccountGetSlots(investment_account);
+    g_assert(acc_frame); // Must not be NULL, but the QofInstance doc is unclear about this
     income_acc_guid = xaccAccountGetGUID(income_account);
+    kvp_val = kvp_value_new_guid(income_acc_guid);
     xaccAccountBeginEdit(investment_account);
-    qof_instance_set (QOF_INSTANCE (investment_account),
-		      KEY_ASSOC_INCOME_ACCOUNT, income_acc_guid,
-		      NULL);
+    kvp_frame_set_slot_nc(acc_frame, KEY_ASSOC_INCOME_ACCOUNT,
+                          kvp_val);
+    qof_instance_set_dirty(QOF_INSTANCE (investment_account));
     xaccAccountCommitEdit(investment_account);
 }
diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp
index 881d029..c52b8e8 100644
--- a/src/libqof/qof/kvp_frame.cpp
+++ b/src/libqof/qof/kvp_frame.cpp
@@ -1665,192 +1665,4 @@ kvp_frame_get_hash(const KvpFrame *frame)
     return frame->hash;
 }
 
-static GValue *gvalue_from_kvp_value (KvpValue*);
-static KvpValue *kvp_value_from_gvalue (const GValue*);
-
-static void
-gvalue_list_from_kvp_value (KvpValue *kval, gpointer pList)
-{
-    GList **gvlist = NULL;
-    GValue *gval = gvalue_from_kvp_value (kval);
-    gvlist =  (GList**)pList;
-    if (G_VALUE_TYPE (gval))
-	*gvlist = g_list_prepend (*gvlist, gval);
-}
-
-static void
-kvp_value_list_from_gvalue (GValue *gval, gpointer pList)
-{
-    GList **kvplist = (GList**)pList;
-    KvpValue *kvp;
-    if (!(gval && G_VALUE_TYPE (gval)))
-	return;
-    kvp = kvp_value_from_gvalue (gval);
-    *kvplist = g_list_prepend (*kvplist, kvp);
-}
-
-static GValue*
-gvalue_from_kvp_value (KvpValue *kval)
-{
-    GValue *val;
-    gnc_numeric num;
-    Timespec tm;
-    GDate gdate;
-
-    if (kval == NULL) return NULL;
-    val = g_slice_new0 (GValue);
-
-    switch (kval->type)
-    {
-	case KVP_TYPE_GINT64:
-	    g_value_init (val, G_TYPE_INT64);
-	    g_value_set_int64 (val, kvp_value_get_gint64 (kval));
-	    break;
-	case KVP_TYPE_DOUBLE:
-	    g_value_init (val, G_TYPE_DOUBLE);
-	    g_value_set_double (val, kvp_value_get_double (kval));
-	    break;
-	case KVP_TYPE_NUMERIC:
-	    g_value_init (val, GNC_TYPE_NUMERIC);
-	    num = kvp_value_get_numeric (kval);
-	    g_value_set_boxed (val, &num);
-	    break;
-	case KVP_TYPE_STRING:
-	    g_value_init (val, G_TYPE_STRING);
-	    g_value_set_string (val, kvp_value_get_string (kval));
-	    break;
-	case KVP_TYPE_GUID:
-	    g_value_init (val, GNC_TYPE_GUID);
-	    g_value_set_boxed (val, kvp_value_get_guid (kval));
-	    break;
-	case KVP_TYPE_TIMESPEC:
-	    g_value_init (val, GNC_TYPE_TIMESPEC);
-	    tm = kvp_value_get_timespec (kval);
-	    g_value_set_boxed (val, &tm);
-	    break;
-	case KVP_TYPE_BINARY:
-	    PWARN ("Error! Don't use Kvp Binary!");
-	    g_slice_free (GValue, val);
-	    val = NULL;
-	    break;
-	case KVP_TYPE_GDATE:
-	    g_value_init (val, G_TYPE_DATE);
-	    gdate = kvp_value_get_gdate (kval);
-	    g_value_set_boxed (val, &gdate);
-	    break;
-	case KVP_TYPE_GLIST:
-	{
-	    GList *gvalue_list = NULL;
-	    GList *kvp_list = kvp_value_get_glist (kval);
-	    g_list_foreach (kvp_list, (GFunc)gvalue_list_from_kvp_value, &gvalue_list);
-	    g_value_init (val, GNC_TYPE_VALUE_LIST);
-	    gvalue_list = g_list_reverse (gvalue_list);
-	    g_value_set_boxed (val, gvalue_list);
-	    break;
-	}
-/* No transfer of KVP frames outside of QofInstance-derived classes! */
-	case KVP_TYPE_FRAME:
-	    PWARN ("Error! Attempt to transfer KvpFrame!");
-	default:
-	    PWARN ("Error! Invalid KVP Transfer Request!");
-	    g_slice_free (GValue, val);
-	    val = NULL;
-	    break;
-    }
-    return val;
-}
-
-KvpValue*
-kvp_value_from_gvalue (const GValue *gval)
-{
-    KvpValue *val = NULL;
-    GType type = G_VALUE_TYPE (gval);
-    g_return_val_if_fail (G_VALUE_TYPE (gval), NULL);
-
-    if (type == G_TYPE_INT64)
-	val = kvp_value_new_gint64 (g_value_get_int64 (gval));
-    else if (type == G_TYPE_DOUBLE)
-	val = kvp_value_new_double (g_value_get_double (gval));
-    else if (type == GNC_TYPE_NUMERIC)
-	val = kvp_value_new_numeric (*(gnc_numeric*)g_value_get_boxed (gval));
-    else if (type == G_TYPE_STRING)
-	val = kvp_value_new_string (g_value_get_string (gval));
-    else if (type == GNC_TYPE_GUID)
-	val = kvp_value_new_guid ((GncGUID*)g_value_get_boxed (gval));
-    else if (type == GNC_TYPE_TIMESPEC)
-	val = kvp_value_new_timespec (*(Timespec*)g_value_get_boxed (gval));
-    else if (type == G_TYPE_DATE)
-	val = kvp_value_new_gdate (*(GDate*)g_value_get_boxed (gval));
-    else if (type == GNC_TYPE_VALUE_LIST)
-    {
-	GList *gvalue_list = (GList*)g_value_get_boxed (gval);
-	GList *kvp_list = NULL;
-	g_list_foreach (gvalue_list, (GFunc)kvp_value_list_from_gvalue, &kvp_list);
-	kvp_list = g_list_reverse (kvp_list);
-	val = kvp_value_new_glist_nc (kvp_list);
-//	g_list_free_full (gvalue_list, (GDestroyNotify)g_value_unset);
-//	gvalue_list = NULL;
-    }
-    else
-	PWARN ("Error! Don't know how to make a KvpValue from a %s",
-	       G_VALUE_TYPE_NAME (gval));
-
-    return val;
-}
-
-GValue*
-kvp_frame_get_gvalue (KvpFrame *frame, const gchar *key)
-{
-    KvpValue *kval = kvp_frame_get_value (frame, key);
-    GValue *value = gvalue_from_kvp_value (kval);
-    return value;
-}
-
-void
-kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *value)
-{
-  kvp_frame_set_value_nc (frame, key, kvp_value_from_gvalue (value));
-}
-
-static GValue*
-gnc_gvalue_copy (GValue *src, gpointer uData)
-{
-    GValue *dest = g_value_init (g_slice_new0 (GValue), G_VALUE_TYPE (src));
-    g_value_copy (src, dest);
-    return dest;
-}
-
-void
-gnc_gvalue_free (GValue *val)
-{
-    if (val == NULL || ! G_IS_VALUE (val)) return;
-    g_value_unset (val);
-    g_slice_free (GValue, val);
-}
-
-static GList*
-gnc_value_list_copy (GList *list)
-{
-    return g_list_copy_deep (list, (GCopyFunc)gnc_gvalue_copy, NULL);
-}
-
-static void
-gnc_value_list_free (GList *list)
-{
-    g_list_free_full (list, (GDestroyNotify)gnc_gvalue_free);
-}
-
-GType
-gnc_value_list_get_type (void)
-{
-    static GType type = 0;
-    if (type == 0)
-    {
-	type = g_boxed_type_register_static ("gnc_value_list",
-					     (GBoxedCopyFunc)gnc_value_list_copy,
-					     (GBoxedFreeFunc)gnc_value_list_free);
-    }
-    return type;
-}
-
 /* ========================== END OF FILE ======================= */
diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h
index 12f9ab5..440377a 100644
--- a/src/libqof/qof/kvp_frame.h
+++ b/src/libqof/qof/kvp_frame.h
@@ -594,59 +594,6 @@ gchar* kvp_frame_to_string(const KvpFrame *frame);
 gchar* binary_to_string(const void *data, guint32 size);
 GHashTable* kvp_frame_get_hash(const KvpFrame *frame);
 
-/** KvpItem: GValue Exchange
- * \brief Transfer of KVP to and from GValue, with the key
- *
- * Used to parameterize KVP <-> GValue exchanges.
- */
-typedef struct
-{
-    const gchar   *key;
-    GValue        *value;
-}KvpItem;
-
-/** Return a KvpItem containing the value of a KvpFrame
- *
- * Structure types (gnc_numeric, Timespec) are converted to pointers
- * and must be extracted with g_value_get_boxed. A KVP_TYPE_GLIST will
- * have all of its contents converted from KvpValues to GValues, so
- * the return type will be a GValue containing a GList of GValue*, not
- * GValue.  Use gnc_value_list_free() to free such a list if you take
- * it out of the GValue.
- *
- * \param frame: (transfer-none) The KvpFrame retrieved with kvp_get_frame_foo()
- * \param key: (transfer-none) A slash-delimited string with the path to
- * the stored value. Must not be NULL or empty.
- * \return (transfer-full) A KvpItem* which must be freed with kvp_item_free().
- */
-GValue *kvp_frame_get_gvalue (KvpFrame *frame, const gchar *key);
-
-/** Replace or create a Kvp slot from a KvpItem
- *
- * Structure types (gnc_numeric, Timespec) should be stored as
- * boxed-type pointers in the GValue with the appropriate type from
- * qof.h. Lists should be stored as a GValue containing a GList of
- * GValues of type convertable to KvpValues. Unsupported types will
- * emit a warning message and will be skipped.
- *
- * \param frame: (transfer none) The KvpFrame into which the value
- * will be added.
- * \param key: (transfer none) The subkey of the frame at which to
- * store the value
- * \param value: GValue containing the paramter to store.
- */
-void kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *value);
-
-/**
- * \brief Convenience function to release the value in a GValue
- * acquired by kvp_frame_get_gvalue and to free the GValue.
- * \param value: A GValue* created by kvp_frame_get_gvalue
- */
-void gnc_gvalue_free (GValue *value);
-
-GType gnc_value_list_get_type (void);
-#define GNC_TYPE_VALUE_LIST (gnc_value_list_get_type ())
-
 /** @} */
 #ifdef __cplusplus
 }
diff --git a/src/libqof/qof/qof.h b/src/libqof/qof/qof.h
index 68ad9ff..f34dc2e 100644
--- a/src/libqof/qof/qof.h
+++ b/src/libqof/qof/qof.h
@@ -84,6 +84,7 @@
 #include "kvp-util-p.h"
 #include "qofbackend.h"
 #include "qofid-p.h"
+#include "qofinstance-p.h"
 #include "qofbook.h"
 #include "qofclass.h"
 #include "qofevent.h"
diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp
index baaa421..0ae2b21 100644
--- a/src/libqof/qof/qofbook.cpp
+++ b/src/libqof/qof/qofbook.cpp
@@ -58,30 +58,9 @@ extern "C"
 #include "qofbookslots.h"
 
 static QofLogModule log_module = QOF_MOD_ENGINE;
-#define AB_KEY "hbci"
-#define AB_TEMPLATES "template-list"
-
-enum
-{
-    PROP_0,
-//  PROP_ROOT_ACCOUNT,		/* Table */
-//  PROP_ROOT_TEMPLATE,		/* Table */
-    PROP_OPT_TRADING_ACCOUNTS,	/* KVP */
-    PROP_OPT_AUTO_READONLY_DAYS,/* KVP */
-    PROP_OPT_NUM_FIELD_SOURCE,	/* KVP */
-    PROP_OPT_DEFAULT_BUDGET,	/* KVP */
-    PROP_OPT_FY_END,		/* KVP */
-    PROP_AB_TEMPLATES,		/* KVP */
-    N_PROPERTIES		/* Just a counter */
-};
 
-QOF_GOBJECT_GET_TYPE(QofBook, qof_book, QOF_TYPE_INSTANCE, {});
-QOF_GOBJECT_DISPOSE(qof_book);
-QOF_GOBJECT_FINALIZE(qof_book);
+QOF_GOBJECT_IMPL(qof_book, QofBook, QOF_TYPE_INSTANCE);
 
-static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
-#undef G_PARAM_READWRITE
-#define G_PARAM_READWRITE static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE)
 /* ====================================================================== */
 /* constructor / destructor */
 
@@ -111,186 +90,6 @@ qof_book_init (QofBook *book)
     book->version = 0;
 }
 
-static void
-qof_book_get_property (GObject* object,
-		       guint prop_id,
-		       GValue* value,
-		       GParamSpec* pspec)
-{
-    QofBook *book;
-    gchar *key;
-
-    g_return_if_fail (QOF_IS_BOOK (object));
-    book = QOF_BOOK (object);
-    switch (prop_id)
-    {
-    case PROP_OPT_TRADING_ACCOUNTS:
-	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
-			       OPTION_SECTION_ACCOUNTS,
-			       OPTION_NAME_TRADING_ACCOUNTS);
-	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
-	g_free (key);
-	break;
-    case PROP_OPT_AUTO_READONLY_DAYS:
-	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
-			       OPTION_SECTION_ACCOUNTS,
-			       OPTION_NAME_AUTO_READONLY_DAYS);
-	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
-	g_free (key);
-	break;
-    case PROP_OPT_NUM_FIELD_SOURCE:
-	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
-			       OPTION_SECTION_ACCOUNTS,
-			       OPTION_NAME_NUM_FIELD_SOURCE);
-	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
-	g_free (key);
-	break;
-    case PROP_OPT_DEFAULT_BUDGET:
-	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
-			       OPTION_SECTION_ACCOUNTS,
-			       OPTION_NAME_DEFAULT_BUDGET);
-	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
-	g_free (key);
-    case PROP_OPT_FY_END:
-	key = const_cast<char*>("fy_end");
-	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
-	break;
-    case PROP_AB_TEMPLATES:
-	key = const_cast<char*>(AB_KEY "/" AB_TEMPLATES);
-	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
-	break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-qof_book_set_property (GObject      *object,
-		       guint         prop_id,
-		       const GValue *value,
-		       GParamSpec   *pspec)
-{
-    QofBook *book;
-    gchar *key;
-
-    g_return_if_fail (QOF_IS_BOOK (object));
-    book = QOF_BOOK (object);
-    g_assert (qof_instance_get_editlevel(book));
-
-    switch (prop_id)
-    {
-    case PROP_OPT_TRADING_ACCOUNTS:
-	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
-			       OPTION_SECTION_ACCOUNTS,
-			       OPTION_NAME_TRADING_ACCOUNTS);
-	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
-	g_free (key);
-	break;
-    case PROP_OPT_AUTO_READONLY_DAYS:
-	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
-			       OPTION_SECTION_ACCOUNTS,
-			       OPTION_NAME_AUTO_READONLY_DAYS);
-	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
-	g_free (key);
-	break;
-    case PROP_OPT_NUM_FIELD_SOURCE:
-	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
-			       OPTION_SECTION_ACCOUNTS,
-			       OPTION_NAME_NUM_FIELD_SOURCE);
-	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
-	g_free (key);
-	break;
-    case PROP_OPT_DEFAULT_BUDGET:
-	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
-			       OPTION_SECTION_ACCOUNTS,
-			       OPTION_NAME_DEFAULT_BUDGET);
-	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
-	g_free (key);
-	break;
-    case PROP_OPT_FY_END:
-	key = const_cast<char*>("fy_end");
-	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
-	break;
-    case PROP_AB_TEMPLATES:
-	key = const_cast<char*>(AB_KEY "/" AB_TEMPLATES);
-	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
-	break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-qof_book_class_init (QofBookClass *klass)
-{
-    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-    gobject_class->dispose = qof_book_dispose;
-    gobject_class->finalize = qof_book_finalize;
-    gobject_class->get_property = qof_book_get_property;
-    gobject_class->set_property = qof_book_set_property;
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_OPT_TRADING_ACCOUNTS,
-     g_param_spec_string("trading-accts",
-                         "Use Trading Accounts",
-			 "Scheme true ('t') or NULL. If 't', then the book "
-			 "uses trading accounts for managing multiple-currency "
-			 "transactions.",
-                         NULL,
-                         G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_OPT_NUM_FIELD_SOURCE,
-     g_param_spec_string("split-action-num-field",
-                         "Use Split-Action in the Num Field",
-			 "Scheme true ('t') or NULL. If 't', then the book "
-			 "will put the split action value in the Num field.",
-                         NULL,
-                         G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_OPT_AUTO_READONLY_DAYS,
-     g_param_spec_double("autoreadonly-days",
-                         "Transaction Auto-read-only Days",
-			 "Prevent editing of transactions posted more than "
-			 "this many days ago.",
-			 0,
-                         G_MAXDOUBLE,
-			 0,
-                         G_PARAM_READWRITE));
-
-    g_object_class_install_property
-    (gobject_class,
-     PROP_OPT_DEFAULT_BUDGET,
-     g_param_spec_boxed("default-budget",
-                        "Book Default Budget",
-                        "The default Budget for this book.",
-                        GNC_TYPE_GUID,
-                        G_PARAM_READWRITE));
-    g_object_class_install_property
-    (gobject_class,
-     PROP_OPT_FY_END,
-     g_param_spec_boxed("fy-end",
-                        "Book Fiscal Year End",
-                        "A GDate with a bogus year having the last Month and "
-			"Day of the Fiscal year for the book.",
-                        G_TYPE_DATE,
-                        G_PARAM_READWRITE));
-    g_object_class_install_property
-    (gobject_class,
-     PROP_AB_TEMPLATES,
-     g_param_spec_boxed("ab-templates",
-                        "AQBanking Template List",
-                        "A GList of AQBanking Templates",
-                        GNC_TYPE_VALUE_LIST,
-                        G_PARAM_READWRITE));
-}
-
 QofBook *
 qof_book_new (void)
 {
@@ -362,7 +161,6 @@ qof_book_destroy (QofBook *book)
 
     LEAVE ("book=%p", book);
 }
-
 /* ====================================================================== */
 
 gboolean
@@ -455,7 +253,20 @@ qof_book_set_backend (QofBook *book, QofBackend *be)
     LEAVE (" ");
 }
 
+void qof_book_kvp_changed (QofBook *book)
+{
+    qof_book_begin_edit(book);
+    qof_instance_set_dirty (QOF_INSTANCE (book));
+    qof_book_commit_edit(book);
+}
+
 /* ====================================================================== */
+
+KvpFrame *qof_book_get_slots(const QofBook *book)
+{
+    return qof_instance_get_slots(QOF_INSTANCE(book));
+}
+
 /* Store arbitrary pointers in the QofBook for data storage extensibility */
 /* XXX if data is NULL, we should remove the key from the hash table!
  */
@@ -578,7 +389,7 @@ qof_book_get_counter (QofBook *book, const char *counter_name)
     }
 
     /* Use the KVP in the book */
-    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
+    kvp = qof_book_get_slots (book);
 
     if (!kvp)
     {
@@ -630,7 +441,7 @@ qof_book_increment_and_format_counter (QofBook *book, const char *counter_name)
     counter++;
 
     /* Get the KVP from the current book */
-    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
+    kvp = qof_book_get_slots (book);
 
     if (!kvp)
     {
@@ -679,7 +490,7 @@ qof_book_get_counter_format(const QofBook *book, const char *counter_name)
     }
 
     /* Get the KVP from the current book */
-    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
+    kvp = qof_book_get_slots (book);
 
     if (!kvp)
     {
@@ -830,10 +641,19 @@ qof_book_validate_counter_format_internal(const gchar *p,
 gboolean
 qof_book_use_trading_accounts (const QofBook *book)
 {
-    const char *opt = NULL;
-    qof_instance_get (QOF_INSTANCE (book),
-		      "trading-accts", &opt,
-		      NULL);
+    const char *opt;
+    kvp_value *kvp_val;
+
+    kvp_val = kvp_frame_get_slot_path (qof_book_get_slots (book),
+                                       KVP_OPTION_PATH,
+                                       OPTION_SECTION_ACCOUNTS,
+                                       OPTION_NAME_TRADING_ACCOUNTS,
+                                       NULL);
+    if (kvp_val == NULL)
+        return FALSE;
+
+    opt = kvp_value_get_string (kvp_val);
+
     if (opt && opt[0] == 't' && opt[1] == 0)
         return TRUE;
     return FALSE;
@@ -844,10 +664,19 @@ qof_book_use_trading_accounts (const QofBook *book)
 gboolean
 qof_book_use_split_action_for_num_field (const QofBook *book)
 {
-    const char *opt = NULL;
-    qof_instance_get (QOF_INSTANCE (book),
-		      "split-action-num-field", &opt,
-		      NULL);
+    const char *opt;
+    kvp_value *kvp_val;
+
+    g_assert(book);
+    kvp_val = kvp_frame_get_slot_path (qof_book_get_slots (book),
+                                       KVP_OPTION_PATH,
+                                       OPTION_SECTION_ACCOUNTS,
+                                       OPTION_NAME_NUM_FIELD_SOURCE,
+                                       NULL);
+    if (kvp_val == NULL)
+        return FALSE;
+
+    opt = kvp_value_get_string (kvp_val);
 
     if (opt && opt[0] == 't' && opt[1] == 0)
         return TRUE;
@@ -863,13 +692,21 @@ gboolean qof_book_uses_autoreadonly (const QofBook *book)
 gint qof_book_get_num_days_autoreadonly (const QofBook *book)
 {
     kvp_value *kvp_val;
-    double tmp = 0;
-    KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
-
+    double tmp;
     g_assert(book);
-    qof_instance_get (QOF_INSTANCE (book),
-		      "autoreadonly-days", &tmp,
-		      NULL);
+    kvp_val = kvp_frame_get_slot_path (qof_book_get_slots (book),
+                                       KVP_OPTION_PATH,
+                                       OPTION_SECTION_ACCOUNTS,
+                                       OPTION_NAME_AUTO_READONLY_DAYS,
+                                       NULL);
+
+    if (kvp_val == NULL)
+    {
+        //PWARN("kvp_val for slot '%s' is NULL", OPTION_NAME_AUTO_READONLY_DAYS);
+        return 0;
+    }
+
+    tmp = kvp_value_get_double (kvp_val);
     return (gint) tmp;
 }
 
@@ -891,16 +728,14 @@ GDate* qof_book_get_autoreadonly_gdate (const QofBook *book)
 const char*
 qof_book_get_string_option(const QofBook* book, const char* opt_name)
 {
-    return kvp_frame_get_string(qof_instance_get_slots(QOF_INSTANCE (book)),
-				opt_name);
+    return kvp_frame_get_string(qof_book_get_slots(book), opt_name);
 }
 
 void
 qof_book_set_string_option(QofBook* book, const char* opt_name, const char* opt_val)
 {
     qof_book_begin_edit(book);
-    kvp_frame_set_string(qof_instance_get_slots(QOF_INSTANCE (book)),
-						opt_name, opt_val);
+    kvp_frame_set_string(qof_book_get_slots(book), opt_name, opt_val);
     qof_instance_set_dirty (QOF_INSTANCE (book));
     qof_book_commit_edit(book);
 }
@@ -917,52 +752,6 @@ static void commit_err (G_GNUC_UNUSED QofInstance *inst, QofBackendError errcode
 //  gnc_engine_signal_commit_error( errcode );
 }
 
-#define GNC_FEATURES "/features/"
-static void
-add_feature_to_hash (const gchar *key, KvpValue *value, gpointer user_data)
-{
-    gchar *descr = kvp_value_get_string (value);
-    g_hash_table_insert (*(GHashTable**)user_data, (gchar*)key, descr);
-}
-
-GHashTable *
-qof_book_get_features (QofBook *book)
-{
-    KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
-    GHashTable *features = g_hash_table_new (g_str_hash, g_str_equal);
-
-    frame = kvp_frame_get_frame (frame, GNC_FEATURES);
-    kvp_frame_for_each_slot (frame, &add_feature_to_hash, &features);
-    return features;
-}
-
-void
-qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr)
-{
-    KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
-    gchar *path = g_strconcat (GNC_FEATURES, key, NULL);
-    qof_book_begin_edit (book);
-    kvp_frame_set_string (frame, path, descr);
-    qof_instance_set_dirty (QOF_INSTANCE (book));
-    qof_book_commit_edit (book);
-}
-
-void
-qof_book_load_options (QofBook *book, GNCOptionLoad load_cb, GNCOptionDB *odb)
-{
-    KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book));
-    load_cb (odb, slots);
-}
-
-void
-qof_book_save_options (QofBook *book, GNCOptionSave save_cb,
-		       GNCOptionDB* odb, gboolean clear)
-{
-    KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book));
-    save_cb (odb, slots, clear);
-    qof_instance_set_dirty (QOF_INSTANCE (book));
-}
-
 static void noop (G_GNUC_UNUSED QofInstance *inst) {}
 
 void
diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h
index c1e5ae4..c3bd255 100644
--- a/src/libqof/qof/qofbook.h
+++ b/src/libqof/qof/qofbook.h
@@ -69,11 +69,6 @@ typedef struct _QofBookClass  QofBookClass;
 
 typedef void (*QofBookDirtyCB) (QofBook *, gboolean dirty, gpointer user_data);
 
-typedef struct gnc_option_db GNCOptionDB;
-
-typedef void (*GNCOptionSave) (GNCOptionDB*, KvpFrame*, gboolean);
-typedef void (*GNCOptionLoad) (GNCOptionDB*, KvpFrame*);
-
 /* Book structure */
 struct _QofBook
 {
@@ -216,11 +211,24 @@ QofCollection  * qof_book_get_collection (const QofBook *, QofIdType);
 typedef void (*QofCollectionForeachCB) (QofCollection *, gpointer user_data);
 void qof_book_foreach_collection (const QofBook *, QofCollectionForeachCB, gpointer);
 
+/** Return The kvp data for the book.
+ *  Note that the book KVP data is persistent, and is stored/retrieved
+ *  from the file/database.  Thus, the book KVP is the correct place to
+ *  store data that needs to be persistent accross sessions (or shared
+ *  between multiple users).  To store application runtime data, use
+ *  qof_book_set_data() instead.
+ */
+KvpFrame *qof_book_get_slots(const QofBook *book);
+
 /** The qof_book_set_data() allows arbitrary pointers to structs
  *    to be stored in QofBook. This is the "preferred" method for
  *    extending QofBook to hold new data types.  This is also
  *    the ideal location to store other arbitrary runtime data
  *    that the application may need.
+ *
+ *    The book data differs from the book KVP in that the contents
+ *    of the book KVP are persistent (are saved and restored to file
+ *    or database), whereas the data pointers exist only at runtime.
  */
 void qof_book_set_data (QofBook *book, const gchar *key, gpointer data);
 
@@ -304,6 +312,10 @@ time64 qof_book_get_session_dirty_time(const QofBook *book);
  */
 void qof_book_set_dirty_cb(QofBook *book, QofBookDirtyCB cb, gpointer user_data);
 
+/** Call this function when you change the book kvp, to make sure the book
+ * is marked 'dirty'. */
+void qof_book_kvp_changed (QofBook *book);
+
 /** This will get the named counter for this book. The return value is
  *    -1 on error or the current value of the counter.
  */
@@ -331,22 +343,9 @@ const char *qof_book_get_counter_format (const QofBook *book,
 const char* qof_book_get_string_option(const QofBook* book, const char* opt_name);
 void qof_book_set_string_option(QofBook* book, const char* opt_name, const char* opt_val);
 
-/** Access functions for reading and setting the used-features on this book.
- */
-GHashTable *qof_book_get_features (QofBook *book);
-void qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr);
-
 void qof_book_begin_edit(QofBook *book);
 void qof_book_commit_edit(QofBook *book);
 
-/* Access functions for loading and saving the file options */
-void qof_book_load_options (QofBook *book, GNCOptionLoad load_cb,
-			    GNCOptionDB *odb);
-void
-qof_book_save_options (QofBook *book, GNCOptionSave save_cb,
-		       GNCOptionDB* odb, gboolean clear);
-
-
 /** deprecated */
 #define qof_book_get_guid(X) qof_entity_get_guid (QOF_INSTANCE(X))
 
diff --git a/src/libqof/qof/qofid.cpp b/src/libqof/qof/qofid.cpp
index 6ff6703..6febf64 100644
--- a/src/libqof/qof/qofid.cpp
+++ b/src/libqof/qof/qofid.cpp
@@ -38,7 +38,6 @@ extern "C"
 
 #include "qof.h"
 #include "qofid-p.h"
-#include "qofinstance-p.h"
 
 static QofLogModule log_module = QOF_MOD_ENGINE;
 static gboolean qof_alt_dirty_mode = FALSE;
diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h
index 751b3f0..aede28c 100644
--- a/src/libqof/qof/qofinstance-p.h
+++ b/src/libqof/qof/qofinstance-p.h
@@ -54,64 +54,8 @@ void qof_instance_set_last_update (QofInstance *inst, Timespec ts);
  *  collection flag at all. */
 void qof_instance_set_dirty_flag (gconstpointer inst, gboolean flag);
 
-/** Set the GncGUID of this instance */
-void qof_instance_set_guid (gpointer inst, const GncGUID *guid);
-
-/** Copy the GncGUID from one instance to another.  This routine should
- *  be used with extreme caution, since GncGUID values are everywhere
- *  assumed to be unique. */
-void qof_instance_copy_guid (gpointer to, gconstpointer from);
-
-//QofIdType qof_instance_get_e_type (const QofInstance *inst);
-//void qof_instance_set_e_type (QofInstance *ent, QofIdType e_type);
-
-/** Return the pointer to the kvp_data */
-/*@ dependent @*/
-KvpFrame* qof_instance_get_slots (const QofInstance *);
-void qof_instance_set_editlevel(gpointer inst, gint level);
-void qof_instance_increase_editlevel (gpointer ptr);
-void qof_instance_decrease_editlevel (gpointer ptr);
-void qof_instance_reset_editlevel (gpointer ptr);
-/** Set the flag that indicates whether or not this object is about to
- *  be destroyed.
- *
- *  @param ptr The object whose flag should be set.
- *
- *  @param value The new value to be set for this object. */
-void qof_instance_set_destroying (gpointer ptr, gboolean value);
-
-/** \brief Set the dirty flag
-Sets this instance AND the collection as dirty.
-*/
-void qof_instance_set_dirty(QofInstance* inst);
-
-/* reset the dirty flag */
-void qof_instance_mark_clean (QofInstance *);
-/** Get the version number on this instance.  The version number is
- *  used to manage multi-user updates. */
-gint32 qof_instance_get_version (gconstpointer inst);
-
-/** Set the version number on this instance.  The version number is
- *  used to manage multi-user updates. */
-void qof_instance_set_version (gpointer inst, gint32 value);
-/** Copy the version number on this instance.  The version number is
- *  used to manage multi-user updates. */
-void qof_instance_copy_version (gpointer to, gconstpointer from);
-
-/** Get the instance version_check number */
-guint32 qof_instance_get_version_check (gconstpointer inst);
-/** Set the instance version_check number */
-void qof_instance_set_version_check (gpointer inst, guint32 value);
-/** copy the instance version_check number */
-void qof_instance_copy_version_check (gpointer to, gconstpointer from);
-void qof_instance_set_idata(gpointer inst, guint32 idata);
-/* Convenience functions to save some typing in property handlers */
-void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value);
-void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value);
-
 #ifdef __cplusplus
 }
 #endif
 
-
 #endif /* QOF_INSTANCE_P_H */
diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp
index b5ac003..dc32af7 100644
--- a/src/libqof/qof/qofinstance.cpp
+++ b/src/libqof/qof/qofinstance.cpp
@@ -62,6 +62,7 @@ enum
     PROP_GUID,
     PROP_COLLECTION,
     PROP_BOOK,
+    PROP_KVP_DATA,
     PROP_LAST_UPDATE,
     PROP_EDITLEVEL,
     PROP_DESTROYING,
@@ -82,6 +83,12 @@ typedef struct QofInstancePrivate
     /* The entity_table in which this instance is stored */
     QofBook * book;
 
+    /* kvp_data is a key-value pair database for storing arbirtary
+     * information associated with this instance.
+     * See src/engine/kvp_doc.txt for a list and description of the
+     * important keys. */
+//    KvpFrame *kvp_data;
+
     /*  Timestamp used to track the last modification to this
      *  instance.  Typically used to compare two versions of the
      *  same object, to see which is newer.  When used with the
@@ -175,6 +182,15 @@ static void qof_instance_class_init(QofInstanceClass *klass)
 
     g_object_class_install_property
     (object_class,
+     PROP_KVP_DATA,
+     g_param_spec_pointer ("kvp-data",
+                           "Object KVP Data",
+                           "A pointer to the key-value data associated "
+                           "with this object.",
+                           G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (object_class,
      PROP_LAST_UPDATE,
      g_param_spec_pointer ("last-update",
                            "Object Last Update",
@@ -380,6 +396,9 @@ qof_instance_get_property (GObject         *object,
     case PROP_BOOK:
         g_value_take_object(value, priv->book);
         break;
+    case PROP_KVP_DATA:
+        g_value_set_pointer(value, inst->kvp_data);
+        break;
     case PROP_LAST_UPDATE:
         g_value_set_pointer(value, &priv->last_update);
         break;
@@ -436,6 +455,9 @@ qof_instance_set_property (GObject         *object,
         qof_instance_set_book(inst,
 			      static_cast<QofBook*>(g_value_get_object(value)));
         break;
+    case PROP_KVP_DATA:
+        qof_instance_set_slots(inst, static_cast<KvpFrame*>(g_value_get_pointer(value)));
+        break;
     case PROP_LAST_UPDATE:
         ts = static_cast<Timespec*>(g_value_get_pointer(value));
         qof_instance_set_last_update(inst, *ts);
@@ -938,32 +960,6 @@ gboolean qof_instance_refers_to_object(const QofInstance* inst, const QofInstanc
     }
 }
 
-/* g_object_set/get wrappers */
-void
-qof_instance_get (const QofInstance *inst, const gchar *first_prop, ...)
-{
-    va_list ap;
-    g_return_if_fail (QOF_IS_INSTANCE (inst));
-
-    va_start (ap, first_prop);
-    g_object_get_valist (G_OBJECT (inst), first_prop, ap);
-    va_end (ap);
-}
-
-void
-qof_instance_set (QofInstance *inst, const gchar *first_prop, ...)
-{
-    va_list ap;
-    QofInstancePrivate *priv = GET_PRIVATE(inst);
-    g_return_if_fail (QOF_IS_INSTANCE (inst));
-
-    qof_instance_set_dirty (inst);
-    va_start (ap, first_prop);
-    g_object_set_valist (G_OBJECT (inst), first_prop, ap);
-    va_end (ap);
-}
-
-
 /* =================================================================== */
 /* Entity edit and commit utilities */
 /* =================================================================== */
@@ -1068,25 +1064,5 @@ qof_commit_edit_part2(QofInstance *inst,
     return TRUE;
 }
 
-void
-qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value)
-{
-    KvpFrame *frame = qof_instance_get_slots (inst);
-    kvp_frame_set_gvalue (frame, key, value);
-}
-
-void
-qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value)
-{
-    KvpFrame *frame = qof_instance_get_slots (inst);
-    GValue *temp = kvp_frame_get_gvalue (frame, key);
-    if (temp)
-    {
-	g_value_copy (temp, value);
-	gnc_gvalue_free (temp);
-    }
-}
-
-
 /* ========================== END OF FILE ======================= */
 
diff --git a/src/libqof/qof/qofinstance.h b/src/libqof/qof/qofinstance.h
index ca485c3..a296099 100644
--- a/src/libqof/qof/qofinstance.h
+++ b/src/libqof/qof/qofinstance.h
@@ -121,12 +121,30 @@ const GncGUID * qof_entity_get_guid (gconstpointer);
 /*@ dependent @*/
 QofCollection* qof_instance_get_collection (gconstpointer inst);
 
+/** Set the GncGUID of this instance */
+void qof_instance_set_guid (gpointer inst, const GncGUID *guid);
+
+/** Copy the GncGUID from one instance to another.  This routine should
+ *  be used with extreme caution, since GncGUID values are everywhere
+ *  assumed to be unique. */
+void qof_instance_copy_guid (gpointer to, gconstpointer from);
+
 /** Compare the GncGUID values of two instances.  This routine returns 0
  *  if the two values are equal, <0 if the first is smaller than the
  *  second, or >0 if the second is smaller tan the first. */
 gint qof_instance_guid_compare(const gconstpointer ptr1, const gconstpointer ptr2);
 
+//QofIdType qof_instance_get_e_type (const QofInstance *inst);
+//void qof_instance_set_e_type (QofInstance *ent, QofIdType e_type);
+
+/** Return the pointer to the kvp_data */
+/*@ dependent @*/
+KvpFrame* qof_instance_get_slots (const QofInstance *);
+void qof_instance_set_editlevel(gpointer inst, gint level);
 gint qof_instance_get_editlevel (gconstpointer ptr);
+void qof_instance_increase_editlevel (gpointer ptr);
+void qof_instance_decrease_editlevel (gpointer ptr);
+void qof_instance_reset_editlevel (gpointer ptr);
 
 /** Compare two instances, based on thier last update times.
  *  Returns a negative, zero or positive value, respectively,
@@ -146,6 +164,14 @@ int qof_instance_version_cmp (const QofInstance *left, const QofInstance *right)
  *  is passed to the function. */
 gboolean qof_instance_get_destroying (gconstpointer ptr);
 
+/** Set the flag that indicates whether or not this object is about to
+ *  be destroyed.
+ *
+ *  @param ptr The object whose flag should be set.
+ *
+ *  @param value The new value to be set for this object. */
+void qof_instance_set_destroying (gpointer ptr, gboolean value);
+
 /** Retrieve the flag that indicates whether or not this object has
  *  been modified.  This is specifically the flag on the object. It
  *  does not perform any other checking which might normally be
@@ -165,22 +191,39 @@ void qof_instance_print_dirty (const QofInstance *entity, gpointer dummy);
 #define qof_instance_is_dirty qof_instance_get_dirty
 gboolean qof_instance_get_dirty (QofInstance *);
 
+/** \brief Set the dirty flag
+
+Sets this instance AND the collection as dirty.
+*/
+void qof_instance_set_dirty(QofInstance* inst);
+
+/* reset the dirty flag */
+void qof_instance_mark_clean (QofInstance *);
+
 gboolean qof_instance_get_infant(const QofInstance *inst);
 
-/**
- * \brief Wrapper for g_object_get
- */
-void qof_instance_get (const QofInstance *inst, const gchar *first_param, ...);
+/** Get the version number on this instance.  The version number is
+ *  used to manage multi-user updates. */
+gint32 qof_instance_get_version (gconstpointer inst);
 
-/**
- * \brief Wrapper for g_object_set
- * Group setting multiple parameters in a single begin/commit/rollback
- */
-void qof_instance_set (QofInstance *inst, const gchar *first_param, ...);
+/** Set the version number on this instance.  The version number is
+ *  used to manage multi-user updates. */
+void qof_instance_set_version (gpointer inst, gint32 value);
+/** Copy the version number on this instance.  The version number is
+ *  used to manage multi-user updates. */
+void qof_instance_copy_version (gpointer to, gconstpointer from);
+
+/** Get the instance version_check number */
+guint32 qof_instance_get_version_check (gconstpointer inst);
+/** Set the instance version_check number */
+void qof_instance_set_version_check (gpointer inst, guint32 value);
+/** copy the instance version_check number */
+void qof_instance_copy_version_check (gpointer to, gconstpointer from);
 
 /** get the instance tag number
     used for kvp management in sql backends. */
 guint32 qof_instance_get_idata (gconstpointer inst);
+void qof_instance_set_idata(gpointer inst, guint32 idata);
 
 /**
  * Returns a displayable name for this object.  The returned string must be freed by the caller.
diff --git a/src/libqof/qof/qoflog.cpp b/src/libqof/qof/qoflog.cpp
index 3475ca3..bd0f7d5 100644
--- a/src/libqof/qof/qoflog.cpp
+++ b/src/libqof/qof/qoflog.cpp
@@ -268,8 +268,6 @@ qof_log_prettify (const char *name)
     begin = g_strrstr (buffer, "*");
     if (begin == NULL)
 	begin = g_strrstr (buffer, " ");
-    else if (*(begin + 1) == ' ')
-	++ begin;
     if (begin != NULL)
 	p = begin + 1;
     else
diff --git a/src/libqof/qof/test/test-kvp_frame.c b/src/libqof/qof/test/test-kvp_frame.c
index c1e5f4a..6267f70 100644
--- a/src/libqof/qof/test/test-kvp_frame.c
+++ b/src/libqof/qof/test/test-kvp_frame.c
@@ -27,7 +27,7 @@ extern "C"
 #include "config.h"
 #include <string.h>
 #include <glib.h>
-#include <unittest-support.h>
+#include "unittest-support.h"
 
 #ifdef __cplusplus
 }
@@ -41,22 +41,18 @@ void test_suite_kvp_frame ( void );
 typedef struct
 {
     KvpFrame *frame;
-    GSList *hdlrs;
 } Fixture;
 
 static void
 setup( Fixture *fixture, gconstpointer pData )
 {
     fixture->frame = kvp_frame_new();
-    fixture->hdlrs = NULL;
 }
 
 static void
 teardown( Fixture *fixture, gconstpointer pData )
 {
     kvp_frame_delete( fixture->frame );
-    g_slist_free_full (fixture->hdlrs, test_free_log_handler);
-    test_clear_error_list ();
 }
 
 extern KvpFrame* ( *p_get_trailer_make )( KvpFrame *frame, const char *key_path, char **end_key );
@@ -71,7 +67,6 @@ static void
 setup_static( Fixture *fixture, gconstpointer pData )
 {
     fixture->frame = kvp_frame_new();
-    fixture->hdlrs = NULL;
     init_static_test_pointers();
     g_assert( p_get_trailer_make && p_kvp_value_glist_to_string &&
               p_get_or_make && p_kvp_frame_get_frame_or_null_slash_trash &&
@@ -82,8 +77,6 @@ static void
 teardown_static( Fixture *fixture, gconstpointer pData )
 {
     kvp_frame_delete( fixture->frame );
-    g_slist_free_full (fixture->hdlrs, test_free_log_handler);
-    test_clear_error_list ();
     p_get_trailer_make = NULL;
     p_kvp_value_glist_to_string = NULL;
     p_get_or_make = NULL;
@@ -91,19 +84,21 @@ teardown_static( Fixture *fixture, gconstpointer pData )
     p_get_trailer_or_null = NULL;
 }
 
-static GncGUID*
-populate_frame (KvpFrame *frame)
+static void
+test_kvp_frame_new_delete( void )
 {
-    GList *list = NULL;
+    KvpFrame *frame;
     Timespec ts;
     GncGUID *guid;
-    GDate gdate;
 
     ts.tv_sec = 1;
     ts.tv_nsec = 1;
-    guid = guid_malloc ();
-    guid_new (guid);
-    g_date_set_dmy (&gdate, 26, 1, 1957);
+    guid = guid_malloc();
+    guid_new( guid );
+
+    frame = kvp_frame_new();
+    g_assert( frame );
+    g_assert( kvp_frame_is_empty( frame ) );
 
     kvp_frame_set_gint64( frame, "gint64-type", 100 );
     kvp_frame_set_double( frame, "double-type", 3.14159 );
@@ -111,37 +106,14 @@ populate_frame (KvpFrame *frame)
     kvp_frame_set_timespec( frame, "timespec-type", ts );
     kvp_frame_set_string( frame, "string-type", "abcdefghijklmnop" );
     kvp_frame_set_guid( frame, "guid-type", guid );
-    kvp_frame_set_value_nc (frame, "gdate-type", kvp_value_new_gdate (gdate));
     kvp_frame_set_frame( frame, "frame-type", kvp_frame_new() );
 
-    list = g_list_prepend (list, kvp_value_new_guid (guid));
-    list = g_list_prepend (list, kvp_value_new_string ("qrstuvwxyz"));
-    list = g_list_prepend (list, kvp_value_new_timespec (ts));
-    list = g_list_prepend (list, kvp_value_new_numeric (gnc_numeric_create (256, 120)));
-    list = g_list_prepend (list, kvp_value_new_double (0.4342944819));
-    list = g_list_prepend (list, kvp_value_new_gint64 (0x1f2e3d4c5b6a79LL));
-    kvp_frame_set_value (frame, "list-type", kvp_value_new_glist_nc (list));
-
-    return guid;
-}
-
-static void
-test_kvp_frame_new_delete( void )
-{
-    KvpFrame *frame;
-    GncGUID *guid;
-
-    frame = kvp_frame_new();
-    g_assert( frame );
-    g_assert( kvp_frame_is_empty( frame ) );
-
-    guid = populate_frame (frame);
-
     g_assert( !kvp_frame_is_empty( frame ) );
 
     kvp_frame_delete( frame );
     g_assert( frame );
-    guid_free (guid);
+
+    guid_free( guid );
 }
 
 static void
@@ -1493,203 +1465,6 @@ test_get_trailer_or_null( Fixture *fixture, gconstpointer pData )
     g_assert_cmpstr( last_key, == , "test2" );
 }
 
-static void
-test_kvp_frame_get_gvalue (Fixture *fixture, gconstpointer pData)
-{
-    KvpFrame *frame = fixture->frame;
-    GValue *value;
-    Timespec ts = {1, 1};
-    GncGUID *guid = populate_frame (frame);
-    GDate date;
-    gchar *log_domain = "qof.kvp";
-    gint log_level = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
-    gchar *msg1 = "[gvalue_from_kvp_value()] Error! Attempt to transfer KvpFrame!";
-    gchar *msg2 = "[gvalue_from_kvp_value()] Error! Invalid KVP Transfer Request!";
-#undef _func
-    TestErrorStruct *check1 = test_error_struct_new (log_domain, log_level,
-							msg1);
-    TestErrorStruct *check2 = test_error_struct_new (log_domain, log_level,
-							msg2);
-    fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check1,
-						 (GLogFunc)test_list_handler);
-    test_add_error (check1);
-    test_add_error (check2);
-
-    g_date_clear (&date, 1);
-    g_date_set_dmy (&date, 26, 1, 1957);
-
-    value = kvp_frame_get_gvalue (frame, "gint64-type");
-    g_assert (value != NULL);
-    g_assert (G_VALUE_HOLDS_INT64 (value));
-    g_assert_cmpint (g_value_get_int64 (value), ==, 100);
-    gnc_gvalue_free (value);
-
-    value = kvp_frame_get_gvalue (frame, "double-type");
-    g_assert (value != NULL);
-    g_assert (G_VALUE_HOLDS_DOUBLE (value));
-    g_assert_cmpfloat (g_value_get_double (value), ==, 3.14159);
-    gnc_gvalue_free (value);
-
-    value = kvp_frame_get_gvalue (frame, "numeric-type");
-    g_assert (value != NULL);
-    g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_NUMERIC);
-    g_assert (gnc_numeric_zero_p (*(gnc_numeric*)g_value_get_boxed (value)));
-    gnc_gvalue_free (value);
-
-    value = kvp_frame_get_gvalue (frame, "timespec-type");
-    g_assert (value != NULL);
-    g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_TIMESPEC);
-    g_assert (timespec_equal (&ts, (Timespec*)g_value_get_boxed (value)));
-    gnc_gvalue_free (value);
-
-    value = kvp_frame_get_gvalue (frame, "string-type");
-    g_assert (value != NULL);
-    g_assert (G_VALUE_HOLDS_STRING (value));
-    g_assert_cmpstr (g_value_get_string (value), ==, "abcdefghijklmnop");
-    gnc_gvalue_free (value);
-
-    value = kvp_frame_get_gvalue (frame, "guid-type");
-    g_assert (value != NULL);
-    g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_GUID);
-    g_assert (guid_equal (guid, (GncGUID*)g_value_get_boxed (value)));
-    gnc_gvalue_free (value);
-
-    value = kvp_frame_get_gvalue (frame, "gdate-type");
-    g_assert (value != NULL);
-    g_assert_cmpint (G_VALUE_TYPE (value), ==, G_TYPE_DATE);
-    g_assert_cmpint (g_date_compare (&date, (GDate*)g_value_get_boxed (value)), ==, 0);
-    gnc_gvalue_free (value);
-
-    value = kvp_frame_get_gvalue (frame, "frame-type");
-    g_assert (value == NULL);
-    g_assert_cmpint (check1->hits, ==, 1);
-    g_assert_cmpint (check2->hits, ==, 1);
-
-    value = kvp_frame_get_gvalue (frame, "list-type");
-    g_assert (value != NULL);
-    g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_VALUE_LIST);
-    {
-	GList *list = (GList*)g_value_get_boxed (value);
-	GValue *value = NULL;
-
-	value = (GValue*)(list->data);
-	g_assert (G_VALUE_HOLDS_INT64 (value));
-	g_assert (g_value_get_int64 (value) == 0x1f2e3d4c5b6a79LL);
-	list = g_list_next (list);
-
-	value = (GValue*)(list->data);
-	g_assert (G_VALUE_HOLDS_DOUBLE (value));
-	g_assert_cmpfloat (g_value_get_double (value), ==, 0.4342944819);
-	list = g_list_next (list);
-
-	value = (GValue*)(list->data);
-	g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_NUMERIC);
-	g_assert (gnc_numeric_eq (*(gnc_numeric*)g_value_get_boxed (value),
-				  gnc_numeric_create (256, 120)));
-	list = g_list_next (list);
-
-	value = (GValue*)(list->data);
-	g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_TIMESPEC);
-	g_assert (timespec_equal (&ts, (Timespec*)g_value_get_boxed (value)));
-	list = g_list_next (list);
-
-	value = (GValue*)(list->data);
-	g_assert (G_VALUE_HOLDS_STRING (value));
-	g_assert_cmpstr (g_value_get_string (value), ==, "qrstuvwxyz");
-	list = g_list_next (list);
-
-	value = (GValue*)(list->data);
-	g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_GUID);
-	g_assert (guid_equal (guid, (GncGUID*)g_value_get_boxed (value)));
-	list = g_list_next (list);
-
-	g_assert (list == NULL);
-
-    }
-    gnc_gvalue_free (value);
-}
-
-static void
-test_kvp_frame_set_gvalue (Fixture *fixture, gconstpointer pData)
-{
-/* Bit of a shortcut: We'll use kvp_frame_get_item to make our KvpItem
- * and feed it into a new frame; something of a round-trip test.
- */
-    KvpFrame *o_frame = fixture->frame;
-    KvpFrame *n_frame = kvp_frame_new ();
-    GValue *value;
-    GList *o_list, *n_list;
-
-    populate_frame (o_frame);
-
-    value = kvp_frame_get_gvalue (o_frame, "gint64-type");
-    g_assert (value != NULL);
-    kvp_frame_set_gvalue (n_frame, "gint64-type", value);
-    g_assert_cmpint (kvp_frame_get_gint64 (o_frame, "gint64-type"), ==,
-		     kvp_frame_get_gint64 (n_frame, "gint64-type"));
-
-    value = kvp_frame_get_gvalue (o_frame, "double-type");
-    g_assert (value != NULL);
-    kvp_frame_set_gvalue (n_frame, "double-type", value);
-    g_assert_cmpint (kvp_frame_get_double (o_frame, "double-type"), ==,
-		     kvp_frame_get_double (n_frame, "double-type"));
-
-    value = kvp_frame_get_gvalue (o_frame, "numeric-type");
-    g_assert (value != NULL);
-    kvp_frame_set_gvalue (n_frame, "numeric-type", value);
-    g_assert (gnc_numeric_equal (kvp_frame_get_numeric (o_frame, "numeric-type"),
-				 kvp_frame_get_numeric (n_frame, "numeric-type")));
-
-    value = kvp_frame_get_gvalue (o_frame, "timespec-type");
-    g_assert (value != NULL);
-    kvp_frame_set_gvalue (n_frame, "timespec-type", value);
-    {
-	Timespec o_ts = kvp_frame_get_timespec (o_frame, "timespec-type");
-	Timespec n_ts = kvp_frame_get_timespec (n_frame, "timespec-type");
-	g_assert (timespec_equal (&o_ts, &n_ts));
-    }
-
-    value = kvp_frame_get_gvalue (o_frame, "string-type");
-    g_assert (value != NULL);
-    kvp_frame_set_gvalue (n_frame, "string-type", value);
-    g_assert_cmpstr (kvp_frame_get_string (o_frame, "string-type"), ==,
-		     kvp_frame_get_string (n_frame, "string-type"));
-
-    value = kvp_frame_get_gvalue (o_frame, "gdate-type");
-    g_assert (value != NULL);
-    kvp_frame_set_gvalue (n_frame, "gdate-type", value);
-    {
-	GDate o_date = kvp_value_get_gdate (kvp_frame_get_slot (o_frame,
-								"gdate-type"));
-	GDate n_date = kvp_value_get_gdate (kvp_frame_get_slot (n_frame,
-								"gdate-type"));
-	g_assert_cmpint (g_date_compare (&o_date, &n_date), ==, 0);
-    }
-
-    value = kvp_frame_get_gvalue (o_frame, "guid-type");
-    g_assert (value != NULL);
-    kvp_frame_set_gvalue (n_frame, "guid-type", value);
-    g_assert (guid_equal (kvp_frame_get_guid (o_frame, "guid-type"),
-			  kvp_frame_get_guid (n_frame, "guid-type")));
-
-    value = kvp_frame_get_gvalue (o_frame, "list-type");
-    g_assert (value != NULL);
-    kvp_frame_set_gvalue (n_frame, "list-type", value);
-    o_list = kvp_value_get_glist (kvp_frame_get_slot (o_frame, "list_type"));
-    n_list = kvp_value_get_glist (kvp_frame_get_slot (n_frame, "list_type"));
-
-    g_assert_cmpint (g_list_length (o_list), ==, g_list_length (n_list));
-    while (o_list && n_list)
-    {
-	g_assert_cmpint (kvp_value_compare ((KvpValue*)o_list->data,
-					    (KvpValue*)n_list->data), ==, 0);
-	o_list = g_list_next (o_list);
-	n_list = g_list_next (n_list);
-    }
-    kvp_frame_delete (n_frame);
-}
-
-
 void
 test_suite_kvp_frame( void )
 {
@@ -1717,6 +1492,4 @@ test_suite_kvp_frame( void )
     GNC_TEST_ADD( suitename, "get or make", Fixture, NULL, setup_static, test_get_or_make, teardown_static );
     GNC_TEST_ADD( suitename, "kvp frame get frame or null slash trash", Fixture, NULL, setup_static, test_kvp_frame_get_frame_or_null_slash_trash, teardown_static );
     GNC_TEST_ADD( suitename, "get trailer or null", Fixture, NULL, setup_static, test_get_trailer_or_null, teardown_static );
-    GNC_TEST_ADD ( suitename, "kvp frame get gvalue", Fixture, NULL, setup, test_kvp_frame_get_gvalue, teardown);
-    GNC_TEST_ADD ( suitename, "kvp frame set gvalue", Fixture, NULL, setup, test_kvp_frame_set_gvalue, teardown);
 }
diff --git a/src/libqof/qof/test/test-qofbook.c b/src/libqof/qof/test/test-qofbook.c
index e6bd41b..475a5f2 100644
--- a/src/libqof/qof/test/test-qofbook.c
+++ b/src/libqof/qof/test/test-qofbook.c
@@ -365,80 +365,99 @@ test_book_increment_and_format_counter ( Fixture *fixture, gconstpointer pData )
 }
 
 static void
+test_book_kvp_changed( Fixture *fixture, gconstpointer pData )
+{
+    g_test_message( "Testing book is marked dirty after kvp_changed" );
+    g_assert( !qof_instance_is_dirty (QOF_INSTANCE (fixture->book)) );
+    qof_book_kvp_changed( fixture->book );
+    g_assert( qof_instance_is_dirty (QOF_INSTANCE (fixture->book)) );
+}
+
+static void
 test_book_use_trading_accounts( Fixture *fixture, gconstpointer pData )
 {
+    const char *slot_path;
+
+    /* create correct slot path */
+    slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/", OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_TRADING_ACCOUNTS, NULL );
+    g_assert( slot_path != NULL );
+
+    g_test_message( "Testing when no trading accounts are used" );
+    g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
+
+    g_test_message( "Testing with incorrect slot path and correct value - t" );
+    qof_book_set_string_option( fixture->book, OPTION_NAME_TRADING_ACCOUNTS, "t" );
     g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
 
     g_test_message( "Testing with existing trading accounts set to true - t" );
-    qof_book_begin_edit (fixture->book);
-    qof_instance_set (QOF_INSTANCE (fixture->book),
-		      "trading-accts", "t",
-		      NULL);
+    qof_book_set_string_option( fixture->book, slot_path, "t" );
     g_assert( qof_book_use_trading_accounts( fixture-> book ) == TRUE );
 
     g_test_message( "Testing with existing trading accounts and incorrect value - tt" );
-    qof_instance_set (QOF_INSTANCE (fixture->book),
-		      "trading-accts", "tt",
-		      NULL);
+    qof_book_set_string_option( fixture->book, slot_path, "tt" );
     g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
-    qof_book_commit_edit (fixture->book);
 
 }
 
 static void
 test_book_get_num_days_autofreeze( Fixture *fixture, gconstpointer pData )
 {
+    const char *slot_path;
+
+    /* create correct slot path */
+    slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/", OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_AUTO_READONLY_DAYS, NULL );
+    g_assert( slot_path != NULL );
+
     g_test_message( "Testing default: No auto-freeze days are set" );
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
 
+    g_test_message( "Testing with incorrect slot path and some correct value - 17" );
+    kvp_frame_set_double(qof_book_get_slots(fixture->book), OPTION_NAME_AUTO_READONLY_DAYS, 17);
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
 
-    qof_book_begin_edit (fixture->book);
-    qof_instance_set (QOF_INSTANCE (fixture->book),
-		      "autoreadonly-days", (gdouble)17,
-		      NULL);
+    g_test_message( "Testing when setting this correctly with some correct value - 17" );
+    kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 17);
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == TRUE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 17 );
 
     g_test_message( "Testing when setting this correctly to zero again" );
-
-    qof_instance_set (QOF_INSTANCE (fixture->book),
-		      "autoreadonly-days", (gdouble)0,
-		      NULL);
+    kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 0);
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
 
-    qof_instance_set (QOF_INSTANCE (fixture->book),
-		      "autoreadonly-days", (gdouble)32,
-		      NULL);
+    g_test_message( "Testing when setting this correctly with some correct value - 32" );
+    kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 32);
     g_assert( qof_book_uses_autoreadonly( fixture-> book ) == TRUE );
     g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 32 );
 
-    qof_book_commit_edit (fixture->book);
 }
 
 static void
 test_book_use_split_action_for_num_field( Fixture *fixture, gconstpointer pData )
 {
+    const char *slot_path;
+
+    /* create correct slot path */
+    slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/",
+                                            OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_NUM_FIELD_SOURCE, NULL );
+    g_assert( slot_path != NULL );
+
     g_test_message( "Testing default: No selection has been specified" );
     g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == FALSE );
 
-    g_test_message( "Testing with existing use split action for num set to true - t" );
+    g_test_message( "Testing with incorrect slot path and correct value - t" );
+    qof_book_set_string_option( fixture->book, OPTION_NAME_NUM_FIELD_SOURCE, "t" );
+    g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == FALSE );
 
-    qof_book_begin_edit (fixture->book);
-    qof_instance_set (QOF_INSTANCE (fixture->book),
-		      "split-action-num-field", "t",
-		      NULL);
+    g_test_message( "Testing with existing use split action for num set to true - t" );
+    qof_book_set_string_option( fixture->book, slot_path, "t" );
     g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == TRUE );
 
     g_test_message( "Testing with existing use split action for num and incorrect value - tt" );
-    qof_instance_set (QOF_INSTANCE (fixture->book),
-		      "split-action-num-field", "tt",
-		      NULL);
+    qof_book_set_string_option( fixture->book, slot_path, "tt" );
     g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == FALSE );
-    qof_book_commit_edit (fixture->book);
 }
 
 static void
@@ -756,6 +775,7 @@ test_suite_qofbook ( void )
     GNC_TEST_ADD( suitename, "get counter", Fixture, NULL, setup, test_book_get_counter, teardown );
     GNC_TEST_ADD( suitename, "get counter format", Fixture, NULL, setup, test_book_get_counter_format, teardown );
     GNC_TEST_ADD( suitename, "increment and format counter", Fixture, NULL, setup, test_book_increment_and_format_counter, teardown );
+    GNC_TEST_ADD( suitename, "kvp changed", Fixture, NULL, setup, test_book_kvp_changed, teardown );
     GNC_TEST_ADD( suitename, "use trading accounts", Fixture, NULL, setup, test_book_use_trading_accounts, teardown );
     GNC_TEST_ADD( suitename, "get autofreeze days", Fixture, NULL, setup, test_book_get_num_days_autofreeze, teardown );
     GNC_TEST_ADD( suitename, "use split action for num field", Fixture, NULL, setup, test_book_use_split_action_for_num_field, teardown );
diff --git a/src/register/ledger-core/split-register-model-save.c b/src/register/ledger-core/split-register-model-save.c
index 60582d4..b22bdee 100644
--- a/src/register/ledger-core/split-register-model-save.c
+++ b/src/register/ledger-core/split-register-model-save.c
@@ -674,14 +674,16 @@ gnc_template_register_save_xfrm_cell (BasicCell * cell,
     }
 
     acctGUID = xaccAccountGetGUID (acct);
-    qof_instance_set (QOF_INSTANCE (sd->split),
-		      "sx-account", acctGUID,
-		      NULL);
+    kvpf = xaccSplitGetSlots (sd->split);
+    kvp_frame_set_slot_path (kvpf, kvp_value_new_guid(acctGUID),
+                             GNC_SX_ID, GNC_SX_ACCOUNT, NULL);
+
     template_acc = xaccAccountLookup (&info->template_account,
                                       gnc_get_current_book ());
 
     /* set the actual account to the fake account for these templates */
     xaccAccountInsertSplit (template_acc, sd->split);
+    qof_instance_set_dirty (QOF_INSTANCE (sd->split));
 }
 
 static void
@@ -698,9 +700,10 @@ gnc_template_register_save_debcred_cell (BasicCell * cell,
 {
     SRSaveData *sd = save_data;
     SplitRegister *reg = user_data;
-    const char *credit_formula, *debit_formula;
+    kvp_frame *kvpf;
+    const char *value;
     char *error_loc;
-    gnc_numeric credit_amount, debit_amount;
+    gnc_numeric new_amount;
     gboolean parse_result;
 
     g_return_if_fail (gnc_basic_cell_has_name (cell, FDEBT_CELL) ||
@@ -709,37 +712,54 @@ gnc_template_register_save_debcred_cell (BasicCell * cell,
     if (sd->handled_dc)
         return;
 
+    kvpf = xaccSplitGetSlots (sd->split);
+
+    DEBUG ("kvp_frame before: %s\n", kvp_frame_to_string (kvpf));
+
     /* amountStr = gnc_numeric_to_string (new_amount); */
 
-    credit_formula = gnc_table_layout_get_cell_value (reg->table->layout,
-						      FCRED_CELL);
+    value = gnc_table_layout_get_cell_value (reg->table->layout, FCRED_CELL);
+    kvp_frame_set_slot_path (kvpf, kvp_value_new_string (value),
+                             GNC_SX_ID,
+                             GNC_SX_CREDIT_FORMULA,
+                             NULL);
+
     /* If the value can be parsed into a numeric result (without any
      * further variable definitions), store that numeric value
      * additionally in the kvp. Otherwise store a zero numeric
      * there.*/
-    parse_result = gnc_exp_parser_parse_separate_vars(credit_formula,
-						      &credit_amount,
-						      &error_loc, NULL);
+    parse_result = gnc_exp_parser_parse_separate_vars(value, &new_amount, &error_loc, NULL);
     if (!parse_result)
-        credit_amount = gnc_numeric_zero();
+    {
+        new_amount = gnc_numeric_zero();
+    }
+    kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_amount),
+                             GNC_SX_ID,
+                             GNC_SX_CREDIT_NUMERIC,
+                             NULL);
+
+    value = gnc_table_layout_get_cell_value (reg->table->layout, FDEBT_CELL);
 
-    debit_formula = gnc_table_layout_get_cell_value (reg->table->layout,
-						     FDEBT_CELL);
+    kvp_frame_set_slot_path (kvpf,
+                             kvp_value_new_string (value),
+                             GNC_SX_ID,
+                             GNC_SX_DEBIT_FORMULA,
+                             NULL);
 
     /* If the value can be parsed into a numeric result, store that
      * numeric value additionally. See above comment.*/
-    parse_result = gnc_exp_parser_parse_separate_vars(debit_formula,
-						      &debit_amount,
-						      &error_loc, NULL);
+    parse_result = gnc_exp_parser_parse_separate_vars(value, &new_amount, &error_loc, NULL);
     if (!parse_result)
-        debit_amount = gnc_numeric_zero();
-
-    qof_instance_set (QOF_INSTANCE (sd->split),
-		      "sx-credit-formula", credit_formula,
-		      "sx-credit-numeric", &credit_amount,
-		      "sx-debit-formula", debit_formula,
-		      "sx-debit-numeric", &debit_amount,
-		      NULL);
+    {
+        new_amount = gnc_numeric_zero();
+    }
+    kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_amount),
+                             GNC_SX_ID,
+                             GNC_SX_DEBIT_NUMERIC,
+                             NULL);
+
+    DEBUG ("kvp_frame  after: %s\n", kvp_frame_to_string (kvpf));
+
     /* set the amount to an innocuous value */
     /* Note that this marks the split dirty */
     xaccSplitSetValue (sd->split, gnc_numeric_create (0, 1));
@@ -753,13 +773,24 @@ gnc_template_register_save_shares_cell (BasicCell * cell,
                                         gpointer user_data)
 {
     SRSaveData *sd = save_data;
+    kvp_frame *kvpf;
     char *sharesStr = "(x + y)/42";
 
     g_return_if_fail (gnc_basic_cell_has_name (cell, SHRS_CELL));
+
+    kvpf = xaccSplitGetSlots (sd->split);
+
     /* FIXME: shares cells are numeric by definition. */
-    qof_instance_set (QOF_INSTANCE (sd->split),
-		      "sx-shares", sharesStr,
-		      NULL);
+    DEBUG ("kvp_frame before: %s\n", kvp_frame_to_string (kvpf));
+
+    /* sharesStr = gnc_numeric_to_string( sharesStr ); */
+    kvp_frame_set_slot_path (kvpf,
+                             kvp_value_new_string (sharesStr),
+                             GNC_SX_ID,
+                             GNC_SX_SHARES,
+                             NULL);
+
+    DEBUG ("kvp_frame  after: %s\n", kvp_frame_to_string (kvpf));
 
     /* set the shares to an innocuous value */
     /* Note that this marks the split dirty */
diff --git a/src/register/ledger-core/split-register-model.c b/src/register/ledger-core/split-register-model.c
index 503c9ba..5af4a3b 100644
--- a/src/register/ledger-core/split-register-model.c
+++ b/src/register/ledger-core/split-register-model.c
@@ -2091,23 +2091,31 @@ gnc_template_register_get_xfrm_entry (VirtualLocation virt_loc,
     static char *name = NULL;
 
     SplitRegister *reg = user_data;
+    kvp_frame *kvpf;
     Split *split;
-    Account *account;
-    GncGUID *guid = NULL;
 
     split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
     if (!split)
         return NULL;
-    /* Caller either uses the return as a temporary in a boolean
-     * expression or g_strdups it, so we keep it static and free the
-     * old one on every call to avoid leaks. Ugly, but it works.
-     */
+
+    kvpf = xaccSplitGetSlots (split);
+
     g_free (name);
-    qof_instance_get (QOF_INSTANCE (split),
-		      "sx-account", &guid,
-		      NULL);
-    account = xaccAccountLookup (guid, gnc_get_current_book ());
-    name = account ? gnc_get_account_name_for_register (account) : NULL;
+
+    if (kvpf)
+    {
+        Account *account;
+        GncGUID *guid;
+
+        guid = kvp_value_get_guid(
+                   kvp_frame_get_slot_path(kvpf, "sched-xaction", "account", NULL));
+
+        account = xaccAccountLookup (guid, gnc_get_current_book ());
+
+        name = account ? gnc_get_account_name_for_register (account) : NULL;
+    }
+    else
+        name = NULL;
 
     return name;
 }
@@ -2120,13 +2128,10 @@ gnc_template_register_get_fdebt_entry (VirtualLocation virt_loc,
 {
     SplitRegister *reg = user_data;
     Split *split = gnc_split_register_get_split(reg, virt_loc.vcell_loc);
-    char *formula = NULL;
+    kvp_frame *kvpf = xaccSplitGetSlots(split);
 
-    qof_instance_get (QOF_INSTANCE (split),
-		      "sx-debit-formula", &formula,
-		      NULL);
-
-    return formula;
+    return kvp_value_get_string(
+               kvp_frame_get_slot_path (kvpf, "sched-xaction", "debit-formula", NULL));
 }
 
 static char *
@@ -2150,15 +2155,14 @@ gnc_template_register_get_fcred_entry (VirtualLocation virt_loc,
                                        gpointer user_data)
 {
     SplitRegister *reg = user_data;
-    Split *split = gnc_split_register_get_split(reg, virt_loc.vcell_loc);
-    char *formula = NULL;
-
-    qof_instance_get (QOF_INSTANCE (split),
-		      "sx-credit-formula", &formula,
-		      NULL);
+    kvp_frame *kvpf;
+    Split *split;
 
-    return formula;
+    split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
+    kvpf = xaccSplitGetSlots (split);
 
+    return kvp_value_get_string(
+               kvp_frame_get_slot_path (kvpf, "sched-xaction", "credit-formula", NULL));
 }
 
 static char *
@@ -2190,13 +2194,8 @@ gnc_template_register_get_debcred_entry (VirtualLocation virt_loc,
         gboolean *conditionally_changed,
         gpointer user_data)
 {
-    PERR("The function called always returned either NULL or an empty string "
-	 "while issuing dire warnings about how incorrect it is. That code "
-	 "has been removed and the function if called raises this error and "
-	 "returns NULL");
-    return NULL;
-#if 0
     SplitRegister *reg = user_data;
+    kvp_frame *kvpf;
     Split *split;
 
     split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
@@ -2242,7 +2241,6 @@ gnc_template_register_get_debcred_entry (VirtualLocation virt_loc,
     }
 
     return NULL;
-#endif
 }
 
 static void
diff --git a/src/report/report-gnome/gnc-plugin-page-report.c b/src/report/report-gnome/gnc-plugin-page-report.c
index 219f418..8878177 100644
--- a/src/report/report-gnome/gnc-plugin-page-report.c
+++ b/src/report/report-gnome/gnc-plugin-page-report.c
@@ -587,6 +587,7 @@ gnc_plugin_page_report_option_change_cb(gpointer data)
     SCM dirty_report = scm_c_eval_string("gnc:report-set-dirty?!");
     const gchar *old_name;
     gchar *new_name;
+    gchar *new_name_escaped;
 
     g_return_if_fail(GNC_IS_PLUGIN_PAGE_REPORT(data));
     report = GNC_PLUGIN_PAGE_REPORT(data);
@@ -602,7 +603,13 @@ gnc_plugin_page_report_option_change_cb(gpointer data)
     new_name = gnc_option_db_lookup_string_option(priv->cur_odb, "General",
                "Report name", NULL);
     if (strcmp(old_name, new_name) != 0)
-        main_window_update_page_name(GNC_PLUGIN_PAGE(report), new_name);
+    {
+        /* Bug 727130 - escape the non-printable characters from the name */
+        new_name_escaped = g_strescape(new_name,NULL);
+        ENTER("Escaped new report name: %s", new_name_escaped);
+        main_window_update_page_name(GNC_PLUGIN_PAGE(report), new_name_escaped);
+        g_free(new_name_escaped);
+	}
     g_free(new_name);
 
     /* it's probably already dirty, but make sure */
@@ -724,6 +731,7 @@ gnc_plugin_page_report_save_page (GncPluginPage *plugin_page,
     GncPluginPageReportPrivate *priv;
     SCM gen_save_text, scm_text;
     SCM get_embedded_list, embedded, item, tmp_report;
+    SCM  get_options;
     gint count, id;
     gchar *text, *key_name;
 
@@ -744,9 +752,10 @@ gnc_plugin_page_report_save_page (GncPluginPage *plugin_page,
         return;
     }
 
-    gen_save_text = scm_c_eval_string("gnc:report-generate-restore-forms");
+    gen_save_text = scm_c_eval_string("gnc:report-serialize");
     get_embedded_list = scm_c_eval_string("gnc:report-embedded-list");
-    embedded = scm_call_1(get_embedded_list, priv->cur_report);
+    get_options    = scm_c_eval_string("gnc:report-options");
+    embedded = scm_call_1(get_embedded_list, scm_call_1(get_options, priv->cur_report));
     count = scm_ilength(embedded);
     while (count-- > 0)
     {
@@ -889,12 +898,10 @@ static void
 gnc_plugin_page_report_name_changed (GncPluginPage *page, const gchar *name)
 {
     GncPluginPageReportPrivate *priv;
-    static gint count = 1, max_count = 10;
     const gchar *old_name;
 
     g_return_if_fail(GNC_IS_PLUGIN_PAGE_REPORT(page));
     g_return_if_fail(name != NULL);
-    g_return_if_fail(count++ <= max_count);
 
     ENTER("page %p, name %s", page, name);
     priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(page);
@@ -1028,14 +1035,14 @@ static GtkActionEntry report_actions[] =
         G_CALLBACK (gnc_plugin_page_report_reload_cb)
     },
     {
-        "ReportSaveAction", GTK_STOCK_SAVE, N_("Save _Report"), "<control><alt>s",
+        "ReportSaveAction", GTK_STOCK_SAVE, N_("Save _Report Configuration"), "<control><alt>s",
         N_("Update the current report's saved configuration. "
         "The report will be saved in the file ~/.gnucash/saved-reports-2.4. "),
         G_CALLBACK(gnc_plugin_page_report_save_cb)
     },
     {
-        "ReportSaveAsAction", GTK_STOCK_SAVE_AS, N_("Save Report As..."), "<control><alt><shift>s",
-        N_("Add the current report's configuration to the `Preconfigured Reports' menu. "
+        "ReportSaveAsAction", GTK_STOCK_SAVE_AS, N_("Save Report Configuration As..."), "<control><alt><shift>s",
+        N_("Add the current report's configuration to the `Saved Report Configurations' menu. "
         "The report will be saved in the file ~/.gnucash/saved-reports-2.4. "),
         G_CALLBACK(gnc_plugin_page_report_save_as_cb)
     },
@@ -1771,6 +1778,8 @@ gnc_plugin_page_report_print_cb( GtkAction *action, GncPluginPageReport *report
     g_free (job_name);
 }
 
+#define KVP_OWNER_EXPORT_PDF_DIRNAME "export-pdf-directory"
+
 static void
 gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *report )
 {
@@ -1778,6 +1787,7 @@ gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *rep
     gchar *job_name = report_create_jobname(priv);
     GncInvoice *invoice;
     GncOwner *owner = NULL;
+    KvpFrame *kvp = NULL;
 
     // Do we have an invoice report?
     invoice = lookup_invoice(priv);
@@ -1787,19 +1797,20 @@ gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *rep
         owner = (GncOwner*) gncInvoiceGetOwner(invoice);
         if (owner)
         {
-	    QofInstance *inst = qofOwnerGetOwner (owner);
-	    gchar *dirname = NULL;
-	    qof_instance_get (inst, "export-pdf-dir", &dirname, NULL);
             // Yes. In the kvp, look up the key for the Export-PDF output
             // directory. If it exists, prepend this to the job name so that
             // we can export to PDF.
-	    if (dirname && g_file_test(dirname,
-				       G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
-	    {
-		gchar *tmp = g_build_filename(dirname, job_name, NULL);
-		g_free(job_name);
-		job_name = tmp;
-	    }
+            kvp = gncOwnerGetSlots(owner);
+            if (kvp)
+            {
+                const char *dirname = kvp_frame_get_string(kvp, KVP_OWNER_EXPORT_PDF_DIRNAME);
+                if (dirname && g_file_test(dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
+                {
+                    gchar *tmp = g_build_filename(dirname, job_name, NULL);
+                    g_free(job_name);
+                    job_name = tmp;
+                }
+            }
         }
     }
 
@@ -1807,12 +1818,10 @@ gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *rep
 
     gnc_html_print(priv->html, job_name, TRUE);
 
-    if (owner)
+    if (owner && kvp)
     {
-	/* As this is an invoice report with some owner, we will try
-	 * to look up the chosen output directory from the print
-	 * settings and store it again in the owner kvp.
-	 */
+        // As this is an invoice report with some owner, we will try to look up the
+        // chosen output directory from the print settings and store it again in the owner kvp.
         GtkPrintSettings *print_settings = gnc_print_get_settings();
         if (print_settings &&
 	    gtk_print_settings_has_key(print_settings,
@@ -1823,10 +1832,15 @@ gnc_plugin_page_report_exportpdf_cb( GtkAction *action, GncPluginPageReport *rep
             // Only store the directory if it exists.
             if (g_file_test(dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
             {
-                QofInstance *inst = qofOwnerGetOwner(owner);
-                gncOwnerBeginEdit(owner);
-		qof_instance_set (inst, "export-pdf-dir", dirname);
-		gncOwnerCommitEdit(owner);
+                QofInstance *qofinstance = qofOwnerGetOwner(owner);
+                if (qofinstance)
+		{
+		    gncOwnerBeginEdit(owner);
+		    kvp_frame_set_string(kvp, KVP_OWNER_EXPORT_PDF_DIRNAME,
+					 dirname);
+                    qof_instance_set_dirty(qofinstance);
+		    qof_commit_edit (qofinstance);
+		}
             }
         }
     }
diff --git a/test-templates/Makefile.decl b/test-templates/Makefile.decl
index 0f163a3..dcc69c1 100644
--- a/test-templates/Makefile.decl
+++ b/test-templates/Makefile.decl
@@ -23,7 +23,7 @@ endif
 # test-nonrecursive: run tests only in cwd
 test-nonrecursive: ${TEST_PROGS}
 if !PLATFORM_WIN32
-	@test -z "${TEST_PROGS}" || MALLOC_CHECK_=2 MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) ${TESTS_ENVIRONMENT} ${GTESTER} --verbose ${TEST_PROGS}
+	@test -z "${TEST_PROGS}" || MALLOC_CHECK_=2 MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) ${GTESTER} --verbose ${TEST_PROGS}
 endif
 
 # test-report: run tests in subdirs and generate report

commit 9d4051230721883f70ed03de9fad99a314f4a4e5
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Wed May 7 17:57:47 2014 +0200

    Revert "Fix typo in test-engine-kvp-properties."
    
    This reverts commit ac9a6ae606e67f8ca7a7fffd75a7f6c8dcc75060.

diff --git a/src/engine/test/test-engine-kvp-properties.c b/src/engine/test/test-engine-kvp-properties.c
index 97b0efe..8b95526 100644
--- a/src/engine/test/test-engine-kvp-properties.c
+++ b/src/engine/test/test-engine-kvp-properties.c
@@ -35,7 +35,7 @@
 #include "../Transaction.h"
 #include "../Split.h"
 #include "../Account.h"
-#include "../SchedXaction.h"
+#include "../SchedXAction.h"
 #include "../gncCustomer.h"
 #include "../gncEmployee.h"
 #include "../gncJob.h"

commit ec9bd763d133c07a26c741fadd5309aee7b70630
Author: Geert Janssens <janssens-geert at telenet.be>
Date:   Wed May 7 17:57:28 2014 +0200

    Revert "Fix bad qof_instance crash in dialog-payments"
    
    This reverts commit edd85faad75055231cc58779d2c677fc61cc9492.

diff --git a/src/business/business-gnome/dialog-payment.c b/src/business/business-gnome/dialog-payment.c
index ae6e0a7..151f678 100644
--- a/src/business/business-gnome/dialog-payment.c
+++ b/src/business/business-gnome/dialog-payment.c
@@ -458,7 +458,7 @@ gnc_payment_dialog_owner_changed (PaymentWindow *pw)
     pw->invoice = NULL;
 
     /* Now handle the account tree */
-    qof_instance_get (qofOwnerGetOwner (owner),
+    qof_instance_get (QOF_INSTANCE (owner),
 		      "payment-last-account", &guid,
 		      NULL);
 
@@ -506,17 +506,17 @@ gnc_payment_dialog_post_to_changed (PaymentWindow *pw)
 static void
 gnc_payment_dialog_remember_account (PaymentWindow *pw, Account *acc)
 {
-     QofInstance *owner = qofOwnerGetOwner (&pw->owner);
+    GncOwner *owner = &pw->owner;
     const GncGUID *guid;
 
     if (!acc) return;
 
     guid = xaccAccountGetGUID(acc);
-    qof_begin_edit (owner);
-    qof_instance_set (owner,
+    qof_begin_edit (QOF_INSTANCE (owner));
+    qof_instance_set (QOF_INSTANCE (owner),
 		      "payment-last-account", guid,
 		      NULL);
-    qof_commit_edit (owner);
+    qof_commit_edit (QOF_INSTANCE (owner));
 }
 
 



Summary of changes:
 src/import-export/CMakeLists.txt                 |   2 +
 src/import-export/import-match-map.c             | 545 -----------------------
 src/import-export/import-utilities.c             |   2 -
 src/libqof/qof/qofbook.cpp                       |   2 +-
 src/libqof/qof/qoflog.cpp                        |   4 +-
 src/libqof/qof/test/test-kvp_frame.c             |   2 +-
 src/report/report-gnome/gnc-plugin-page-report.c |  23 +-
 7 files changed, 21 insertions(+), 559 deletions(-)
 delete mode 100644 src/import-export/import-match-map.c



More information about the gnucash-changes mailing list