gnucash master: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Thu Jun 9 18:42:30 EDT 2016


Updated	 via  https://github.com/Gnucash/gnucash/commit/2bbc1a19 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/949ff816 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ce190e34 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1c00937a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/293a2866 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/74800e18 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/0ee7e61b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3063c873 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/557a5e2f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/33908860 (commit)
	from  https://github.com/Gnucash/gnucash/commit/9f3dc0c8 (commit)



commit 2bbc1a193d582a6f1a9b7a95391485af09fd3e6a
Merge: 949ff81 ce190e3
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Jun 9 15:29:45 2016 -0700

    Merge branch 'guid_header'


commit 949ff816d6997a0ba443e3921c61d436a622d16c
Merge: 9f3dc0c 0ee7e61
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Jun 9 15:29:10 2016 -0700

    Merge branch 'session-refactor'


commit ce190e34856baba21896ba28efb7fe8beebcce70
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Jun 9 15:28:39 2016 -0700

    Some minor fixups to resolve clang warning and errors from session-refactor.

diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index f3ae101..ab00254 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -83,7 +83,7 @@ gnc_value_get_guid (const GValue *value)
     return val;
 }
 
-static GncGUID s_null_guid {{0}};
+static GncGUID s_null_guid {{{0}}};
 
 /*It looks like we are expected to provide the same pointer every time from this function*/
 const GncGUID *
diff --git a/src/libqof/qof/test/test-qofsession-old.cpp b/src/libqof/qof/test/test-qofsession-old.cpp
index 537cb80..f61baaa 100644
--- a/src/libqof/qof/test/test-qofsession-old.cpp
+++ b/src/libqof/qof/test/test-qofsession-old.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
+#include "../guid.hpp"
 extern "C"
 {
 #include "config.h"
diff --git a/src/libqof/qof/test/test-qofsession.cpp b/src/libqof/qof/test/test-qofsession.cpp
index 0262ff1..0b5cd22 100644
--- a/src/libqof/qof/test/test-qofsession.cpp
+++ b/src/libqof/qof/test/test-qofsession.cpp
@@ -23,10 +23,10 @@
  ********************************************************************/
 
 #include <gtest/gtest.h>
+#include "../guid.hpp"
 #include <qofsession.hpp>
 #include "qofbackend-p.h"
 #include <cstdlib>
-#include "../guid.hpp"
 #include "../gnc-backend-prov.hpp"
 
 static QofBook * exported_book {nullptr};

commit 1c00937abe924c8d2f4cefb10af46f94badecc3b
Author: lmat <dartme18 at gmail.com>
Date:   Tue Jun 7 18:06:02 2016 -0400

    Clean up guid usage.
    
    Now that there is a subclass of boost::uuids::uuid, that subclass can be
    used for GncGUID implementation. This removes the need for the untidy
    casts to/from bost::uuids::uuid, and simplifies the logic in many areas.

diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index 5deaaea..f3ae101 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -59,8 +59,6 @@ extern "C"
 #include <sstream>
 #include <string>
 
-using namespace std;
-
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = QOF_MOD_ENGINE;
 
@@ -74,6 +72,7 @@ static QofLogModule log_module = QOF_MOD_ENGINE;
 const GncGUID*
 gnc_value_get_guid (const GValue *value)
 {
+    if (!value) return nullptr;
     GncGUID *val;
 
     g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
@@ -98,74 +97,52 @@ guid_null (void)
 GncGUID *
 guid_malloc (void)
 {
-    /*Note, the Boost uuid is a POD, so its constructor is trivial*/
-    return reinterpret_cast<GncGUID*> (new boost::uuids::uuid);
+    return new GncGUID;
 }
 
 void
 guid_free (GncGUID *guid)
 {
-    if (!guid)
-        return;
+    if (!guid) return;
     if (guid == &s_null_guid)
         /*!!Don't delete that!!*/
         return;
-    delete reinterpret_cast<boost::uuids::uuid*> (guid);
-    guid = nullptr;
+    delete guid;
 }
 
-
 GncGUID *
 guid_copy (const GncGUID *guid)
 {
-    const boost::uuids::uuid * old {reinterpret_cast<const boost::uuids::uuid*> (guid)};
-    boost::uuids::uuid * ret {new boost::uuids::uuid (*old)};
-    return reinterpret_cast<GncGUID*> (ret);
+    if (!guid) return nullptr;
+    return new GncGUID {*guid};
 }
 
 /*Takes an allocated guid pointer and constructs it in place*/
 void
 guid_replace (GncGUID *guid)
 {
-    static boost::uuids::random_generator gen;
-    boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)};
-    val->boost::uuids::uuid::~uuid ();
-    boost::uuids::uuid temp (gen ());
-    val->swap (temp);
+    if (!guid) return;
+    auto other = GncGUID::create_random();
+    guid->swap (other);
 }
 
 GncGUID *
 guid_new (void)
 {
-    GncGUID * ret {guid_malloc ()};
-    guid_replace (ret);
-    return ret;
+    return new GncGUID {GncGUID::create_random ()};
 }
 
 GncGUID
 guid_new_return (void)
 {
-    /*we need to construct our value as a boost guid so that
-    it can be deconstructed (in place) in guid_replace*/
-    boost::uuids::uuid guid;
-    GncGUID * ret {reinterpret_cast<GncGUID*> (&guid)};
-    guid_replace (ret);
-    /*return a copy*/
-    return *ret;
+    return GncGUID::create_random ();
 }
 
 gchar *
 guid_to_string (const GncGUID * guid)
 {
-    /* We need to malloc here, not 'new' because it will be freed
-    by the caller which will use free (not delete).*/
-    gchar * ret {reinterpret_cast<gchar*> (g_malloc (sizeof (gchar)*GUID_ENCODING_LENGTH+1))};
-    gchar * temp {guid_to_string_buff (guid, ret)};
-    if (!temp){
-        g_free (ret);
-        return nullptr;
-    }
-    return ret;
+    if (!guid) return nullptr;
+    return g_strdup (guid->to_string ().c_str ());
 }
 
 gchar *
@@ -173,28 +150,21 @@ guid_to_string_buff (const GncGUID * guid, gchar *str)
 {
     if (!str || !guid) return NULL;
 
-    boost::uuids::uuid const & tempg = *reinterpret_cast<boost::uuids::uuid const *> (guid);
-    unsigned destspot {0};
-    string const & val {to_string (tempg)};
-    for (auto val_char : val)
-        if (val_char != '-')
-            str [destspot++] = val_char;
-
-    str[GUID_ENCODING_LENGTH] = '\0';
-    return &str[GUID_ENCODING_LENGTH];
+    auto val = guid->to_string ();
+    /*We need to be sure to copy the terminating null character.*/
+    std::copy (val.c_str (), val.c_str() + val.size () + 1, str);
+    return str + val.size();
 }
 
 gboolean
 string_to_guid (const char * str, GncGUID * guid)
 {
-    if (!guid || !str)
-        return false;
+    if (!guid || !str) return false;
 
     try
     {
-        static boost::uuids::string_generator strgen;
-        boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)};
-        new (converted) boost::uuids::uuid (strgen (str));
+        auto other = GncGUID::from_string (str);
+        guid->swap (other);
     }
     catch (...)
     {
@@ -207,20 +177,16 @@ gboolean
 guid_equal (const GncGUID *guid_1, const GncGUID *guid_2)
 {
     if (!guid_1 || !guid_2)
-        return false;
-    boost::uuids::uuid const * g1 {reinterpret_cast<boost::uuids::uuid const *> (guid_1)};
-    boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (guid_2)};
-    return *g1 == *g2;
+        return !guid_1 && !guid_2;
+    return *guid_1 == *guid_2;
 }
 
 gint
 guid_compare (const GncGUID *guid_1, const GncGUID *guid_2)
 {
-    boost::uuids::uuid const * g1 {reinterpret_cast<boost::uuids::uuid const *> (guid_1)};
-    boost::uuids::uuid const * g2 {reinterpret_cast<boost::uuids::uuid const *> (guid_2)};
-    if (*g1 < *g2)
+    if (*guid_1 < *guid_2)
         return -1;
-    if (*g1 == *g2)
+    if (*guid_1 == *guid_2)
         return 0;
     return 1;
 }
@@ -228,21 +194,19 @@ guid_compare (const GncGUID *guid_1, const GncGUID *guid_2)
 guint
 guid_hash_to_guint (gconstpointer ptr)
 {
-    const boost::uuids::uuid * guid = reinterpret_cast<const boost::uuids::uuid*> (ptr);
-
-    if (!guid)
+    if (!ptr)
     {
         PERR ("received NULL guid pointer.");
         return 0;
     }
+    GncGUID const & guid = * reinterpret_cast <GncGUID const *> (ptr);
 
     guint hash {0};
     unsigned retspot {0};
-    for (auto guidspot : *guid)
-    {
-        hash <<= 4;
-        hash |= guidspot;
-    }
+    std::for_each (guid.begin (), guid.end (), [&hash] (unsigned char a) {
+        hash <<=4;
+        hash |= a;
+    });
     return hash;
 }
 
@@ -321,10 +285,6 @@ GncGUID::create_random () noexcept
     return {gen ()};
 }
 
-GncGUID::GncGUID () noexcept
-{
-}
-
 GncGUID::GncGUID (boost::uuids::uuid const & other) noexcept
     : boost::uuids::uuid (other)
 {
diff --git a/src/libqof/qof/guid.hpp b/src/libqof/qof/guid.hpp
index bc59625..f33c58b 100644
--- a/src/libqof/qof/guid.hpp
+++ b/src/libqof/qof/guid.hpp
@@ -33,7 +33,7 @@ struct guid_syntax_exception : public std::invalid_argument
 struct GncGUID : public boost::uuids::uuid
 {
     GncGUID (boost::uuids::uuid const &) noexcept;
-    GncGUID () noexcept;
+    GncGUID () noexcept = default;
     static GncGUID create_random () noexcept;
     static GncGUID const & null_guid () noexcept;
     static GncGUID from_string (std::string const &) throw (guid_syntax_exception);

commit 293a286693bb3330906b7195b3dfb16d23518a13
Author: lmat <dartme18 at gmail.com>
Date:   Tue Jun 7 10:39:46 2016 -0400

    Add C++ header for guid.cpp and tests.

diff --git a/src/app-utils/test/test-option-util.cpp b/src/app-utils/test/test-option-util.cpp
index 7bc7b9b..db25596 100644
--- a/src/app-utils/test/test-option-util.cpp
+++ b/src/app-utils/test/test-option-util.cpp
@@ -21,6 +21,7 @@
  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  ********************************************************************/
+#include <guid.hpp>
 #include <kvp_frame.hpp>
 #include <gmp.h> 
 extern "C"
diff --git a/src/app-utils/test/test-print-parse-amount.cpp b/src/app-utils/test/test-print-parse-amount.cpp
index 728cbcf..5941897 100644
--- a/src/app-utils/test/test-print-parse-amount.cpp
+++ b/src/app-utils/test/test-print-parse-amount.cpp
@@ -18,6 +18,7 @@
  *                                                                  *
 \********************************************************************/
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/app-utils/test/test-scm-query-string.cpp b/src/app-utils/test/test-scm-query-string.cpp
index 33f963e..460d1ba 100644
--- a/src/app-utils/test/test-scm-query-string.cpp
+++ b/src/app-utils/test/test-scm-query-string.cpp
@@ -18,6 +18,7 @@
  *                                                                  *
 \********************************************************************/
 
+#include <guid.hpp>
 #include <libguile.h>
 
 extern "C"
diff --git a/src/app-utils/test/test-sx.cpp b/src/app-utils/test/test-sx.cpp
index 027731b..f3028fa 100644
--- a/src/app-utils/test/test-sx.cpp
+++ b/src/app-utils/test/test-sx.cpp
@@ -18,6 +18,7 @@
  *                                                                  *
 \********************************************************************/
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/dbi/gnc-backend-dbi.cpp b/src/backend/dbi/gnc-backend-dbi.cpp
index beec3ca..902f8a2 100644
--- a/src/backend/dbi/gnc-backend-dbi.cpp
+++ b/src/backend/dbi/gnc-backend-dbi.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db using libdbi
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/dbi/test/test-backend-dbi-basic.cpp b/src/backend/dbi/test/test-backend-dbi-basic.cpp
index b0112d7..02fc7bc 100644
--- a/src/backend/dbi/test/test-backend-dbi-basic.cpp
+++ b/src/backend/dbi/test/test-backend-dbi-basic.cpp
@@ -24,6 +24,7 @@
  *                                                                  *
 \********************************************************************/
 
+#include <guid.hpp>
 #include <kvp_frame.hpp>
 
 extern "C"
diff --git a/src/backend/dbi/test/test-backend-dbi.cpp b/src/backend/dbi/test/test-backend-dbi.cpp
index 6bf6785..209c88d 100644
--- a/src/backend/dbi/test/test-backend-dbi.cpp
+++ b/src/backend/dbi/test/test-backend-dbi.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/dbi/test/test-dbi-business-stuff.cpp b/src/backend/dbi/test/test-dbi-business-stuff.cpp
index 6461f41..ae5d440 100644
--- a/src/backend/dbi/test/test-dbi-business-stuff.cpp
+++ b/src/backend/dbi/test/test-dbi-business-stuff.cpp
@@ -22,6 +22,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/dbi/test/test-dbi-stuff.cpp b/src/backend/dbi/test/test-dbi-stuff.cpp
index 58526af..56cd329 100644
--- a/src/backend/dbi/test/test-dbi-stuff.cpp
+++ b/src/backend/dbi/test/test-dbi-stuff.cpp
@@ -22,6 +22,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include <config.h>
diff --git a/src/backend/sql/escape.cpp b/src/backend/sql/escape.cpp
index 5c4103c..704e414 100644
--- a/src/backend/sql/escape.cpp
+++ b/src/backend/sql/escape.cpp
@@ -27,6 +27,7 @@
  * FUNCTION:
  * Escapes the ' and \ characters in a string
  */
+#include <guid.hpp>
 
 #include "config.h"
 #include <glib.h>
diff --git a/src/backend/sql/gnc-account-sql.cpp b/src/backend/sql/gnc-account-sql.cpp
index 226f385..4c5fe83 100644
--- a/src/backend/sql/gnc-account-sql.cpp
+++ b/src/backend/sql/gnc-account-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-address-sql.cpp b/src/backend/sql/gnc-address-sql.cpp
index bca6be7..5c6455c 100644
--- a/src/backend/sql/gnc-address-sql.cpp
+++ b/src/backend/sql/gnc-address-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-backend-sql.cpp b/src/backend/sql/gnc-backend-sql.cpp
index f57fbee..973de93 100644
--- a/src/backend/sql/gnc-backend-sql.cpp
+++ b/src/backend/sql/gnc-backend-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include <stdlib.h>
diff --git a/src/backend/sql/gnc-bill-term-sql.cpp b/src/backend/sql/gnc-bill-term-sql.cpp
index a881eda..ce7462b 100644
--- a/src/backend/sql/gnc-bill-term-sql.cpp
+++ b/src/backend/sql/gnc-bill-term-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-book-sql.cpp b/src/backend/sql/gnc-book-sql.cpp
index 9c47987..ddf4a5f 100644
--- a/src/backend/sql/gnc-book-sql.cpp
+++ b/src/backend/sql/gnc-book-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-budget-sql.cpp b/src/backend/sql/gnc-budget-sql.cpp
index 599208d..da50067 100644
--- a/src/backend/sql/gnc-budget-sql.cpp
+++ b/src/backend/sql/gnc-budget-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-commodity-sql.cpp b/src/backend/sql/gnc-commodity-sql.cpp
index 11a8c61..cb757fb 100644
--- a/src/backend/sql/gnc-commodity-sql.cpp
+++ b/src/backend/sql/gnc-commodity-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-customer-sql.cpp b/src/backend/sql/gnc-customer-sql.cpp
index 05ff4bf..ba67acf 100644
--- a/src/backend/sql/gnc-customer-sql.cpp
+++ b/src/backend/sql/gnc-customer-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-employee-sql.cpp b/src/backend/sql/gnc-employee-sql.cpp
index ce28239..ee0b2ef 100644
--- a/src/backend/sql/gnc-employee-sql.cpp
+++ b/src/backend/sql/gnc-employee-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-entry-sql.cpp b/src/backend/sql/gnc-entry-sql.cpp
index 88a43d8..11dd17c 100644
--- a/src/backend/sql/gnc-entry-sql.cpp
+++ b/src/backend/sql/gnc-entry-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-invoice-sql.cpp b/src/backend/sql/gnc-invoice-sql.cpp
index cef0763..cbcab3e 100644
--- a/src/backend/sql/gnc-invoice-sql.cpp
+++ b/src/backend/sql/gnc-invoice-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-job-sql.cpp b/src/backend/sql/gnc-job-sql.cpp
index 1a42eb5..baa16c3 100644
--- a/src/backend/sql/gnc-job-sql.cpp
+++ b/src/backend/sql/gnc-job-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-lots-sql.cpp b/src/backend/sql/gnc-lots-sql.cpp
index 1a271f4..e8005ba 100644
--- a/src/backend/sql/gnc-lots-sql.cpp
+++ b/src/backend/sql/gnc-lots-sql.cpp
@@ -26,6 +26,7 @@
  * restoring data to/from an SQL db
  */
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-order-sql.cpp b/src/backend/sql/gnc-order-sql.cpp
index 7512baf..77a1cb1 100644
--- a/src/backend/sql/gnc-order-sql.cpp
+++ b/src/backend/sql/gnc-order-sql.cpp
@@ -28,6 +28,7 @@
  * restoring data to/from an SQL database
  */
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-owner-sql.cpp b/src/backend/sql/gnc-owner-sql.cpp
index f4696d2..9b8e24a 100644
--- a/src/backend/sql/gnc-owner-sql.cpp
+++ b/src/backend/sql/gnc-owner-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-price-sql.cpp b/src/backend/sql/gnc-price-sql.cpp
index c061120..5e2370b 100644
--- a/src/backend/sql/gnc-price-sql.cpp
+++ b/src/backend/sql/gnc-price-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-recurrence-sql.cpp b/src/backend/sql/gnc-recurrence-sql.cpp
index 17e60be..7f18877 100644
--- a/src/backend/sql/gnc-recurrence-sql.cpp
+++ b/src/backend/sql/gnc-recurrence-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-schedxaction-sql.cpp b/src/backend/sql/gnc-schedxaction-sql.cpp
index 9cce493..5b3869f 100644
--- a/src/backend/sql/gnc-schedxaction-sql.cpp
+++ b/src/backend/sql/gnc-schedxaction-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-slots-sql.cpp b/src/backend/sql/gnc-slots-sql.cpp
index 06983ba..56febc9 100644
--- a/src/backend/sql/gnc-slots-sql.cpp
+++ b/src/backend/sql/gnc-slots-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-tax-table-sql.cpp b/src/backend/sql/gnc-tax-table-sql.cpp
index 4f56eea..8154edc 100644
--- a/src/backend/sql/gnc-tax-table-sql.cpp
+++ b/src/backend/sql/gnc-tax-table-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-transaction-sql.cpp b/src/backend/sql/gnc-transaction-sql.cpp
index ec8ad34..a3d93dc 100644
--- a/src/backend/sql/gnc-transaction-sql.cpp
+++ b/src/backend/sql/gnc-transaction-sql.cpp
@@ -25,6 +25,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL db
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/gnc-vendor-sql.cpp b/src/backend/sql/gnc-vendor-sql.cpp
index 70935ed..d6ccbb3 100644
--- a/src/backend/sql/gnc-vendor-sql.cpp
+++ b/src/backend/sql/gnc-vendor-sql.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an SQL database
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/test/test-column-types.cpp b/src/backend/sql/test/test-column-types.cpp
index 0189001..0084ce9 100644
--- a/src/backend/sql/test/test-column-types.cpp
+++ b/src/backend/sql/test/test-column-types.cpp
@@ -23,6 +23,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/test/test-sqlbe.cpp b/src/backend/sql/test/test-sqlbe.cpp
index 0b3d12e..cc3a056 100644
--- a/src/backend/sql/test/test-sqlbe.cpp
+++ b/src/backend/sql/test/test-sqlbe.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/sql/test/utest-gnc-backend-sql.cpp b/src/backend/sql/test/utest-gnc-backend-sql.cpp
index 9e474b5..236ddb5 100644
--- a/src/backend/sql/test/utest-gnc-backend-sql.cpp
+++ b/src/backend/sql/test/utest-gnc-backend-sql.cpp
@@ -20,6 +20,7 @@
  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-account-xml-v2.cpp b/src/backend/xml/gnc-account-xml-v2.cpp
index 72e70ba..92cd1db 100644
--- a/src/backend/xml/gnc-account-xml-v2.cpp
+++ b/src/backend/xml/gnc-account-xml-v2.cpp
@@ -22,6 +22,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-address-xml-v2.cpp b/src/backend/xml/gnc-address-xml-v2.cpp
index 90dcf69..ef3dc81 100644
--- a/src/backend/xml/gnc-address-xml-v2.cpp
+++ b/src/backend/xml/gnc-address-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-backend-xml.cpp b/src/backend/xml/gnc-backend-xml.cpp
index 91bc094..a78dd1f 100644
--- a/src/backend/xml/gnc-backend-xml.cpp
+++ b/src/backend/xml/gnc-backend-xml.cpp
@@ -27,6 +27,7 @@
  * This file implements the top-level QofBackend API for saving/
  * restoring data to/from an ordinary Unix filesystem file.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-bill-term-xml-v2.cpp b/src/backend/xml/gnc-bill-term-xml-v2.cpp
index 5bee3cd..65db438 100644
--- a/src/backend/xml/gnc-bill-term-xml-v2.cpp
+++ b/src/backend/xml/gnc-bill-term-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-book-xml-v2.cpp b/src/backend/xml/gnc-book-xml-v2.cpp
index 868dc35..43bced8 100644
--- a/src/backend/xml/gnc-book-xml-v2.cpp
+++ b/src/backend/xml/gnc-book-xml-v2.cpp
@@ -22,6 +22,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-budget-xml-v2.cpp b/src/backend/xml/gnc-budget-xml-v2.cpp
index 93b9163..a5efa92 100644
--- a/src/backend/xml/gnc-budget-xml-v2.cpp
+++ b/src/backend/xml/gnc-budget-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org
  */
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-commodity-xml-v2.cpp b/src/backend/xml/gnc-commodity-xml-v2.cpp
index 69d7f18..8fd980c 100644
--- a/src/backend/xml/gnc-commodity-xml-v2.cpp
+++ b/src/backend/xml/gnc-commodity-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-customer-xml-v2.cpp b/src/backend/xml/gnc-customer-xml-v2.cpp
index 74cc13e..18f0720 100644
--- a/src/backend/xml/gnc-customer-xml-v2.cpp
+++ b/src/backend/xml/gnc-customer-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-employee-xml-v2.cpp b/src/backend/xml/gnc-employee-xml-v2.cpp
index d8f8be2..96ec1f5 100644
--- a/src/backend/xml/gnc-employee-xml-v2.cpp
+++ b/src/backend/xml/gnc-employee-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-entry-xml-v2.cpp b/src/backend/xml/gnc-entry-xml-v2.cpp
index 4466201..982b402 100644
--- a/src/backend/xml/gnc-entry-xml-v2.cpp
+++ b/src/backend/xml/gnc-entry-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-freqspec-xml-v2.cpp b/src/backend/xml/gnc-freqspec-xml-v2.cpp
index 3b11029..ac33572 100644
--- a/src/backend/xml/gnc-freqspec-xml-v2.cpp
+++ b/src/backend/xml/gnc-freqspec-xml-v2.cpp
@@ -22,6 +22,7 @@
  *                                                                  *
  *******************************************************************/
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-invoice-xml-v2.cpp b/src/backend/xml/gnc-invoice-xml-v2.cpp
index 4cf3fbd..2ef9065 100644
--- a/src/backend/xml/gnc-invoice-xml-v2.cpp
+++ b/src/backend/xml/gnc-invoice-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-job-xml-v2.cpp b/src/backend/xml/gnc-job-xml-v2.cpp
index 9239376..be33e23 100644
--- a/src/backend/xml/gnc-job-xml-v2.cpp
+++ b/src/backend/xml/gnc-job-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-lot-xml-v2.cpp b/src/backend/xml/gnc-lot-xml-v2.cpp
index 696a466..03d1e9e 100644
--- a/src/backend/xml/gnc-lot-xml-v2.cpp
+++ b/src/backend/xml/gnc-lot-xml-v2.cpp
@@ -22,6 +22,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-order-xml-v2.cpp b/src/backend/xml/gnc-order-xml-v2.cpp
index 12512c7..7afb347 100644
--- a/src/backend/xml/gnc-order-xml-v2.cpp
+++ b/src/backend/xml/gnc-order-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-owner-xml-v2.cpp b/src/backend/xml/gnc-owner-xml-v2.cpp
index b17923a..78d7157 100644
--- a/src/backend/xml/gnc-owner-xml-v2.cpp
+++ b/src/backend/xml/gnc-owner-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-pricedb-xml-v2.cpp b/src/backend/xml/gnc-pricedb-xml-v2.cpp
index 1c5240c..232754c 100644
--- a/src/backend/xml/gnc-pricedb-xml-v2.cpp
+++ b/src/backend/xml/gnc-pricedb-xml-v2.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  *******************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-recurrence-xml-v2.cpp b/src/backend/xml/gnc-recurrence-xml-v2.cpp
index b3e817a..a973555 100644
--- a/src/backend/xml/gnc-recurrence-xml-v2.cpp
+++ b/src/backend/xml/gnc-recurrence-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org
  */
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-schedxaction-xml-v2.cpp b/src/backend/xml/gnc-schedxaction-xml-v2.cpp
index f719cde..c399e05 100644
--- a/src/backend/xml/gnc-schedxaction-xml-v2.cpp
+++ b/src/backend/xml/gnc-schedxaction-xml-v2.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  *******************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-tax-table-xml-v2.cpp b/src/backend/xml/gnc-tax-table-xml-v2.cpp
index 183fe3a..27f2e7d 100644
--- a/src/backend/xml/gnc-tax-table-xml-v2.cpp
+++ b/src/backend/xml/gnc-tax-table-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-transaction-xml-v2.cpp b/src/backend/xml/gnc-transaction-xml-v2.cpp
index 4992fac..2f08e74 100644
--- a/src/backend/xml/gnc-transaction-xml-v2.cpp
+++ b/src/backend/xml/gnc-transaction-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  *******************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/gnc-vendor-xml-v2.cpp b/src/backend/xml/gnc-vendor-xml-v2.cpp
index f897502..447e078 100644
--- a/src/backend/xml/gnc-vendor-xml-v2.cpp
+++ b/src/backend/xml/gnc-vendor-xml-v2.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/io-example-account.cpp b/src/backend/xml/io-example-account.cpp
index c024d6a..95b61a3 100644
--- a/src/backend/xml/io-example-account.cpp
+++ b/src/backend/xml/io-example-account.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/io-gncxml-gen.cpp b/src/backend/xml/io-gncxml-gen.cpp
index 6accc4a..440c36f 100644
--- a/src/backend/xml/io-gncxml-gen.cpp
+++ b/src/backend/xml/io-gncxml-gen.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/io-gncxml-v1.cpp b/src/backend/xml/io-gncxml-v1.cpp
index 74aae4f..bec03b9 100644
--- a/src/backend/xml/io-gncxml-v1.cpp
+++ b/src/backend/xml/io-gncxml-v1.cpp
@@ -24,6 +24,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  *******************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/io-gncxml-v2.cpp b/src/backend/xml/io-gncxml-v2.cpp
index 80958bc..61de9d2 100644
--- a/src/backend/xml/io-gncxml-v2.cpp
+++ b/src/backend/xml/io-gncxml-v2.cpp
@@ -18,6 +18,7 @@
  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/io-utils.cpp b/src/backend/xml/io-utils.cpp
index 72c3563..1b1293a 100644
--- a/src/backend/xml/io-utils.cpp
+++ b/src/backend/xml/io-utils.cpp
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/sixtp-dom-generators.cpp b/src/backend/xml/sixtp-dom-generators.cpp
index 1db5895..c2b298d 100644
--- a/src/backend/xml/sixtp-dom-generators.cpp
+++ b/src/backend/xml/sixtp-dom-generators.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #define __EXTENSIONS__
diff --git a/src/backend/xml/sixtp-dom-parsers.cpp b/src/backend/xml/sixtp-dom-parsers.cpp
index 7f1b93c..1848b14 100644
--- a/src/backend/xml/sixtp-dom-parsers.cpp
+++ b/src/backend/xml/sixtp-dom-parsers.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/sixtp-stack.cpp b/src/backend/xml/sixtp-stack.cpp
index 4aea535..5f86008 100644
--- a/src/backend/xml/sixtp-stack.cpp
+++ b/src/backend/xml/sixtp-stack.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/sixtp-to-dom-parser.cpp b/src/backend/xml/sixtp-to-dom-parser.cpp
index 5404952..5c2331f 100644
--- a/src/backend/xml/sixtp-to-dom-parser.cpp
+++ b/src/backend/xml/sixtp-to-dom-parser.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/sixtp-utils.cpp b/src/backend/xml/sixtp-utils.cpp
index 1b99b6d..a0d9d86 100644
--- a/src/backend/xml/sixtp-utils.cpp
+++ b/src/backend/xml/sixtp-utils.cpp
@@ -22,6 +22,7 @@
  ********************************************************************/
 
 #define __EXTENSIONS__
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/sixtp.cpp b/src/backend/xml/sixtp.cpp
index 10b4be8..d19e49a 100644
--- a/src/backend/xml/sixtp.cpp
+++ b/src/backend/xml/sixtp.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
  ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-date-converting.cpp b/src/backend/xml/test/test-date-converting.cpp
index 46c2bc6..4c94171 100644
--- a/src/backend/xml/test/test-date-converting.cpp
+++ b/src/backend/xml/test/test-date-converting.cpp
@@ -17,7 +17,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
-
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-dom-converters1.cpp b/src/backend/xml/test/test-dom-converters1.cpp
index c577f9a..4725408 100644
--- a/src/backend/xml/test/test-dom-converters1.cpp
+++ b/src/backend/xml/test/test-dom-converters1.cpp
@@ -21,6 +21,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-file-stuff.cpp b/src/backend/xml/test/test-file-stuff.cpp
index a6bbf80..59556c0 100644
--- a/src/backend/xml/test/test-file-stuff.cpp
+++ b/src/backend/xml/test/test-file-stuff.cpp
@@ -20,6 +20,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 #include <kvp_frame.hpp>
 
 extern "C"
diff --git a/src/backend/xml/test/test-kvp-frames.cpp b/src/backend/xml/test/test-kvp-frames.cpp
index 2a483d1..fac1f15 100644
--- a/src/backend/xml/test/test-kvp-frames.cpp
+++ b/src/backend/xml/test/test-kvp-frames.cpp
@@ -1,3 +1,4 @@
+#include <guid.hpp>
 #include <kvp_frame.hpp>
 
 extern "C"
diff --git a/src/backend/xml/test/test-load-backend.cpp b/src/backend/xml/test/test-load-backend.cpp
index b891743..475e0f3 100644
--- a/src/backend/xml/test/test-load-backend.cpp
+++ b/src/backend/xml/test/test-load-backend.cpp
@@ -24,6 +24,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-load-example-account.cpp b/src/backend/xml/test/test-load-example-account.cpp
index c098e81..356ba0f 100644
--- a/src/backend/xml/test/test-load-example-account.cpp
+++ b/src/backend/xml/test/test-load-example-account.cpp
@@ -20,6 +20,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-load-xml2.cpp b/src/backend/xml/test/test-load-xml2.cpp
index 3df9861..0ddabf6 100644
--- a/src/backend/xml/test/test-load-xml2.cpp
+++ b/src/backend/xml/test/test-load-xml2.cpp
@@ -25,6 +25,7 @@
 /* @file test-load-xml2.c
  * @brief test the loading of a version-2 gnucash XML file
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-save-in-lang.cpp b/src/backend/xml/test/test-save-in-lang.cpp
index 04214d0..71bdb61 100644
--- a/src/backend/xml/test/test-save-in-lang.cpp
+++ b/src/backend/xml/test/test-save-in-lang.cpp
@@ -17,6 +17,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-string-converters.cpp b/src/backend/xml/test/test-string-converters.cpp
index 8cbf726..2f0362f 100644
--- a/src/backend/xml/test/test-string-converters.cpp
+++ b/src/backend/xml/test/test-string-converters.cpp
@@ -17,6 +17,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-xml-account.cpp b/src/backend/xml/test/test-xml-account.cpp
index 352e259..b31763e 100644
--- a/src/backend/xml/test/test-xml-account.cpp
+++ b/src/backend/xml/test/test-xml-account.cpp
@@ -21,6 +21,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-xml-commodity.cpp b/src/backend/xml/test/test-xml-commodity.cpp
index afb9d0e..206465f 100644
--- a/src/backend/xml/test/test-xml-commodity.cpp
+++ b/src/backend/xml/test/test-xml-commodity.cpp
@@ -17,6 +17,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-xml-pricedb.cpp b/src/backend/xml/test/test-xml-pricedb.cpp
index efbf249..4ce7145 100644
--- a/src/backend/xml/test/test-xml-pricedb.cpp
+++ b/src/backend/xml/test/test-xml-pricedb.cpp
@@ -21,6 +21,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-xml-transaction.cpp b/src/backend/xml/test/test-xml-transaction.cpp
index 9247fda..24b1241 100644
--- a/src/backend/xml/test/test-xml-transaction.cpp
+++ b/src/backend/xml/test/test-xml-transaction.cpp
@@ -21,6 +21,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/backend/xml/test/test-xml2-is-file.cpp b/src/backend/xml/test/test-xml2-is-file.cpp
index 956d269..f2a15fe 100644
--- a/src/backend/xml/test/test-xml2-is-file.cpp
+++ b/src/backend/xml/test/test-xml2-is-file.cpp
@@ -17,6 +17,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/kvp-scm.cpp b/src/engine/kvp-scm.cpp
index 8755f1e..9f69319 100644
--- a/src/engine/kvp-scm.cpp
+++ b/src/engine/kvp-scm.cpp
@@ -1,3 +1,4 @@
+#include <guid.hpp>
 #include <kvp_frame.hpp>
 #include <libguile.h>
 
diff --git a/src/engine/test-core/test-engine-stuff.cpp b/src/engine/test-core/test-engine-stuff.cpp
index 28a12d5..b9386e8 100644
--- a/src/engine/test-core/test-engine-stuff.cpp
+++ b/src/engine/test-core/test-engine-stuff.cpp
@@ -35,6 +35,7 @@
  *                                                                  *
 \********************************************************************/
 
+#include <guid.hpp>
 #include <kvp_frame.hpp>
 
 extern "C"
diff --git a/src/engine/test/gtest-import-map.cpp b/src/engine/test/gtest-import-map.cpp
index 53a00e9..e990067 100644
--- a/src/engine/test/gtest-import-map.cpp
+++ b/src/engine/test/gtest-import-map.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
+#include <guid.hpp>
 extern "C"
 {
 #include <config.h>
diff --git a/src/engine/test/test-account-object.cpp b/src/engine/test/test-account-object.cpp
index ccc4289..7c21491 100644
--- a/src/engine/test/test-account-object.cpp
+++ b/src/engine/test/test-account-object.cpp
@@ -24,6 +24,7 @@
  * @brief Minimal test of reading/writing account parameters
  * @author David Hampton <hampton at employees.org>
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-commodities.cpp b/src/engine/test/test-commodities.cpp
index eaff923..ea577c0 100644
--- a/src/engine/test/test-commodities.cpp
+++ b/src/engine/test/test-commodities.cpp
@@ -22,6 +22,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-date.cpp b/src/engine/test/test-date.cpp
index 1bb9e7a..07285ee 100644
--- a/src/engine/test/test-date.cpp
+++ b/src/engine/test/test-date.cpp
@@ -21,7 +21,7 @@
  *                                                                  *
 \********************************************************************/
 
-
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-group-vs-book.cpp b/src/engine/test/test-group-vs-book.cpp
index 8ef2a8e..769c4ba 100644
--- a/src/engine/test/test-group-vs-book.cpp
+++ b/src/engine/test/test-group-vs-book.cpp
@@ -20,6 +20,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-guid.cpp b/src/engine/test/test-guid.cpp
index 923e59d..1c46785 100644
--- a/src/engine/test/test-guid.cpp
+++ b/src/engine/test/test-guid.cpp
@@ -25,6 +25,7 @@
  * Try to create duplicate GncGUID's, which should never happen.
  *
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-lots.cpp b/src/engine/test/test-lots.cpp
index 556df24..31ee122 100644
--- a/src/engine/test/test-lots.cpp
+++ b/src/engine/test/test-lots.cpp
@@ -24,6 +24,7 @@
  * @brief Minimal test to see if automatic lot scrubbing works.
  * @author Linas Vepstas <linas at linas.org>
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-numeric.cpp b/src/engine/test/test-numeric.cpp
index 7bbb9c4..adf06a9 100644
--- a/src/engine/test/test-numeric.cpp
+++ b/src/engine/test/test-numeric.cpp
@@ -22,6 +22,7 @@
  *  02110-1301, USA.
  */
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-query.cpp b/src/engine/test/test-query.cpp
index 844d7ea..9226f7d 100644
--- a/src/engine/test/test-query.cpp
+++ b/src/engine/test/test-query.cpp
@@ -20,6 +20,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-scm-query.cpp b/src/engine/test/test-scm-query.cpp
index 98d394b..c3e3b53 100644
--- a/src/engine/test/test-scm-query.cpp
+++ b/src/engine/test/test-scm-query.cpp
@@ -20,6 +20,7 @@
 
 #include <libguile.h>
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-split-vs-account.cpp b/src/engine/test/test-split-vs-account.cpp
index 77e92e7..af22cc6 100644
--- a/src/engine/test/test-split-vs-account.cpp
+++ b/src/engine/test/test-split-vs-account.cpp
@@ -21,6 +21,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-transaction-reversal.cpp b/src/engine/test/test-transaction-reversal.cpp
index 3214167..36ebdd6 100644
--- a/src/engine/test/test-transaction-reversal.cpp
+++ b/src/engine/test/test-transaction-reversal.cpp
@@ -21,6 +21,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/test-transaction-voiding.cpp b/src/engine/test/test-transaction-voiding.cpp
index 9c556d5..56f58a5 100644
--- a/src/engine/test/test-transaction-voiding.cpp
+++ b/src/engine/test/test-transaction-voiding.cpp
@@ -21,6 +21,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  *  02110-1301, USA.
  */
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/utest-Account.cpp b/src/engine/test/utest-Account.cpp
index cc7e19e..1ce5365 100644
--- a/src/engine/test/utest-Account.cpp
+++ b/src/engine/test/utest-Account.cpp
@@ -19,6 +19,7 @@
  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/utest-Split.cpp b/src/engine/test/utest-Split.cpp
index 71fe4b5..4989705 100644
--- a/src/engine/test/utest-Split.cpp
+++ b/src/engine/test/utest-Split.cpp
@@ -21,6 +21,7 @@
  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/engine/test/utest-Transaction.cpp b/src/engine/test/utest-Transaction.cpp
index dcdac4d..0331eb5 100644
--- a/src/engine/test/utest-Transaction.cpp
+++ b/src/engine/test/utest-Transaction.cpp
@@ -21,6 +21,7 @@
  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  ********************************************************************/
+#include <guid.hpp>
 extern "C"
 {
 #include <config.h>
diff --git a/src/libqof/qof/gnc-aqbanking-templates.cpp b/src/libqof/qof/gnc-aqbanking-templates.cpp
index 54f9b6f..8f542aa 100644
--- a/src/libqof/qof/gnc-aqbanking-templates.cpp
+++ b/src/libqof/qof/gnc-aqbanking-templates.cpp
@@ -25,6 +25,7 @@
 /** Class for managing AQBanking Transaction Templates.
  */
 
+#include "guid.hpp"
 #include <string>
 
 extern "C"
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 4d2691e..18f7405 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -24,6 +24,7 @@
  *                                                                  *
 \********************************************************************/
 
+#include <guid.hpp>
 #define __EXTENSIONS__
 extern "C"
 {
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index a03ecb0..6946c98 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
+#include <guid.hpp>
 #include "gnc-timezone.hpp"
 
 #include <string>
diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index befe986..5deaaea 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -22,6 +22,7 @@
  *                                                                  *
 \********************************************************************/
 
+#include "guid.hpp"
 extern "C"
 {
 
@@ -29,11 +30,6 @@ extern "C"
 # include <config.h>
 #endif
 
-#include <platform.h>
-#if PLATFORM(WINDOWS)
-#include <windows.h>
-#endif
-
 #ifdef HAVE_SYS_TYPES_H
 # include <sys/types.h>
 #endif
@@ -88,13 +84,13 @@ gnc_value_get_guid (const GValue *value)
     return val;
 }
 
-static GncGUID * nullguid {reinterpret_cast<GncGUID*> (new boost::uuids::uuid{{0}})};
+static GncGUID s_null_guid {{0}};
 
 /*It looks like we are expected to provide the same pointer every time from this function*/
 const GncGUID *
 guid_null (void)
 {
-    return nullguid;
+    return &s_null_guid;
 }
 
 /* Memory management routines ***************************************/
@@ -111,7 +107,7 @@ guid_free (GncGUID *guid)
 {
     if (!guid)
         return;
-    if (guid == nullguid)
+    if (guid == &s_null_guid)
         /*!!Don't delete that!!*/
         return;
     delete reinterpret_cast<boost::uuids::uuid*> (guid);
@@ -194,7 +190,7 @@ string_to_guid (const char * str, GncGUID * guid)
     if (!guid || !str)
         return false;
 
-    try 
+    try
     {
         static boost::uuids::string_generator strgen;
         boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)};
@@ -317,3 +313,55 @@ gnc_guid_get_type (void)
 
     return type;
 }
+
+GncGUID
+GncGUID::create_random () noexcept
+{
+    static boost::uuids::random_generator gen;
+    return {gen ()};
+}
+
+GncGUID::GncGUID () noexcept
+{
+}
+
+GncGUID::GncGUID (boost::uuids::uuid const & other) noexcept
+    : boost::uuids::uuid (other)
+{
+}
+
+GncGUID const &
+GncGUID::null_guid () noexcept
+{
+    return s_null_guid;
+}
+
+std::string
+GncGUID::to_string () const noexcept
+{
+    auto const & val = boost::uuids::to_string (*this);
+    std::string ret;
+    std::for_each (val.begin (), val.end (), [&ret] (char a) {
+        if (a != '-') ret.push_back (a);
+    });
+    return ret;
+}
+
+GncGUID
+GncGUID::from_string (std::string const & str) throw (guid_syntax_exception)
+{
+    try
+    {
+        static boost::uuids::string_generator strgen;
+        return strgen (str);
+    }
+    catch (...)
+    {
+        throw guid_syntax_exception {};
+    }
+}
+
+guid_syntax_exception::guid_syntax_exception () noexcept
+    : invalid_argument {"Invalid syntax for guid."}
+{
+}
diff --git a/src/libqof/qof/guid.h b/src/libqof/qof/guid.h
index 7015e23..e3f0cf0 100644
--- a/src/libqof/qof/guid.h
+++ b/src/libqof/qof/guid.h
@@ -61,10 +61,16 @@ extern "C"
 #define GNC_TYPE_GUID (gnc_guid_get_type())
 #define GNC_VALUE_HOLDS_GUID(value) G_VALUE_HOLDS(value, GNC_TYPE_GUID)
 
-/** The type used to store guids */
+/* We use two definitions for gncguid: one when compiling for C (so that
+ * the object can be persisted), and a different one when compiling for C++
+ * found in guid.hpp
+ */
+#ifndef __cplusplus
+/** The type used to store guids in C */
 typedef struct _gncGuid {
     unsigned char reserved[GUID_DATA_SIZE];
 } GncGUID;
+#endif
 
 GType gnc_guid_get_type (void);
 const GncGUID* gnc_value_get_guid (const GValue *value);
diff --git a/src/backend/sql/test/test-sqlbe.cpp b/src/libqof/qof/guid.hpp
similarity index 62%
copy from src/backend/sql/test/test-sqlbe.cpp
copy to src/libqof/qof/guid.hpp
index 0b3d12e..bc59625 100644
--- a/src/backend/sql/test/test-sqlbe.cpp
+++ b/src/libqof/qof/guid.hpp
@@ -1,7 +1,6 @@
 /********************************************************************
- * testmain.c: GLib g_test test execution file.             *
- * Copyright 2011 John Ralls <jralls at ceridwen.us>           *
- *                                                                  *
+ * guid.hpp - GncGUID struct definition.                            *
+ * Copyright 2016 Aaron Laws                                        *
  * 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   *
@@ -18,26 +17,27 @@
  * 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                   *
-\********************************************************************/
+ *                                                                  *
+ *******************************************************************/
+#ifndef GUID_HPP_HEADER
+#define GUID_HPP_HEADER
 
-extern "C"
-{
-#include "config.h"
-#include <glib.h>
-#include "qof.h"
-}
-extern void test_suite_gnc_backend_sql ();
+#include <boost/uuid/uuid.hpp>
+#include <stdexcept>
 
-int
-main (int   argc,
-      char* argv[])
+struct guid_syntax_exception : public std::invalid_argument
 {
-    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 */
-    g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */
+    guid_syntax_exception () noexcept;
+};
 
-    test_suite_gnc_backend_sql ();
+struct GncGUID : public boost::uuids::uuid
+{
+    GncGUID (boost::uuids::uuid const &) noexcept;
+    GncGUID () noexcept;
+    static GncGUID create_random () noexcept;
+    static GncGUID const & null_guid () noexcept;
+    static GncGUID from_string (std::string const &) throw (guid_syntax_exception);
+    std::string to_string () const noexcept;
+};
 
-    return g_test_run ();
-}
+#endif
diff --git a/src/libqof/qof/kvp-value.cpp b/src/libqof/qof/kvp-value.cpp
index a671284..12d16b1 100644
--- a/src/libqof/qof/kvp-value.cpp
+++ b/src/libqof/qof/kvp-value.cpp
@@ -20,6 +20,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 
 #include "kvp-value.hpp"
 #include "kvp_frame.hpp"
diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp
index 5a5b6be..790ae26 100644
--- a/src/libqof/qof/kvp_frame.cpp
+++ b/src/libqof/qof/kvp_frame.cpp
@@ -22,6 +22,7 @@
  *                                                                  *
  ********************************************************************/
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/libqof/qof/qof-string-cache.cpp b/src/libqof/qof/qof-string-cache.cpp
index 2d86839..118b205 100644
--- a/src/libqof/qof/qof-string-cache.cpp
+++ b/src/libqof/qof/qof-string-cache.cpp
@@ -26,11 +26,9 @@
  *   Author: Phil Longstaff (phil.longstaff at yahoo.ca)               *
 \********************************************************************/
 
-#ifdef __cplusplus
+#include <guid.hpp>
 extern "C"
 {
-#endif
-
 #include "config.h"
 
 #include <ctype.h>
@@ -38,10 +36,7 @@ extern "C"
 #include <stdlib.h>
 #include <string.h>
 #include "qof.h"
-
-#ifdef __cplusplus
 }
-#endif
 
 /* Uncomment if you need to log anything.
 static QofLogModule log_module = QOF_MOD_UTIL;
diff --git a/src/libqof/qof/qofbackend.cpp b/src/libqof/qof/qofbackend.cpp
index a805808..f8c286e 100644
--- a/src/libqof/qof/qofbackend.cpp
+++ b/src/libqof/qof/qofbackend.cpp
@@ -21,10 +21,10 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
-#ifdef __cplusplus
+
+#include <guid.hpp>
 extern "C"
 {
-#endif
 
 #include "config.h"
 #include <stdio.h>
@@ -37,9 +37,7 @@ extern "C"
 #include "qof.h"
 #include "qofbackend-p.h"
 
-#ifdef __cplusplus
 }
-#endif
 
 G_GNUC_UNUSED static QofLogModule log_module = QOF_MOD_BACKEND;
 
diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp
index 7349718..5a9a6db 100644
--- a/src/libqof/qof/qofbook.cpp
+++ b/src/libqof/qof/qofbook.cpp
@@ -33,10 +33,9 @@
  * Copyright (c) 2007 David Hampton <hampton at employees.org>
  */
 
-#ifdef __cplusplus
+#include <guid.hpp>
 extern "C"
 {
-#endif
 
 #include "config.h"
 
@@ -50,9 +49,7 @@ extern "C"
 #endif
 #include <inttypes.h>
 
-#ifdef __cplusplus
 }
-#endif
 
 #include "qof.h"
 #include "qofevent-p.h"
diff --git a/src/libqof/qof/qofchoice.cpp b/src/libqof/qof/qofchoice.cpp
index 588fc68..c680acf 100644
--- a/src/libqof/qof/qofchoice.cpp
+++ b/src/libqof/qof/qofchoice.cpp
@@ -21,17 +21,14 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#ifdef __cplusplus
+#include <guid.hpp>
 extern "C"
 {
-#endif
 
 #include "config.h"
 #include <glib.h>
 
-#ifdef __cplusplus
 }
-#endif
 
 #include "qof.h"
 #include "qofchoice.h"
diff --git a/src/libqof/qof/qofclass.cpp b/src/libqof/qof/qofclass.cpp
index 436db70..25f0708 100644
--- a/src/libqof/qof/qofclass.cpp
+++ b/src/libqof/qof/qofclass.cpp
@@ -20,19 +20,13 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                  *
 \********************************************************************/
+#include <guid.hpp>
 
-#ifdef __cplusplus
 extern "C"
 {
-#endif
-
 #include "config.h"
-
 #include <glib.h>
-
-#ifdef __cplusplus
 }
-#endif
 
 #include "qof.h"
 #include "qofclass-p.h"
diff --git a/src/libqof/qof/qofevent.cpp b/src/libqof/qof/qofevent.cpp
index 3d2519f..9fbae7d 100644
--- a/src/libqof/qof/qofevent.cpp
+++ b/src/libqof/qof/qofevent.cpp
@@ -22,17 +22,12 @@
  *                                                                  *
  ********************************************************************/
 
-#ifdef __cplusplus
+#include <guid.hpp>
 extern "C"
 {
-#endif
-
 #include "config.h"
 #include <glib.h>
-
-#ifdef __cplusplus
 }
-#endif
 
 #include "qof.h"
 #include "qofevent-p.h"
diff --git a/src/libqof/qof/qofid.cpp b/src/libqof/qof/qofid.cpp
index 949f16f..53a2ee1 100644
--- a/src/libqof/qof/qofid.cpp
+++ b/src/libqof/qof/qofid.cpp
@@ -22,19 +22,13 @@
  *                                                                  *
 \********************************************************************/
 
-#ifdef __cplusplus
+#include <guid.hpp>
 extern "C"
 {
-#endif
-
 #include "config.h"
-
 #include <string.h>
 #include <glib.h>
-
-#ifdef __cplusplus
 }
-#endif
 
 #include "qof.h"
 #include "qofid-p.h"
diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp
index 1bd5da6..9f3f542 100644
--- a/src/libqof/qof/qofinstance.cpp
+++ b/src/libqof/qof/qofinstance.cpp
@@ -28,6 +28,7 @@
  * Copyright (c) 2007 David Hampton <hampton at employees.org>
  */
 
+#include <guid.hpp>
 extern "C"
 {
 #include "config.h"
diff --git a/src/libqof/qof/qoflog.cpp b/src/libqof/qof/qoflog.cpp
index f33b882..37c4916 100644
--- a/src/libqof/qof/qoflog.cpp
+++ b/src/libqof/qof/qoflog.cpp
@@ -25,11 +25,9 @@
  *  02110-1301,  USA
  */
 
-#ifdef __cplusplus
+#include <guid.hpp>
 extern "C"
 {
-#endif
-
 #include "config.h"
 
 #include <platform.h>
@@ -53,10 +51,7 @@ extern "C"
 
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "qof.log"
-
-#ifdef __cplusplus
 }
-#endif
 
 #include "qof.h"
 #include "qoflog.h"
diff --git a/src/libqof/qof/qofobject.cpp b/src/libqof/qof/qofobject.cpp
index cfd848a..1675c9f 100644
--- a/src/libqof/qof/qofobject.cpp
+++ b/src/libqof/qof/qofobject.cpp
@@ -23,19 +23,12 @@
  * Copyright (C) 2001 Derek Atkins
  * Author: Derek Atkins <warlord at MIT.EDU>
  */
-
-#ifdef __cplusplus
+#include <guid.hpp>
 extern "C"
 {
-#endif
-
 #include "config.h"
-
 #include <glib.h>
-
-#ifdef __cplusplus
 }
-#endif
 
 #include "qof.h"
 #include "qofobject-p.h"
diff --git a/src/libqof/qof/qofquery.cpp b/src/libqof/qof/qofquery.cpp
index 3810fa4..bd9dbad 100644
--- a/src/libqof/qof/qofquery.cpp
+++ b/src/libqof/qof/qofquery.cpp
@@ -21,11 +21,9 @@
  *                                                                  *
 \********************************************************************/
 
-#ifdef __cplusplus
+#include <guid.hpp>
 extern "C"
 {
-#endif
-
 #include "config.h"
 
 #include <sys/types.h>
@@ -33,10 +31,7 @@ extern "C"
 #include <glib.h>
 #include <regex.h>
 #include <string.h>
-
-#ifdef __cplusplus
 }
-#endif
 
 #include "qof.h"
 #include "qofbackend-p.h"
diff --git a/src/libqof/qof/qofquerycore.cpp b/src/libqof/qof/qofquerycore.cpp
index 68a6f62..56350f3 100644
--- a/src/libqof/qof/qofquerycore.cpp
+++ b/src/libqof/qof/qofquerycore.cpp
@@ -21,6 +21,7 @@
  *                                                                  *
 \********************************************************************/
 
+#include <guid.hpp>
 #include "config.h"
 
 #include <glib.h>
diff --git a/src/libqof/qof/qofsession.cpp b/src/libqof/qof/qofsession.cpp
index d6f7d6e..2d77edb 100644
--- a/src/libqof/qof/qofsession.cpp
+++ b/src/libqof/qof/qofsession.cpp
@@ -32,6 +32,7 @@
  @author Copyright (c) 2016 Aaron Laws
    */
 
+#include "guid.hpp"
 extern "C"
 {
 
diff --git a/src/libqof/qof/qofutil.cpp b/src/libqof/qof/qofutil.cpp
index 2881fd7..9119e63 100644
--- a/src/libqof/qof/qofutil.cpp
+++ b/src/libqof/qof/qofutil.cpp
@@ -25,6 +25,7 @@
  *   Author: Linas Vepstas (linas at linas.org)                        *
 \********************************************************************/
 
+#include <guid.hpp>
 #include "config.h"
 
 #include <ctype.h>
diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am
index 52a26c3..f5f6507 100644
--- a/src/libqof/qof/test/Makefile.am
+++ b/src/libqof/qof/test/Makefile.am
@@ -16,7 +16,7 @@ test_qof_SOURCES = \
 	test-qofobject.c \
 	test-qofsession-old.cpp \
 	test-qof-string-cache.c \
-	test-gnc-guid.cpp \
+	test-gnc-guid-old.cpp \
 	${top_srcdir}/src/test-core/unittest-support.c
 
 test_qof_HEADERS = \
@@ -33,6 +33,27 @@ check_PROGRAMS = \
 TESTS = ${check_PROGRAMS}
 
 if WITH_GOOGLE_TEST
+test_gnc_guid_SOURCES = \
+	$(top_srcdir)/$(MODULEPATH)/guid.cpp \
+	test-gnc-guid.cpp
+test_gnc_guid_LDADD = \
+	$(top_builddir)/$(MODULEPATH)/libgnc-qof.la \
+        $(GLIB_LIBS) \
+	$(GTEST_LIBS) \
+	$(BOOST_LDFLAGS)
+if !GOOGLE_TEST_LIBS
+nodist_test_gnc_guid_SOURCES = \
+        ${GTEST_SRC}/src/gtest_main.cc
+endif
+
+test_gnc_guid_CPPFLAGS = \
+    -I$(GTEST_HEADERS) \
+    -I$(top_srcdir)/$(MODULEPATH) \
+    $(GLIB_CFLAGS) \
+    $(BOOST_CPPFLAGS)
+
+check_PROGRAMS += test-gnc-guid
+
 test_kvp_value_SOURCES = \
     $(top_srcdir)/$(MODULEPATH)/kvp-value.cpp \
     test-kvp-value.cpp \
diff --git a/src/libqof/qof/test/test-gnc-guid.cpp b/src/libqof/qof/test/test-gnc-guid-old.cpp
similarity index 98%
copy from src/libqof/qof/test/test-gnc-guid.cpp
copy to src/libqof/qof/test/test-gnc-guid-old.cpp
index 2fdda52..df2d543 100644
--- a/src/libqof/qof/test/test-gnc-guid.cpp
+++ b/src/libqof/qof/test/test-gnc-guid-old.cpp
@@ -1,5 +1,5 @@
 /********************************************************************
- * GLib test suite for guid.cpp                                     *
+ * GLib test suite for the C interface to guid.cpp                  *
  * Copyright 2014 Aaron Laws <dartmetrash at gmail.com>                *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -21,6 +21,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  ********************************************************************/
 
+#include "../guid.hpp"
 extern "C"
 {
 #include <config.h>
diff --git a/src/libqof/qof/test/test-gnc-guid.cpp b/src/libqof/qof/test/test-gnc-guid.cpp
index 2fdda52..b4bcf35 100644
--- a/src/libqof/qof/test/test-gnc-guid.cpp
+++ b/src/libqof/qof/test/test-gnc-guid.cpp
@@ -1,6 +1,7 @@
 /********************************************************************
- * GLib test suite for guid.cpp                                     *
- * Copyright 2014 Aaron Laws <dartmetrash at gmail.com>                *
+ * GLib test suite for the C++ interface to guid.cpp                *
+ *
+ * Copyright 2016 Aaron Laws                                        *
  * 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   *
@@ -21,179 +22,75 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  ********************************************************************/
 
-extern "C"
-{
-#include <config.h>
-#include <string.h>
-#include <glib.h>
-#include <unittest-support.h>
-void test_suite_gnc_guid (void);
-}
-
-/*Can be included as c++, because it's c++ tolerant*/
-#include "../guid.h"
+#include "../guid.hpp"
 
 #include <random>
 #include <sstream>
 #include <iomanip>
 #include <string>
 #include <iostream>
+#include <gtest/gtest.h>
 
-using namespace std;
-
-static const gchar * suitename {"/qof/gnc-guid"};
-
-/*Create a GUID and free it.*/
-static void test_create_gnc_guid (void){
-    GncGUID * guid {guid_malloc ()};
-    g_assert (guid != nullptr);
-    guid_replace (guid);
-    /*We apparently don't need to free guid_null (based on its being const)*/
-    const GncGUID * guidnull {guid_null ()};
-    g_assert (!guid_equal (guid, guidnull));
-    guid_free (guid);
-}
-
-/*We create a GUID, create a copy, and compare them to ensure they're not different.*/
-static void test_gnc_guid_copy (void) {
-    GncGUID * guid {guid_malloc ()};
-    g_assert (guid != nullptr);
-    guid_replace (guid);
-    GncGUID * cp {guid_copy (guid)};
-    g_assert (guid_equal (guid, cp));
-    guid_free (cp);
-    guid_free (guid);
-}
-
-/* We create a GUID, then convert it to a string using the two methods
-defined in the guid api. We then compare them.*/
-static void test_gnc_guid_to_string (void) {
-    GncGUID * guid {guid_malloc()};
-    gchar guidstrp [GUID_ENCODING_LENGTH+1];
-    gchar guidstrp2[GUID_ENCODING_LENGTH+1];
-    g_assert (guid != nullptr);
-    guid_replace (guid);
-    string message {" using guid_to_string (deprecated): "};
-    guid_to_string_buff (guid,guidstrp);
-    string guidstr {guidstrp};
-    g_assert (guidstr.size () == GUID_ENCODING_LENGTH);
-    message += guidstr;
-    g_test_message ("%s", message.c_str ());
-    message = " using guid_to_string_buff: ";
-    gchar * ret {guid_to_string_buff (guid, guidstrp2)};
-    g_assert (ret == guidstrp2 + GUID_ENCODING_LENGTH);
-    string guidstr2 {guidstrp2};
-    g_assert (guidstr2.size () == GUID_ENCODING_LENGTH);
-    message += guidstr2;
-    g_test_message ("%s", message.c_str ());
-
-    g_assert (guidstr2 == guidstr);
-    guid_free (guid);
+TEST (GncGUID, creation)
+{
+    auto guid = GncGUID::create_random ();
+    EXPECT_NE (guid, GncGUID::null_guid ());
+    // There should be a default constructor.
+    GncGUID other;
 }
 
-/*We fill a stringstream with random data, convert those to 
-two GUIDs, then ensure that they are equal*/
-static void test_gnc_guid_equals (void) {
-    GncGUID * guid1 {guid_malloc ()};
-    g_assert (guid1 != nullptr);
-    GncGUID * guid2 {guid_malloc ()};
-    g_assert (guid2 != nullptr);
-    GncGUID * guidold {guid_malloc ()};
-    g_assert (guidold != nullptr);
-
-    mt19937 m;
-    uniform_int_distribution<unsigned> dist;
-    /*we use the same seed every time for reproducibility's sake, and
-    for sanity's sake. It may be nerve-wracking for this test to fail
-    only sometimes, or in different ways.*/
-    m.seed (0);
-    unsigned num_tests {200};
-    for (unsigned test {0}; test < num_tests; ++test){
-        ostringstream o;
-        o << hex << setfill ('0') << right;
-        /*Now we put a GUID into the stringstream*/
-        for (unsigned spot {0}; spot < 4; ++spot)
-            o << setw (8) << dist (m);
-        string guids {o.str ()};
-        g_assert (guids.size() == GUID_ENCODING_LENGTH);
-        g_assert (string_to_guid (guids.c_str (), guid1));
-        g_assert (string_to_guid (guids.c_str (), guid2));
-        g_assert (guid_equal (guid1, guid2));
-        /*Assuming that our distribution won't give the same
-        GUID twice in a row.*/
-        g_assert (!guid_equal (guid1, guidold));
-        g_assert (string_to_guid (guids.c_str (), guidold));
-    }
-    guid_free (guidold);
-    guid_free (guid2);
-    guid_free (guid1);
+TEST (GncGUID, copy)
+{
+    auto guid = GncGUID::create_random ();
+    auto cpy = guid;
+    EXPECT_EQ (guid, cpy);
+    GncGUID cpy2 {cpy};
+    EXPECT_EQ (guid, cpy2);
 }
 
-/*We create a new guid, convert it to string, and convert that to
-a guid, ensuring that we end up with an equivalent structure*/
-static void test_gnc_guid_roundtrip (void) {
-    GncGUID * guid1 {guid_malloc ()};
-    g_assert (guid1 != nullptr);
-    GncGUID * guid2 {guid_malloc ()};
-    g_assert (guid2 != nullptr);
-    guid_replace (guid1);
-
-    gchar guidstrp [GUID_ENCODING_LENGTH+1];
-    gchar * temp {guid_to_string_buff (guid1, guidstrp)};
-    g_assert (temp == guidstrp + GUID_ENCODING_LENGTH);
-
-    g_assert (string_to_guid (guidstrp, guid2));
-    g_assert (guid_equal (guid1, guid2));
-    guid_free (guid2);
-    guid_free (guid1);
+TEST (GncGUID, move)
+{
+    auto guid = GncGUID::create_random ();
+    auto cpy = guid;
+    auto mv = std::move(guid);
+    EXPECT_EQ (cpy, mv);
 }
 
-/**
- * guid_replace should put a newly generated guid into the parameter. In
- * this test, we ensure that the first "new" guid doesn't match a subsequent
- * "new" guid in the same memory location.
- */
-static void test_gnc_guid_replace (void)
+TEST (GncGUID, to_string)
 {
-    GncGUID * guid1 {guid_malloc ()};
-
-    guid_replace (guid1);
-    GncGUID * guid2 {guid_copy (guid1)};
-    guid_replace (guid1);
-    g_assert (! guid_equal (guid1, guid2));
-
-    guid_free (guid2);
-    guid_free (guid1);
+    std::string fixture (32, '0');
+    auto str {GncGUID::null_guid ().to_string ()};
+    EXPECT_EQ (str, fixture);
 }
 
-/**
- * We create a bogus guid and ensure that it doesn't get parsed successfully,
- * then we pass in a good GUID from string and ensure that the function returns true.
- */
-static void test_gnc_guid_from_string (void) {
-    GncGUID * guid {guid_malloc ()};
-    const char * bogus {"01-23-45-6789a.cDeF0123z56789abcdef"};
-
-    /* string_to_guid should return false if either parameter is null*/
-    g_assert (!string_to_guid (nullptr, guid));
-    g_assert (!string_to_guid (bogus, nullptr));
-
-    g_assert (!string_to_guid (bogus, guid));
-
-    const char * good {"0123456789abcdef1234567890abcdef"};
-    g_assert (string_to_guid (good, guid));
-
-    guid_free (guid);
+TEST (GncGUID, from_string)
+{
+    std::string fixture (32, '0');
+    auto guid {GncGUID::from_string (fixture)};
+    EXPECT_EQ (guid, GncGUID::null_guid ());
+
+    guid = GncGUID::create_random ();
+    std::string bogus {"Have a great big roast beef sandwich, if you please!"};
+    bool fail = false;
+    try
+    {
+        auto guid = GncGUID::from_string (bogus);
+    }
+    catch (guid_syntax_exception const &)
+    {
+        fail = true;
+    }
+    /* Currently, boost uuid string parsing is mostly very permissive, but it has some
+     * odd pet peves. See https://svn.boost.org/trac/boost/ticket/12253 for more.*/
+    //EXPECT_TRUE (fail) << "Parsing the bogus string should throw";
+    EXPECT_FALSE (fail) << "Perhaps boost uuid is fixed.";
 }
 
-void test_suite_gnc_guid (void)
+TEST (GncGUID, round_trip)
 {
-    GNC_TEST_ADD_FUNC (suitename, "gnc create guid", test_create_gnc_guid);
-    GNC_TEST_ADD_FUNC (suitename, "gnc copy guid", test_gnc_guid_copy);
-    GNC_TEST_ADD_FUNC (suitename, "gnc guid to string", test_gnc_guid_to_string);
-    GNC_TEST_ADD_FUNC (suitename, "gnc guid equal", test_gnc_guid_equals);
-    GNC_TEST_ADD_FUNC (suitename, "gnc guid string roundtrip", test_gnc_guid_roundtrip);
-    GNC_TEST_ADD_FUNC (suitename, "gnc guid from string", test_gnc_guid_from_string);
-    GNC_TEST_ADD_FUNC (suitename, "gnc guid replace", test_gnc_guid_replace);
+    auto guid1 = GncGUID::create_random ();
+    auto str = guid1.to_string ();
+    auto guid2 = GncGUID::from_string (str);
+    EXPECT_EQ (guid1, guid2);
 }
 
diff --git a/src/libqof/qof/test/test-kvp-frame.cpp b/src/libqof/qof/test/test-kvp-frame.cpp
index bbe4894..0c99330 100644
--- a/src/libqof/qof/test/test-kvp-frame.cpp
+++ b/src/libqof/qof/test/test-kvp-frame.cpp
@@ -22,6 +22,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  ********************************************************************/
 
+#include <guid.hpp>
 #include "../kvp-value.hpp"
 #include "../kvp_frame.hpp"
 #include <gtest/gtest.h>
diff --git a/src/libqof/qof/test/test-kvp-value.cpp b/src/libqof/qof/test/test-kvp-value.cpp
index ef8bd93..e8568d2 100644
--- a/src/libqof/qof/test/test-kvp-value.cpp
+++ b/src/libqof/qof/test/test-kvp-value.cpp
@@ -22,6 +22,7 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  ********************************************************************/
 
+#include <guid.hpp>
 #include "../kvp-value.hpp"
 #include "../guid.h"
 #include "../kvp_frame.hpp"
diff --git a/src/libqof/qof/test/test-qofinstance.cpp b/src/libqof/qof/test/test-qofinstance.cpp
index ba2e153..955be9c 100644
--- a/src/libqof/qof/test/test-qofinstance.cpp
+++ b/src/libqof/qof/test/test-qofinstance.cpp
@@ -19,6 +19,8 @@
  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
+
+#include <guid.hpp>
 extern "C"
 {
 #include <config.h>
diff --git a/src/libqof/qof/test/test-qofsession.cpp b/src/libqof/qof/test/test-qofsession.cpp
index d47022e..0262ff1 100644
--- a/src/libqof/qof/test/test-qofsession.cpp
+++ b/src/libqof/qof/test/test-qofsession.cpp
@@ -26,6 +26,7 @@
 #include <qofsession.hpp>
 #include "qofbackend-p.h"
 #include <cstdlib>
+#include "../guid.hpp"
 #include "../gnc-backend-prov.hpp"
 
 static QofBook * exported_book {nullptr};

commit 74800e18f38068eb6a43ae2c434b9d5994212664
Author: lmat <dartme18 at gmail.com>
Date:   Mon Jun 6 11:22:41 2016 -0400

    Remove unused, left over typedef

diff --git a/src/libqof/qof/guid.cpp b/src/libqof/qof/guid.cpp
index 6993f8d..befe986 100644
--- a/src/libqof/qof/guid.cpp
+++ b/src/libqof/qof/guid.cpp
@@ -65,8 +65,6 @@ extern "C"
 
 using namespace std;
 
-typedef boost::uuids::uuid gg;
-
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = QOF_MOD_ENGINE;
 

commit 0ee7e61b48e91ed846195efba1acc5d25f05272b
Author: lmat <dartme18 at gmail.com>
Date:   Sun Jun 5 13:30:47 2016 -0400

    Adding googletest cases for c++ qofsession struct

diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h
index f15c0ad..f18a1ea 100644
--- a/src/libqof/qof/qofbook.h
+++ b/src/libqof/qof/qofbook.h
@@ -56,6 +56,7 @@ typedef struct KvpValueImpl KvpValue;
 
 #include "qofid.h"
 #include "qofinstance.h"
+#include "qofbackend.h"
 
 /* --- type macros --- */
 #define QOF_TYPE_BOOK            (qof_book_get_type ())
diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am
index 5b2f1b3..52a26c3 100644
--- a/src/libqof/qof/test/Makefile.am
+++ b/src/libqof/qof/test/Makefile.am
@@ -56,6 +56,28 @@ test_kvp_value_CPPFLAGS = \
 
 check_PROGRAMS += test-kvp-value
 
+test_qofsession_SOURCES = \
+	$(top_srcdir)/$(MODULEPATH)/qofsession.cpp \
+	test-qofsession.cpp
+test_qofsession_LDADD = \
+	$(top_builddir)/$(MODULEPATH)/libgnc-qof.la \
+	$(GLIB_LIBS) \
+	$(GTEST_LIBS) \
+	$(BOOST_LDFLAGS)
+
+if !GOOGLE_TEST_LIBS
+nodist_test_qofsession_SOURCES = \
+	${GTEST_SRC}/src/gtest_main.cc
+endif
+
+test_qofsession_CPPFLAGS = \
+	-I$(GTEST_HEADERS) \
+	-I$(top_srcdir)/$(MODULEPATH) \
+	$(GLIB_CFLAGS) \
+	$(BOOST_CPPFLAGS)
+
+check_PROGRAMS += test-qofsession
+
 test_gnc_int128_SOURCES = \
         $(top_srcdir)/${MODULEPATH}/gnc-int128.cpp \
         gtest-gnc-int128.cpp
diff --git a/src/libqof/qof/test/test-qofsession.cpp b/src/libqof/qof/test/test-qofsession.cpp
new file mode 100644
index 0000000..d47022e
--- /dev/null
+++ b/src/libqof/qof/test/test-qofsession.cpp
@@ -0,0 +1,229 @@
+/********************************************************************
+ * test-qofsession.cpp: A Google Test suite for Qof Session.        *
+ * Copyright 2016 Aaron Laws                                        *
+ *                                                                  *
+ * 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 <gtest/gtest.h>
+#include <qofsession.hpp>
+#include "qofbackend-p.h"
+#include <cstdlib>
+#include "../gnc-backend-prov.hpp"
+
+static QofBook * exported_book {nullptr};
+static bool safe_sync_called {false};
+static bool sync_called {false};
+static bool load_error {true};
+static bool hook_called {false};
+static bool data_loaded {false};
+void example_hook (QofSession & session)
+{
+    hook_called = true;
+}
+
+void test_load (QofBackend * be, QofBook *, QofBackendLoadType)
+{
+    if (load_error) be->last_err = ERR_BACKEND_NO_BACKEND;
+    data_loaded = true;
+}
+
+void test_safe_sync (QofBackend *, QofBook *)
+{
+    safe_sync_called = true;
+}
+
+void test_sync (QofBackend *, QofBook *)
+{
+    sync_called = true;
+}
+
+void test_export_fn (QofBackend *, QofBook * book)
+{
+    exported_book = book;
+}
+
+QofBackend * test_backend_factory ()
+{
+    QofBackend * ret = (QofBackend*) std::malloc (sizeof (QofBackend));
+    ret->session_begin = nullptr;
+    ret->session_end = nullptr;
+    ret->destroy_backend = nullptr;
+    ret->load = &test_load;
+    ret->sync = &test_sync;
+    ret->safe_sync = &test_safe_sync;
+    ret->export_fn = &test_export_fn;
+    ret->error_msg = nullptr;
+    ret->fullpath = nullptr;
+    ret->last_err = ERR_BACKEND_NO_ERR;
+    ret->begin = nullptr;
+    ret->commit = nullptr;
+    ret->rollback = nullptr;
+    ret->compile_query = nullptr;
+    ret->free_query = nullptr;
+    ret->run_query = nullptr;
+    ret->events_pending = nullptr;
+    ret->process_events = nullptr;
+    ret->percentage = nullptr;
+    ret->config_count = 0;
+    ret->price_lookup = nullptr;
+    return ret;
+}
+
+struct MockProvider : public QofBackendProvider
+{
+    MockProvider (char const * name, char const * access_method)
+        : QofBackendProvider {name, access_method} {}
+    QofBackend * create_backend (void) {return test_backend_factory ();}
+    bool type_check (char const * type) {return true;}
+};
+
+QofBackendProvider_ptr get_provider ()
+{
+    return QofBackendProvider_ptr {new MockProvider {"Mock Backend", "file"}};
+}
+
+TEST (QofSessionTest, swap_books)
+{
+    qof_backend_register_provider (get_provider ());
+    QofSession s1;
+    s1.begin ("book1", false, false, false);
+    QofSession s2;
+    s2.begin ("book2", false, false, false);
+    QofBook * b1 {s1.get_book ()};
+    QofBook * b2 {s2.get_book ()};
+    ASSERT_NE (b1, b2);
+    s1.swap_books (s2);
+    EXPECT_EQ (s1.get_book (), b2);
+    EXPECT_EQ (s2.get_book (), b1);
+    qof_backend_unregister_all_providers ();
+}
+
+TEST (QofSessionTest, ensure_all_data_loaded)
+{
+    qof_backend_register_provider (get_provider ());
+    QofSession s;
+    s.begin ("book1", false, false, false);
+    data_loaded = false;
+    s.ensure_all_data_loaded ();
+    EXPECT_EQ (data_loaded, true);
+    qof_backend_unregister_all_providers ();
+}
+
+TEST (QofSessionTest, get_error)
+{
+    qof_backend_register_provider (get_provider ());
+    QofSession s;
+    s.begin ("book1", false, false, false);
+    s.ensure_all_data_loaded ();
+    EXPECT_NE (s.get_error (), ERR_BACKEND_NO_ERR);
+    //get_error should not clear the error.
+    EXPECT_NE (s.get_error (), ERR_BACKEND_NO_ERR);
+    qof_backend_unregister_all_providers ();
+}
+
+TEST (QofSessionTest, pop_error)
+{
+    qof_backend_register_provider (get_provider ());
+    QofSession s;
+    s.begin ("book1", false, false, false);
+    //We run the test first, and make sure there is an error condition.
+    s.ensure_all_data_loaded ();
+    EXPECT_NE (s.pop_error (), ERR_BACKEND_NO_ERR);
+    EXPECT_EQ (s.get_error (), ERR_BACKEND_NO_ERR);
+    qof_backend_unregister_all_providers ();
+}
+
+TEST (QofSessionTest, clear_error)
+{
+    qof_backend_register_provider (get_provider ());
+    QofSession s;
+    s.begin ("book1", false, false, false);
+    //We run the test first, and make sure there is an error condition.
+    s.ensure_all_data_loaded ();
+    EXPECT_NE (s.get_error (), ERR_BACKEND_NO_ERR);
+    //Now we run it, and clear_error to make sure the error is actually cleared.
+    s.ensure_all_data_loaded ();
+    s.clear_error ();
+    EXPECT_EQ (s.get_error (), ERR_BACKEND_NO_ERR);
+    qof_backend_unregister_all_providers ();
+}
+
+TEST (QofSessionTest, load)
+{
+    // We register a provider that gives a backend that
+    // throws an error on load.
+    // This error during load should cause the qof session to
+    // "roll back" the book load.
+    qof_backend_register_provider (get_provider ());
+    QofSession s;
+    s.begin ("book1", false, false, false);
+    auto book = s.get_book ();
+    s.load (nullptr);
+    EXPECT_EQ (book, s.get_book ());
+
+    // Now we'll do the load without returning an error from the backend,
+    // and ensure that the book changed to a new book.
+    load_error = false;
+    s.load (nullptr);
+    EXPECT_NE (book, s.get_book ());
+    // I'll put load_error back just to be tidy.
+    load_error = true;
+    qof_backend_unregister_all_providers ();
+}
+
+TEST (QofSessionTest, save)
+{
+    qof_backend_register_provider (get_provider ());
+    QofSession s;
+    s.begin ("book1", false, false, false);
+    s.save (nullptr);
+    EXPECT_EQ (sync_called, true);
+    qof_backend_unregister_all_providers ();
+    sync_called = false;
+}
+
+TEST (QofSessionTest, safe_save)
+{
+    qof_backend_register_provider (get_provider ());
+    QofSession s;
+    s.begin ("book1", false, false, false);
+    s.safe_save (nullptr);
+    EXPECT_EQ (safe_sync_called, true);
+    qof_backend_unregister_all_providers ();
+    safe_sync_called = false;
+}
+
+TEST (QofSessionTest, export_session)
+{
+    qof_backend_register_provider (get_provider ());
+    QofSession s1;
+    s1.begin ("book1", false, false, false);
+    QofSession s2;
+    s2.begin ("book2", false, false, false);
+    QofBook * b1 = s1.get_book ();
+    QofBook * b2 = s2.get_book ();
+    b1->backend = s1.get_backend ();
+    b2->backend = s2.get_backend ();
+    s2.export_session (s1, nullptr);
+    EXPECT_EQ (exported_book, b1);
+
+    qof_backend_unregister_all_providers ();
+}

commit 3063c873464f3e79dad9fe936bc9426da727db75
Author: lmat <dartme18 at gmail.com>
Date:   Sun Jun 5 13:14:45 2016 -0400

    Replace C qofsession struct with c++ qofsession struct

diff --git a/src/app-utils/gnc-state.c b/src/app-utils/gnc-state.c
index 494b690..b5cdfa5 100644
--- a/src/app-utils/gnc-state.c
+++ b/src/app-utils/gnc-state.c
@@ -84,9 +84,9 @@ gnc_state_set_base (const QofSession *session)
     state_file_name = NULL;
     state_file_name_pre_241 = NULL;
 
-    uri = qof_session_get_url(session);
+    uri = qof_session_get_url (session);
     ENTER("session %p (%s)", session, uri ? uri : "(null)");
-    if (!uri)
+    if (!strlen (uri))
     {
         LEAVE("no uri, nothing to do");
         return;
@@ -228,7 +228,7 @@ void gnc_state_save (const QofSession *session)
 {
     GError *error = NULL;
 
-    if (!qof_session_get_url(session))
+    if (!strlen (qof_session_get_url(session)))
     {
         DEBUG("No file associated with session - skip state saving");
         return;
diff --git a/src/backend/dbi/test/test-backend-dbi-basic.cpp b/src/backend/dbi/test/test-backend-dbi-basic.cpp
index 01941cc..b0112d7 100644
--- a/src/backend/dbi/test/test-backend-dbi-basic.cpp
+++ b/src/backend/dbi/test/test-backend-dbi-basic.cpp
@@ -51,7 +51,6 @@ extern "C"
 #include "gncInvoice.h"
     /* For version_control */
 #include <gnc-prefs.h>
-#include <qofsession-p.h>
 }
 /* For test_conn_index_functions */
 #include "test-dbi-stuff.h"
diff --git a/src/backend/dbi/test/test-dbi-stuff.cpp b/src/backend/dbi/test/test-dbi-stuff.cpp
index ea1f043..58526af 100644
--- a/src/backend/dbi/test/test-dbi-stuff.cpp
+++ b/src/backend/dbi/test/test-dbi-stuff.cpp
@@ -26,7 +26,6 @@ extern "C"
 {
 #include <config.h>
 #include <qof.h>
-#include <qofsession-p.h>
 #include <cashobjects.h>
 #include <test-dbi-stuff.h>
 #include <unittest-support.h>
diff --git a/src/gnome-utils/gnc-file.c b/src/gnome-utils/gnc-file.c
index ddb301e..178d9e5 100644
--- a/src/gnome-utils/gnc-file.c
+++ b/src/gnome-utils/gnc-file.c
@@ -492,7 +492,7 @@ gnc_add_history (QofSession * session)
     if (!session) return;
 
     url = qof_session_get_url ( session );
-    if ( !url )
+    if ( !strlen (url) )
         return;
 
     if ( gnc_uri_is_file_uri ( url ) )
@@ -1188,7 +1188,7 @@ gnc_file_do_export(const char * filename)
      * file. If so, prevent the export from happening to avoid killing this file */
     current_session = gnc_get_current_session ();
     oldfile = qof_session_get_url(current_session);
-    if (oldfile && (strcmp(oldfile, newfile) == 0))
+    if (strlen (oldfile) && (strcmp(oldfile, newfile) == 0))
     {
         g_free (newfile);
         show_session_error (ERR_FILEIO_WRITE_ERROR, filename,
@@ -1271,7 +1271,7 @@ gnc_file_save (void)
     /* If we don't have a filename/path to save to get one. */
     session = gnc_get_current_session ();
 
-    if (!qof_session_get_url(session))
+    if (!strlen (qof_session_get_url (session)))
     {
         gnc_file_save_as ();
         return;
@@ -1420,7 +1420,7 @@ gnc_file_do_save_as (const char* filename)
      * file. If so, then just do a simple save, instead of a full save as */
     session = gnc_get_current_session ();
     oldfile = qof_session_get_url(session);
-    if (oldfile && (strcmp(oldfile, newfile) == 0))
+    if (strlen (oldfile) && (strcmp(oldfile, newfile) == 0))
     {
         g_free (newfile);
         gnc_file_save ();
@@ -1578,7 +1578,7 @@ gnc_file_revert (void)
 
     session = gnc_get_current_session();
     fileurl = qof_session_get_url(session);
-    if (fileurl == NULL)
+    if (!strlen (fileurl))
         fileurl = _("<unknown>");
     if ((tmp = strrchr(fileurl, '/')) != NULL)
         filename = tmp + 1;
diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c
index 14b22e4..9d9d8ad4 100644
--- a/src/gnome-utils/gnc-main-window.c
+++ b/src/gnome-utils/gnc-main-window.c
@@ -1216,7 +1216,7 @@ gnc_main_window_prompt_for_save (GtkWidget *window)
     session = gnc_get_current_session();
     book = qof_session_get_book(session);
     filename = qof_session_get_url(session);
-    if (filename == NULL)
+    if (!strlen (filename))
         filename = _("<unknown>");
     if ((tmp = strrchr(filename, '/')) != NULL)
         filename = tmp + 1;
@@ -1626,7 +1626,7 @@ static gchar *generate_statusbar_lastmodified_message()
         book_id = qof_session_get_url (gnc_get_current_session ());
     }
 
-    if (!book_id)
+    if (!strlen (book_id))
         return NULL;
     else
     {
diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am
index 1077642..5e83159 100644
--- a/src/libqof/qof/Makefile.am
+++ b/src/libqof/qof/Makefile.am
@@ -77,6 +77,7 @@ qofinclude_HEADERS = \
    qofquery.h        \
    qofquerycore.h    \
    qofsession.h      \
+   qofsession.hpp    \
    qof-string-cache.h  \
    qofutil.h         \
    qof-gobject.h
@@ -89,8 +90,7 @@ noinst_HEADERS = \
    gnc-int128.hpp  \
    qofobject-p.h  \
    qofquery-p.h  \
-   qofquerycore-p.h \
-   qofsession-p.h
+   qofquerycore-p.h
 
 if OS_WIN32
 libgnc_qof_la_SOURCES += qof-win32.cpp
diff --git a/src/libqof/qof/gnc-backend-prov.hpp b/src/libqof/qof/gnc-backend-prov.hpp
index 1c55015..228cae2 100644
--- a/src/libqof/qof/gnc-backend-prov.hpp
+++ b/src/libqof/qof/gnc-backend-prov.hpp
@@ -78,4 +78,6 @@ using QofBackendProvider_ptr = std::unique_ptr<QofBackendProvider>;
  */
 void qof_backend_register_provider (QofBackendProvider_ptr&&);
 
+void qof_backend_unregister_all_providers ();
+
 #endif // __GNC_BACKEND_PROV_HPP__
diff --git a/src/libqof/qof/qofsession.cpp b/src/libqof/qof/qofsession.cpp
index acf2c28..d6f7d6e 100644
--- a/src/libqof/qof/qofsession.cpp
+++ b/src/libqof/qof/qofsession.cpp
@@ -1,5 +1,5 @@
 /********************************************************************\
- * qofsesssion.c -- session access (connection to backend)          *
+ * qofsesssion.cpp -- session access (connection to backend)        *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -29,6 +29,7 @@
  @author Copyright (c) 1998-2004 Linas Vepstas <linas at linas.org>
  @author Copyright (c) 2000 Dave Peticolas
  @author Copyright (c) 2005 Neil Williams <linux at codehelp.co.uk>
+ @author Copyright (c) 2016 Aaron Laws
    */
 
 extern "C"
@@ -36,13 +37,7 @@ extern "C"
 
 #include "config.h"
 
-#include <platform.h>
-#if PLATFORM(WINDOWS)
-#include <windows.h>
-#endif
-
 #include <stdlib.h>
-#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #ifdef HAVE_UNISTD_H
@@ -62,10 +57,12 @@ static QofLogModule log_module = QOF_MOD_SESSION;
 } //extern 'C'
 
 #include "qofbackend-p.h"
-#include "qofsession-p.h"
+#include "qofsession.hpp"
 #include "gnc-backend-prov.hpp"
 
 #include <vector>
+#include <boost/algorithm/string.hpp>
+#include <vector>
 #include <algorithm>
 #include <string>
 #include <sstream>
@@ -79,7 +76,6 @@ static ProviderVec s_providers;
 
 ProviderVec& get_providers (void );
 bool get_providers_initialized (void );
-void unregister_all_providers (void );
 
 ProviderVec&
 get_providers (void)
@@ -94,17 +90,15 @@ get_providers_initialized (void)
 }
 
 void
-unregister_all_providers (void)
+qof_backend_register_provider (QofBackendProvider_ptr&& prov)
 {
-    s_providers.clear();
+    s_providers.emplace_back(std::move(prov));
 }
 
-/* ====================================================================== */
-
 void
-qof_backend_register_provider (QofBackendProvider_ptr&& prov)
+qof_backend_unregister_all_providers ()
 {
-    s_providers.emplace_back(std::move(prov));
+    s_providers.clear ();
 }
 
 /* Called from C so we have to keep the GList for now. */
@@ -120,446 +114,346 @@ qof_backend_get_registered_access_method_list(void)
     return list;
 }
 
-
+/* QofSessionImpl */
 /* ====================================================================== */
-/* error handling routines */
+/* Constructor/Destructor ----------------------------------*/
 
-static void
-qof_session_clear_error (QofSession *session)
+QofSessionImpl::QofSessionImpl () noexcept
+    : m_book {qof_book_new ()},
+    m_book_id {},
+    m_saving {false},
+    m_error_message {}
 {
-    QofBackendError err;
-
-    session->last_err = ERR_BACKEND_NO_ERR;
-    g_free(session->error_message);
-    session->error_message = NULL;
-
-    /* pop the stack on the backend as well. */
-    if (session->backend)
-    {
-        do
-        {
-            err = qof_backend_get_error (session->backend);
-        }
-        while (ERR_BACKEND_NO_ERR != err);
-    }
+    clear_error ();
 }
 
-void
-qof_session_push_error (QofSession *session, QofBackendError err,
-                        const char *message)
+QofSessionImpl::~QofSessionImpl () noexcept
 {
-    if (!session) return;
-
-    g_free (session->error_message);
-
-    session->last_err = err;
-    session->error_message = g_strdup (message);
-}
-
-QofBackendError
-qof_session_get_error (QofSession * session)
-{
-    QofBackendError err;
-
-    if (!session) return ERR_BACKEND_NO_BACKEND;
-
-    /* if we have a local error, return that. */
-    if (ERR_BACKEND_NO_ERR != session->last_err)
-    {
-        return session->last_err;
-    }
-
-    /* maybe we should return a no-backend error ??? */
-    if (! session->backend) return ERR_BACKEND_NO_ERR;
-
-    err = qof_backend_get_error (session->backend);
-    session->last_err = err;
-    return err;
-}
-
-static const char *
-get_default_error_message(QofBackendError err)
-{
-    return "";
-}
-
-const char *
-qof_session_get_error_message(const QofSession *session)
-{
-    if (!session) return "";
-    if (!session->error_message)
-        return get_default_error_message(session->last_err);
-    return session->error_message;
-}
-
-QofBackendError
-qof_session_pop_error (QofSession * session)
-{
-    QofBackendError err;
-
-    if (!session) return ERR_BACKEND_NO_BACKEND;
-
-    err = qof_session_get_error(session);
-    qof_session_clear_error(session);
-
-    return err;
+    ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
+    end ();
+    destroy_backend ();
+    qof_book_set_backend (m_book, nullptr);
+    qof_book_destroy (m_book);
+    m_book = nullptr;
+    LEAVE ("sess=%p", this);
 }
 
-/* ====================================================================== */
-
-static void
-qof_session_init (QofSession *session)
+void
+qof_session_destroy (QofSession * session)
 {
-    if (!session) return;
-
-    session->entity.e_type = QOF_ID_SESSION;
-    session->book = qof_book_new ();
-    session->book_id = NULL;
-    session->backend = NULL;
-    session->lock = 1;
-
-    qof_session_clear_error (session);
+    delete session;
 }
 
 QofSession *
 qof_session_new (void)
 {
-    QofSession *session = g_new0(QofSession, 1);
-    qof_session_init(session);
-    return session;
+    return new QofSessionImpl;
 }
 
-QofBook *
-qof_session_get_book (const QofSession *session)
+void
+QofSessionImpl::destroy_backend () noexcept
 {
-    if (!session) return NULL;
-    if (!session->book) return NULL;
-
-    if ('y' == session->book->book_open)
+    auto backend = qof_book_get_backend (m_book);
+    if (backend)
     {
-        return session->book;
-    }
-    else
-    {
-        return NULL;
+        clear_error ();
+        if (backend->destroy_backend)
+            backend->destroy_backend (backend);
+        else
+            g_free(backend);
+        qof_book_set_backend (m_book, nullptr);
     }
 }
 
-QofBackend *
-qof_session_get_backend (const QofSession *session)
-{
-    if (!session) return NULL;
-    return session->backend;
-}
-
-const char *
-qof_session_get_file_path (const QofSession *session)
-{
-    if (!session) return NULL;
-    if (!session->backend) return NULL;
-    return session->backend->fullpath;
-}
-
-const char *
-qof_session_get_url (const QofSession *session)
-{
-    if (!session) return NULL;
-    return session->book_id;
-}
-
-void
-qof_session_ensure_all_data_loaded (QofSession *session)
-{
-    QofBackend* backend;
-
-    if (session == NULL) return;
-    backend = qof_session_get_backend(session);
-    if (backend == NULL) return;
-
-    if (backend->load == NULL) return;
-    backend->load(backend, qof_session_get_book(session), LOAD_TYPE_LOAD_ALL);
-    qof_session_push_error (session, qof_backend_get_error(backend), NULL);
-}
-
 /* ====================================================================== */
 
-static void
-qof_session_load_backend(QofSession * session, const char * access_method)
+void
+QofSessionImpl::load_backend (std::string access_method) noexcept
 {
-
-    ENTER (" list=%lu", s_providers.size());
-    for (QofBackendProvider_ptr& prov : s_providers)
+    ENTER (" list=%lu", s_providers.size ());
+    for (auto const & prov : s_providers)
     {
-        /* Does this provider handle the desired access method? */
-        if (0 != g_ascii_strcasecmp (access_method, prov->access_method))
+        if (!boost::iequals (access_method, prov->access_method))
+        {
+            PINFO ("The provider providers access_method, %s, but we're loading for access_method, %s. Skipping.",
+                    prov->access_method, access_method.c_str ());
             continue;
-
-        /* More than one backend could provide this
-           access method, check file type compatibility. */
-
-        if (!prov->type_check(session->book_id))
+        }
+        PINFO (" Selected provider %s", prov->provider_name);
+        if (!prov->type_check (m_book_id.c_str ()))
         {
-            PINFO(" %s not usable", prov->provider_name);
+            PINFO("Provider, %s, reported not being usable for book, %s.",
+                    prov->provider_name, m_book_id.c_str ());
             continue;
         }
-        PINFO (" selected %s", prov->provider_name);
-        /* Use the providers creation callback */
-        session->backend = prov->create_backend();
-        /* Tell the book about the backend that they'll be using. */
-        qof_book_set_backend (session->book, session->backend);
+        auto backend = prov->create_backend();
+        qof_book_set_backend (m_book, backend);
         LEAVE (" ");
         return;
     }
-
-    std::ostringstream msgstrm;
-    msgstrm << "Failed to load '" << access_method << "' using access_method";
-    qof_session_push_error (session, ERR_BACKEND_NO_HANDLER,
-                            msgstrm.str().c_str());
+    std::string msg {"failed to get_backend using access method \"" + access_method + "\""};
+    push_error (ERR_BACKEND_NO_HANDLER, msg);
     LEAVE (" ");
 }
 
-/* ====================================================================== */
-
-static void
-qof_session_destroy_backend (QofSession *session)
+void
+QofSessionImpl::load (QofPercentageFunc percentage_func) noexcept
 {
-    g_return_if_fail (session);
+    if (!m_book_id.size ()) return;
+    ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
 
-    if (session->backend)
-    {
-        /* clear any error message */
-        char * msg = qof_backend_get_message (session->backend);
-        g_free (msg);
+    /* At this point, we should are supposed to have a valid book
+    * id and a lock on the file. */
+    QofBook * oldbook {m_book};
 
-        /* Then destroy the backend */
-        if (session->backend->destroy_backend)
-        {
-            session->backend->destroy_backend(session->backend);
-        }
-        else
+    QofBook * newbook {qof_book_new ()};
+    m_book = newbook;
+    PINFO ("new book=%p", newbook);
+    clear_error ();
+
+    /* This code should be sufficient to initialize *any* backend,
+    * whether http, postgres, or anything else that might come along.
+    * Basically, the idea is that by now, a backend has already been
+    * created & set up.  At this point, we only need to get the
+    * top-level account group out of the backend, and that is a
+    * generic, backend-independent operation.
+    */
+    QofBackend * be {qof_book_get_backend (oldbook)};
+    qof_book_set_backend (newbook, be);
+
+    /* Starting the session should result in a bunch of accounts
+    * and currencies being downloaded, but probably no transactions;
+    * The GUI will need to do a query for that.
+    */
+    if (be)
+    {
+        be->percentage = percentage_func;
+        if (be->load)
         {
-            g_free(session->backend);
+            be->load (be, newbook, LOAD_TYPE_INITIAL_LOAD);
+            push_error (qof_backend_get_error(be), {});
         }
     }
 
-    session->backend = NULL;
+    /* XXX if the load fails, then we try to restore the old set of books;
+    * however, we don't undo the session id (the URL).  Thus if the
+    * user attempts to save after a failed load, they weill be trying to
+    * save to some bogus URL.   This is wrong. XXX  FIXME.
+    */
+    auto err = get_error ();
+    if ((err != ERR_BACKEND_NO_ERR) &&
+            (err != ERR_FILEIO_FILE_TOO_OLD) &&
+            (err != ERR_FILEIO_NO_ENCODING) &&
+            (err != ERR_FILEIO_FILE_UPGRADE) &&
+            (err != ERR_SQL_DB_TOO_OLD) &&
+            (err != ERR_SQL_DB_TOO_NEW))
+    {
+        /* Something broke, put back the old stuff */
+        qof_book_set_backend (newbook, NULL);
+        qof_book_destroy (newbook);
+        m_book = oldbook;
+        LEAVE ("error from backend %d", get_error ());
+        return;
+    }
+    qof_book_set_backend (oldbook, NULL);
+    qof_book_destroy (oldbook);
+
+    LEAVE ("sess = %p, book_id=%s", this, m_book_id.c_str ());
 }
 
 void
-qof_session_begin (QofSession *session, const char * book_id,
-                   gboolean ignore_lock, gboolean create, gboolean force)
+QofSessionImpl::begin (std::string new_book_id, bool ignore_lock, bool create, bool force) noexcept
 {
-    gchar *scheme = NULL, *filename = NULL;
-
-    if (!session) return;
-
     ENTER (" sess=%p ignore_lock=%d, book-id=%s",
-           session, ignore_lock,
-           book_id ? book_id : "(null)");
-
-    /* Clear the error condition of previous errors */
-    qof_session_clear_error (session);
-
+           this, ignore_lock, new_book_id.c_str ());
+    clear_error ();
     /* Check to see if this session is already open */
-    if (session->book_id)
+    if (m_book_id.size ())
     {
-        if (ERR_BACKEND_NO_ERR != qof_session_get_error(session))
-            qof_session_push_error (session, ERR_BACKEND_LOCKED, NULL);
+        if (ERR_BACKEND_NO_ERR != get_error ())
+            push_error (ERR_BACKEND_LOCKED, {});
         LEAVE("push error book is already open ");
         return;
     }
 
     /* seriously invalid */
-    if (!book_id)
+    if (!new_book_id.size ())
     {
-        if (ERR_BACKEND_NO_ERR != qof_session_get_error(session))
-            qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
-        LEAVE("push error missing book_id");
+        if (ERR_BACKEND_NO_ERR != get_error ())
+            push_error (ERR_BACKEND_BAD_URL, {});
+        LEAVE("push error missing new_book_id");
         return;
     }
-    scheme = g_uri_parse_scheme (book_id);
+
+    char * scheme {g_uri_parse_scheme (new_book_id.c_str ())};
+    char * filename {nullptr};
     if (g_strcmp0 (scheme, "file") == 0)
-        filename = g_filename_from_uri (book_id, NULL, NULL);
+        filename = g_filename_from_uri (new_book_id.c_str (), nullptr, nullptr);
     else if (!scheme)
-        filename = g_strdup (book_id);
+        filename = g_strdup (new_book_id.c_str ());
 
     if (filename && g_file_test (filename, G_FILE_TEST_IS_DIR))
     {
-        if (ERR_BACKEND_NO_ERR == qof_session_get_error(session))
-            qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
+        if (ERR_BACKEND_NO_ERR == get_error ())
+            push_error (ERR_BACKEND_BAD_URL, {});
         g_free (filename);
         g_free (scheme);
         LEAVE("Can't open a directory");
         return;
     }
-
-
     /* destroy the old backend */
-    qof_session_destroy_backend(session);
-
+    destroy_backend ();
     /* Store the session URL  */
-    session->book_id = g_strdup (book_id);
-
+    m_book_id = new_book_id;
     if (filename)
-        qof_session_load_backend(session, "file");
+        load_backend ("file");
     else                       /* access method found, load appropriate backend */
-        qof_session_load_backend(session, scheme);
+        load_backend (scheme);
     g_free (filename);
     g_free (scheme);
 
     /* No backend was found. That's bad. */
-    if (NULL == session->backend)
+    if (!qof_book_get_backend (m_book))
     {
-        g_free(session->book_id);
-        session->book_id = NULL;
-        if (ERR_BACKEND_NO_ERR == qof_session_get_error(session))
-            qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
+        m_book_id = {};
+        if (ERR_BACKEND_NO_ERR == get_error ())
+            push_error (ERR_BACKEND_BAD_URL, {});
         LEAVE (" BAD: no backend: sess=%p book-id=%s",
-               session,  book_id ? book_id : "(null)");
+               this,  new_book_id.c_str ());
         return;
     }
 
     /* If there's a begin method, call that. */
-    if (session->backend->session_begin)
+    if (qof_book_get_backend (m_book)->session_begin)
     {
-        char *msg;
-        QofBackendError err;
-
-        (session->backend->session_begin)(session->backend, session,
-                                          session->book_id, ignore_lock,
-                                          create, force);
-        PINFO("Done running session_begin on backend");
-        err = qof_backend_get_error(session->backend);
-        msg = qof_backend_get_message(session->backend);
+        auto backend = qof_book_get_backend (m_book);
+        (backend->session_begin) (backend, this, m_book_id.c_str (), ignore_lock, create, force);
+        PINFO ("Done running session_begin on backend");
+        QofBackendError const err {qof_backend_get_error (backend)};
+        char * msg {qof_backend_get_message (backend)};
         if (err != ERR_BACKEND_NO_ERR)
         {
-            g_free(session->book_id);
-            session->book_id = NULL;
-            qof_session_push_error (session, err, msg);
-            LEAVE(" backend error %d %s", err, msg ? msg : "(null)");
+            m_book_id = {};
+            push_error (err, msg ? msg : "");
+            LEAVE (" backend error %d %s", err, msg ? msg : "(null)");
             return;
         }
-        if (msg != NULL)
+        if (msg != nullptr)
         {
             PWARN("%s", msg);
             g_free(msg);
         }
     }
+    LEAVE (" sess=%p book-id=%s", this,  new_book_id.c_str ());
+}
 
-    LEAVE (" sess=%p book-id=%s",
-           session,  book_id ? book_id : "(null)");
+void
+QofSessionImpl::end () noexcept
+{
+    ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
+    auto backend = qof_book_get_backend (m_book);
+    if (backend && backend->session_end)
+        (backend->session_end) (backend);
+    clear_error ();
+    m_book_id = {};
+    LEAVE ("sess=%p book_id=%s", this, m_book_id.c_str ());
 }
 
-/* ====================================================================== */
+/* error handling functions --------------------------------*/
 
 void
-qof_session_load (QofSession *session,
-                  QofPercentageFunc percentage_func)
+QofSessionImpl::clear_error () noexcept
 {
-    QofBook *newbook, *oldbook;
-    QofBackend *be;
-    QofBackendError err;
-
-    if (!session) return;
-    if (!session->book_id) return;
+    m_last_err = ERR_BACKEND_NO_ERR;
+    m_error_message = {};
 
-    ENTER ("sess=%p book_id=%s", session, session->book_id
-           ? session->book_id : "(null)");
+    /* pop the stack on the backend as well. */
+    if (qof_book_get_backend (m_book))
+    {
+        QofBackendError err;
+        do
+            err = qof_backend_get_error (qof_book_get_backend (m_book));
+        while (ERR_BACKEND_NO_ERR != err);
+    }
+}
 
-    /* At this point, we should are supposed to have a valid book
-    * id and a lock on the file. */
+void
+QofSessionImpl::push_error (QofBackendError const err, std::string message) noexcept
+{
+    m_last_err = err;
+    m_error_message = message;
+}
 
-    oldbook = session->book;
+QofBackendError
+QofSessionImpl::get_error () noexcept
+{
+    /* if we have a local error, return that. */
+    if (ERR_BACKEND_NO_ERR != m_last_err)
+        return m_last_err;
 
-    /* XXX why are we creating a book here? I think the books
-    * need to be handled by the backend ... especially since
-    * the backend may need to load multiple books ... XXX. FIXME.
-    */
-    newbook = qof_book_new();
-    session->book = newbook;
-    PINFO ("new book=%p", newbook);
+    if (!qof_book_get_backend (m_book)) return ERR_BACKEND_NO_ERR;
 
-    qof_session_clear_error (session);
+    m_last_err = qof_backend_get_error (qof_book_get_backend (m_book));
+    return m_last_err;
+}
 
-    /* This code should be sufficient to initialize *any* backend,
-    * whether http, postgres, or anything else that might come along.
-    * Basically, the idea is that by now, a backend has already been
-    * created & set up.  At this point, we only need to get the
-    * top-level account group out of the backend, and that is a
-    * generic, backend-independent operation.
-    */
-    be = session->backend;
-    qof_book_set_backend(newbook, be);
+std::string
+QofSessionImpl::get_error_message () const noexcept
+{
+    return m_error_message;
+}
 
-    /* Starting the session should result in a bunch of accounts
-    * and currencies being downloaded, but probably no transactions;
-    * The GUI will need to do a query for that.
-    */
-    if (be)
-    {
-        be->percentage = percentage_func;
+QofBackendError
+QofSessionImpl::pop_error () noexcept
+{
+    QofBackendError err {get_error ()};
+    clear_error ();
+    return err;
+}
 
-        if (be->load)
-        {
-            be->load (be, newbook, LOAD_TYPE_INITIAL_LOAD);
-            qof_session_push_error (session, qof_backend_get_error(be), NULL);
-        }
-    }
+/* Accessors (getters/setters) -----------------------------*/
 
-    /* XXX if the load fails, then we try to restore the old set of books;
-    * however, we don't undo the session id (the URL).  Thus if the
-    * user attempts to save after a failed load, they weill be trying to
-    * save to some bogus URL.   This is wrong. XXX  FIXME.
-    */
-    err = qof_session_get_error(session);
-    if ((err != ERR_BACKEND_NO_ERR) &&
-            (err != ERR_FILEIO_FILE_TOO_OLD) &&
-            (err != ERR_FILEIO_NO_ENCODING) &&
-            (err != ERR_FILEIO_FILE_UPGRADE) &&
-            (err != ERR_SQL_DB_TOO_OLD) &&
-            (err != ERR_SQL_DB_TOO_NEW))
-    {
-        /* Something broke, put back the old stuff */
-        qof_book_set_backend (newbook, NULL);
-        qof_book_destroy (newbook);
-        session->book = oldbook;
-        LEAVE("error from backend %d", qof_session_get_error(session));
-        return;
-    }
-    qof_book_set_backend (oldbook, NULL);
-    qof_book_destroy (oldbook);
+QofBook *
+QofSessionImpl::get_book () const noexcept
+{
+    if (!m_book) return nullptr;
+    if ('y' == m_book->book_open)
+        return m_book;
+    return nullptr;
+}
 
-    LEAVE ("sess = %p, book_id=%s", session, session->book_id
-           ? session->book_id : "(null)");
+QofBackend *
+QofSession::get_backend () const noexcept
+{
+    return qof_book_get_backend (m_book);
 }
 
-/* ====================================================================== */
+std::string
+QofSessionImpl::get_file_path () const noexcept
+{
+    if (!qof_book_get_backend (m_book)) return nullptr;
+    return qof_book_get_backend (m_book)->fullpath;
+}
 
-static gboolean
-save_error_handler(QofBackend *be, QofSession *session)
+std::string const &
+QofSessionImpl::get_book_id () const noexcept
 {
-    QofBackendError err;
-    err = qof_backend_get_error(be);
+    return m_book_id;
+}
 
-    if (ERR_BACKEND_NO_ERR != err)
-    {
-        qof_session_push_error (session, err, NULL);
-        return TRUE;
-    }
-    return FALSE;
+bool
+QofSessionImpl::is_saving () const noexcept
+{
+    return m_saving;
 }
 
+/* Manipulators (save, load, etc.) -------------------------*/
+
 void
-qof_session_save (QofSession *session,
-                  QofPercentageFunc percentage_func)
+QofSessionImpl::save (QofPercentageFunc percentage_func) noexcept
 {
-    QofBackend *be;
-
-    if (!session) return;
-    if (!g_atomic_int_dec_and_test(&session->lock))
-        goto leave;
-    ENTER ("sess=%p book_id=%s",
-           session, session->book_id ? session->book_id : "(null)");
+    m_saving = true;
+    ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
 
     /* If there is a backend, and the backend is reachable
     * (i.e. we can communicate with it), then synchronize with
@@ -570,228 +464,295 @@ qof_session_save (QofSession *session,
     * hack alert -- FIXME -- XXX the code below no longer
     * does what the words above say.  This needs fixing.
     */
-    be = session->backend;
-    if (be)
+    auto backend = qof_book_get_backend (m_book);
+    if (backend)
     {
         /* if invoked as SaveAs(), then backend not yet set */
-        qof_book_set_backend (session->book, be);
-        be->percentage = percentage_func;
-        if (be->sync)
+        qof_book_set_backend (m_book, backend);
+        backend->percentage = percentage_func;
+        if (backend->sync)
         {
-            (be->sync)(be, session->book);
-            if (save_error_handler(be, session))
-                goto leave;
+            (backend->sync)(backend, m_book);
+            QofBackendError err {qof_backend_get_error (backend)};
+            if (ERR_BACKEND_NO_ERR != err)
+            {
+                push_error (err, {});
+                m_saving = false;
+                return;
+            }
         }
-
         /* If we got to here, then the backend saved everything
         * just fine, and we are done. So return. */
-        /* Return the book_id to previous value. */
-        qof_session_clear_error (session);
+        clear_error ();
         LEAVE("Success");
-        goto leave;
     }
     else
     {
-        if (ERR_BACKEND_NO_ERR != qof_session_get_error(session))
-        {
-	    /* push_error strdups, stack const is fine. */
-	    const char *msg = "failed to load backend";
-            qof_session_push_error(session, ERR_BACKEND_NO_HANDLER, msg);
-        }
+        push_error (ERR_BACKEND_NO_HANDLER, "failod to load backend");
+        LEAVE("error -- No backend!");
     }
-    LEAVE("error -- No backend!");
-leave:
-    g_atomic_int_inc(&session->lock);
-    return;
+    m_saving = false;
 }
 
 void
-qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
-{
-    QofBackend *be = session->backend;
-    QofBackendError err;
-    char *msg = NULL;
-    g_return_if_fail( be != NULL );
-    g_return_if_fail( be->safe_sync != NULL );
-    be->percentage = percentage_func;
-    (be->safe_sync)( be, qof_session_get_book( session ));
-    err = qof_backend_get_error(session->backend);
-    msg = qof_backend_get_message(session->backend);
+QofSessionImpl::safe_save (QofPercentageFunc percentage_func) noexcept
+{
+    auto backend = qof_book_get_backend (m_book);
+    if (!backend) return;
+    if (!backend->safe_sync) return;
+    backend->percentage = percentage_func;
+    (backend->safe_sync) (backend, get_book ());
+    auto err = qof_backend_get_error (qof_book_get_backend (m_book));
+    auto msg = qof_backend_get_message (qof_book_get_backend (m_book));
     if (err != ERR_BACKEND_NO_ERR)
     {
-        g_free(session->book_id);
-        session->book_id = NULL;
-        qof_session_push_error (session, err, msg);
-        /* qof_backend_get_message transfers ownership. */
-	g_free(msg);
+        m_book_id = {};
+        push_error (err, msg ? msg : "");
     }
+    g_free (msg);
 }
 
-
-/* ====================================================================== */
-gboolean
-qof_session_save_in_progress(const QofSession *session)
+void
+QofSessionImpl::ensure_all_data_loaded () noexcept
 {
-    return (session && g_atomic_int_get(&session->lock) != 1);
+    auto backend = qof_book_get_backend (m_book);
+    if (!backend) return;
+    if (!backend->load) return;
+    backend->load(backend, get_book (), LOAD_TYPE_LOAD_ALL);
+    push_error (qof_backend_get_error (backend), {});
 }
 
 void
-qof_session_end (QofSession *session)
+QofSessionImpl::swap_books (QofSessionImpl & other) noexcept
+{
+    ENTER ("sess1=%p sess2=%p", this, &other);
+    // don't swap (that is, double-swap) read_only flags
+    std::swap (m_book->read_only, other.m_book->read_only);
+    std::swap (m_book, other.m_book);
+    auto mybackend = qof_book_get_backend (m_book);
+    qof_book_set_backend (m_book, qof_book_get_backend (other.m_book));
+    qof_book_set_backend (other.m_book, mybackend);
+    LEAVE (" ");
+}
+
+bool
+QofSessionImpl::events_pending () const noexcept
 {
-    if (!session) return;
+    auto backend = qof_book_get_backend (m_book);
+    if (!backend) return false;
+    if (!backend->events_pending) return false;
+    return backend->events_pending (backend);
+}
 
-    ENTER ("sess=%p book_id=%s", session, session->book_id
-           ? session->book_id : "(null)");
+bool
+QofSessionImpl::process_events () const noexcept
+{
+    auto backend = qof_book_get_backend (m_book);
+    if (!backend) return false;
+    if (!backend->process_events) return false;
+    return backend->process_events (backend);
+}
 
-    /* close down the backend first */
-    if (session->backend && session->backend->session_end)
-    {
-        (session->backend->session_end)(session->backend);
-    }
+/* XXX This exports the list of accounts to a file.  It does not
+ * export any transactions.  It's a place-holder until full
+ * book-closing is implemented.
+ */
+bool
+QofSessionImpl::export_session (QofSessionImpl & real_session, QofPercentageFunc percentage_func) noexcept
+{
+    auto real_book = real_session.get_book ();
+    ENTER ("tmp_session=%p real_session=%p book=%p book_id=%s",
+           this, &real_session, real_book, m_book_id.c_str ());
 
-    qof_session_clear_error (session);
+    /* There must be a backend or else.  (It should always be the file
+     * backend too.)
+     */
+    auto backend2 = qof_book_get_backend(m_book);
+    if (!backend2) return false;
 
-    g_free (session->book_id);
-    session->book_id = NULL;
+    backend2->percentage = percentage_func;
+    if (!backend2->export_fn) return true;
 
-    LEAVE ("sess=%p book_id=%s", session, session->book_id
-           ? session->book_id : "(null)");
+    (backend2->export_fn)(backend2, real_book);
+    auto err = qof_backend_get_error(backend2);
+    if (ERR_BACKEND_NO_ERR != err)
+        return false;
+    return true;
 }
 
-void
-qof_session_destroy (QofSession *session)
-{
-    if (!session) return;
+/* C Wrapper Functions */
+/* ====================================================================== */
 
-    ENTER ("sess=%p book_id=%s", session, session->book_id
-           ? session->book_id : "(null)");
+const char *
+qof_session_get_error_message (const QofSession * session)
+{
+    if (!session) return "";
+    return session->get_error_message ().c_str ();
+}
 
-    qof_session_end (session);
+QofBackendError
+qof_session_pop_error (QofSession * session)
+{
+    if (!session) return ERR_BACKEND_NO_BACKEND;
+    return session->pop_error ();
+}
 
-    /* destroy the backend */
-    qof_session_destroy_backend(session);
+QofBook *
+qof_session_get_book (const QofSession *session)
+{
+    if (!session) return NULL;
+    return session->get_book ();
+}
 
-    qof_book_set_backend (session->book, NULL);
-    qof_book_destroy (session->book);
-    session->book  = NULL;
+const char *
+qof_session_get_file_path (const QofSession *session)
+{
+    if (!session) return NULL;
+    return session->get_file_path ().c_str ();
+}
 
-    g_free (session);
+void
+qof_session_ensure_all_data_loaded (QofSession *session)
+{
+    if (session == nullptr) return;
+    return session->ensure_all_data_loaded ();
+}
 
-    LEAVE ("sess=%p", session);
+const char *
+qof_session_get_url (const QofSession *session)
+{
+    if (!session) return NULL;
+    return session->get_book_id ().c_str ();
 }
 
-/* ====================================================================== */
-/* this call is weird. */
+QofBackend *
+qof_session_get_backend (const QofSession *session)
+{
+    if (!session) return NULL;
+    return session->get_backend ();
+}
 
 void
-qof_session_swap_data (QofSession *session_1, QofSession *session_2)
+qof_session_begin (QofSession *session, const char * book_id,
+                   gboolean ignore_lock, gboolean create, gboolean force)
 {
-    QofBook *book_1, *book_2;
-    gboolean tmp;
-
-    if (session_1 == session_2) return;
-    if (!session_1 || !session_2) return;
-
-    ENTER ("sess1=%p sess2=%p", session_1, session_2);
+    if (!session) return;
+    session->begin((book_id ? book_id : ""), ignore_lock, create, force);
+}
 
-    book_1 = session_1->book;
-    book_2 = session_2->book;
+void
+qof_session_load (QofSession *session,
+                  QofPercentageFunc percentage_func)
+{
+    if (!session) return;
+    session->load (percentage_func);
+}
 
-    // Swap the read_only flags backwards.
-    tmp = book_1->read_only;
-    book_1->read_only = book_2->read_only;
-    book_2->read_only = tmp;
+void
+qof_session_save (QofSession *session,
+                  QofPercentageFunc percentage_func)
+{
+    if (!session) return;
+    session->save (percentage_func);
+}
 
-    session_1->book = book_2;
-    session_2->book = book_1;
+void
+qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
+{
+    if (!session) return;
+    session->safe_save (percentage_func);
+}
 
-    qof_book_set_backend (book_1, session_2->backend);
-    qof_book_set_backend (book_2, session_1->backend);
+gboolean
+qof_session_save_in_progress(const QofSession *session)
+{
+    if (!session) return false;
+    return session->is_saving ();
+}
 
-    LEAVE (" ");
+void
+qof_session_end (QofSession *session)
+{
+    if (!session) return;
+    session->end ();
 }
 
-/* ====================================================================== */
+void
+qof_session_swap_data (QofSession *session_1, QofSession *session_2)
+{
+    if (session_1 == session_2) return;
+    if (!session_1 || !session_2) return;
+    session_1->swap_books (*session_2);
+}
 
 gboolean
 qof_session_events_pending (const QofSession *session)
 {
-    if (!session) return FALSE;
-    if (!session->backend) return FALSE;
-    if (!session->backend->events_pending) return FALSE;
-
-    return session->backend->events_pending (session->backend);
+    if (!session) return false;
+    return session->events_pending ();
 }
 
 gboolean
 qof_session_process_events (QofSession *session)
 {
     if (!session) return FALSE;
-    if (!session->backend) return FALSE;
-    if (!session->backend->process_events) return FALSE;
-
-    return session->backend->process_events (session->backend);
+    return session->process_events ();
 }
 
-/* XXX This exports the list of accounts to a file.  It does not
- * export any transactions.  It's a place-holder until full
- * book-closing is implemented.
- */
 gboolean
 qof_session_export (QofSession *tmp_session,
                     QofSession *real_session,
                     QofPercentageFunc percentage_func)
 {
-    QofBook *book, *book2;
-    QofBackend *be;
-
     if ((!tmp_session) || (!real_session)) return FALSE;
+    return tmp_session->export_session (*real_session, percentage_func);
+}
 
-    book = qof_session_get_book (real_session);
-    ENTER ("tmp_session=%p real_session=%p book=%p book_id=%s",
-           tmp_session, real_session, book,
-           qof_session_get_url(tmp_session)
-           ? qof_session_get_url(tmp_session) : "(null)");
-
-    /* There must be a backend or else.  (It should always be the file
-     * backend too.)
-     */
-    book2 = qof_session_get_book(tmp_session);
-    be = qof_book_get_backend(book2);
-    if (!be)
-        return FALSE;
-
-    be->percentage = percentage_func;
-    if (be->export_fn)
-    {
-        int err;
+/* ================= Static function access for testing ================= */
 
-        (be->export_fn)(be, book);
-        err = qof_backend_get_error(be);
+void init_static_qofsession_pointers (void);
 
-        if (ERR_BACKEND_NO_ERR != err)
-        {
-            return FALSE;
-        }
-    }
+void qof_session_load_backend (QofSession * session, const char * access_method)
+{
+    session->load_backend (access_method);
+}
 
-    return TRUE;
+void qof_session_clear_error (QofSession * session)
+{
+    session->clear_error ();
 }
 
-/* ================= Static function access for testing ================= */
+void qof_session_destroy_backend (QofSession * session)
+{
+    session->destroy_backend ();
+}
 
-void init_static_qofsession_pointers (void);
+void qof_session_set_book_id (QofSession * session, char const * book_id)
+{
+    if (!book_id)
+        session->m_book_id = "";
+    else
+        session->m_book_id = book_id;
+}
 
-void (*p_qof_session_load_backend) (QofSession * session, const char * access_method);
-void (*p_qof_session_clear_error) (QofSession *session);
-void (*p_qof_session_destroy_backend) (QofSession *session);
+void (*p_qof_session_load_backend) (QofSession *, const char * access_method);
+void (*p_qof_session_clear_error) (QofSession *);
+void (*p_qof_session_destroy_backend) (QofSession *);
+void (*p_qof_session_set_book_id) (QofSession *, char const * book_id);
 
 void
 init_static_qofsession_pointers (void)
 {
-    p_qof_session_load_backend = qof_session_load_backend;
-    p_qof_session_clear_error = qof_session_clear_error;
-    p_qof_session_destroy_backend = qof_session_destroy_backend;
+    p_qof_session_load_backend = &qof_session_load_backend;
+    p_qof_session_clear_error = &qof_session_clear_error;
+    p_qof_session_destroy_backend = &qof_session_destroy_backend;
+    p_qof_session_set_book_id = &qof_session_set_book_id;
+}
+
+QofBackendError
+qof_session_get_error (QofSession * session)
+{
+    if (!session) return ERR_BACKEND_NO_BACKEND;
+    return session->get_error();
 }
 
-/* =================== END OF FILE ====================================== */
diff --git a/src/libqof/qof/qofsession.h b/src/libqof/qof/qofsession.h
index afc6515..3aabdee 100644
--- a/src/libqof/qof/qofsession.h
+++ b/src/libqof/qof/qofsession.h
@@ -112,7 +112,7 @@ extern "C"
 
 /* PROTOTYPES ******************************************************/
 
-typedef struct _QofSession    QofSession;
+typedef struct QofSessionImpl QofSession;
 
 QofSession * qof_session_new (void);
 void         qof_session_destroy (QofSession *session);
@@ -156,7 +156,6 @@ void qof_session_begin (QofSession *session, const char * book_id,
                         gboolean ignore_lock, gboolean create,
                         gboolean force);
 
-
 /**
  * The qof_session_load() method causes the QofBook to be made ready to
  *    to use with this URL/datastore.   When the URL points at a file,
@@ -195,7 +194,6 @@ const char * qof_session_get_error_message(const QofSession *session);
 QofBackendError qof_session_pop_error (QofSession *session);
 /** @} */
 
-
 /** Returns the QofBook of this session. */
 QofBook * qof_session_get_book (const QofSession *session);
 
@@ -224,6 +222,11 @@ const char * qof_session_get_url (const QofSession *session);
 /* gboolean qof_session_not_saved(const QofSession *session); <- unimplemented */
 gboolean qof_session_save_in_progress(const QofSession *session);
 
+/**
+ * Returns the qof session's backend.
+ */
+QofBackend * qof_session_get_backend(const QofSession *session);
+
 /** The qof_session_save() method will commit all changes that have been
  *    made to the session. For the file backend, this is nothing
  *    more than a write to the file of the current Accounts & etc.
diff --git a/src/libqof/qof/qofsession-p.h b/src/libqof/qof/qofsession.hpp
similarity index 52%
rename from src/libqof/qof/qofsession-p.h
rename to src/libqof/qof/qofsession.hpp
index 182a261..57a2425 100644
--- a/src/libqof/qof/qofsession-p.h
+++ b/src/libqof/qof/qofsession.hpp
@@ -1,5 +1,5 @@
 /********************************************************************\
- * qofsession-p.h -- private functions for QOF sessions.            *
+ * qofsession.hpp -- declarations for QOF sessions.                 *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -31,23 +31,70 @@
 
 #include "qofbook.h"
 #include "qofsession.h"
+#include <utility>
+#include <string>
 
-struct _QofSession
+struct QofSessionImpl
 {
-    /* This is just a "fake" entry point to allow me to pass a Session as
-     * an Entity.  NOTE:  THIS IS NOT AN ENTITY!  THE ONLY PART OF ENTITY
-     * THAT IS VALID IS E_TYPE!
+    QofSessionImpl () noexcept;
+    /* Ends the current session, destroys the backend, and destroys the book.  */
+    ~QofSessionImpl () noexcept;
+
+    /** Begin this session.  */
+    void begin (std::string book_id, bool ignore_lock, bool create, bool force) noexcept;
+
+    /** Swap books with another session */
+    void swap_books (QofSessionImpl &) noexcept;
+    void ensure_all_data_loaded () noexcept;
+    void load (QofPercentageFunc) noexcept;
+    void save (QofPercentageFunc) noexcept;
+    void safe_save (QofPercentageFunc) noexcept;
+    bool save_in_progress () const noexcept;
+    bool export_session (QofSessionImpl & real_session, QofPercentageFunc) noexcept;
+
+    bool events_pending () const noexcept;
+    bool process_events () const noexcept;
+
+    void clear_error () noexcept;
+    QofBackendError pop_error () noexcept;
+
+    /**
+     * We return by reference so that a pointer to the data of the string lives
+     * long enough to make it back to C code.
+     */
+    std::string const & get_book_id () const noexcept;
+    /**
+     * Returns and clears the local cached error. If there is no local error, we check
+     * for an error in the backend.
      */
-    QofInstance entity;
+    QofBackendError get_error () noexcept;
+    std::string get_error_message () const noexcept;
+    QofBook * get_book () const noexcept;
+    QofBackend * get_backend () const noexcept;
+    std::string get_file_path () const noexcept;
+    bool is_saving () const noexcept;
+
+    /**
+     * Terminates the current backend.
+     */
+    void end () noexcept;
+    void destroy_backend () noexcept;
+
+private:
+    void push_error (QofBackendError const err, std::string message) noexcept;
+
+    void load_backend (std::string access_method) noexcept;
 
     /* A book holds pointers to the various types of datasets.
      * A session has exactly one book. */
-    QofBook *book;
+    QofBook * m_book;
 
     /* The requested book id, in the form or a URI, such as
      * file:/some/where, or sql:server.host.com:555
      */
-    char *book_id;
+    std::string m_book_id;
+
+    bool m_saving;
 
     /* If any book subroutine failed, this records the failure reason
      * (file not found, etc).
@@ -56,14 +103,14 @@ struct _QofSession
      * and the backends should all be using (or making it look like)
      * there is only one stack.
      */
-    QofBackendError last_err;
-    char *error_message;
-
-    /* ---------------------------------------------------- */
-    /* Pointer to the backend that is actually used to move data
-     * between the persistant store and the local engine.  */
-    QofBackend *backend;
-    gint lock;
+    QofBackendError m_last_err;
+    std::string m_error_message;
+
+    /* These functions support the old testing infrastructure and should
+     * be removed when they are no longer necessary.*/
+    friend void qof_session_load_backend (QofSession *, const char *);
+    friend char const * qof_session_get_book_id (QofSession *);
+    friend void qof_session_set_book_id (QofSession *, char const *);
 };
 
 typedef struct qof_instance_copy_data
@@ -84,8 +131,6 @@ extern "C"
 
 QofBackend * qof_session_get_backend (const QofSession *session);
 
-void qof_session_push_error (QofSession *session, QofBackendError err,
-                             const char *message);
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am
index 0d40f6e..5b2f1b3 100644
--- a/src/libqof/qof/test/Makefile.am
+++ b/src/libqof/qof/test/Makefile.am
@@ -14,7 +14,7 @@ test_qof_SOURCES = \
 	test-qofbook.c \
 	test-qofinstance.cpp \
 	test-qofobject.c \
-	test-qofsession.cpp \
+	test-qofsession-old.cpp \
 	test-qof-string-cache.c \
 	test-gnc-guid.cpp \
 	${top_srcdir}/src/test-core/unittest-support.c
diff --git a/src/libqof/qof/test/test-qofsession.cpp b/src/libqof/qof/test/test-qofsession-old.cpp
similarity index 83%
rename from src/libqof/qof/test/test-qofsession.cpp
rename to src/libqof/qof/test/test-qofsession-old.cpp
index ea5e4f9..537cb80 100644
--- a/src/libqof/qof/test/test-qofsession.cpp
+++ b/src/libqof/qof/test/test-qofsession-old.cpp
@@ -29,7 +29,7 @@ extern "C"
 
 #include "../qof.h"
 #include "../qofbackend-p.h"
-#include "../qofsession-p.h"
+#include "../qofsession.h"
 #include "../qofclass-p.h"
 #include "../gnc-backend-prov.hpp"
 #include <vector>
@@ -37,16 +37,16 @@ extern "C"
 static const gchar *suitename = "/qof/qofsession";
 extern "C" void test_suite_qofsession ( void );
 
-extern void (*p_qof_session_load_backend) (QofSession * session, const char * access_method);
-extern void (*p_qof_session_clear_error) (QofSession * session);
-extern void (*p_qof_session_destroy_backend) (QofSession * session);
+extern void (*p_qof_session_load_backend) (QofSession *, const char * access_method);
+extern void (*p_qof_session_clear_error) (QofSession *);
+extern void (*p_qof_session_destroy_backend) (QofSession *);
+extern void (*p_qof_session_set_book_id) (QofSession *, const char * book_id);
 
 void init_static_qofsession_pointers (void);
 
 using ProviderVec =  std::vector<QofBackendProvider_ptr>;
 extern ProviderVec& get_providers (void);
 extern bool get_providers_initialized (void);
-extern void unregister_all_providers (void);
 
 typedef struct
 {
@@ -92,14 +92,13 @@ test_qof_session_new_destroy (void)
     g_test_message ("Test session initialization");
     session = qof_session_new ();
     g_assert (session);
-    g_assert_cmpstr (session->entity.e_type, == , QOF_ID_SESSION);
-    g_assert (session->book);
-    book = (QofBook*) session->book;
+    g_assert (qof_session_get_book (session));
+    book = (QofBook*) qof_session_get_book (session);
     g_assert (book);
     g_assert (QOF_IS_BOOK (book));
-    g_assert (!session->book_id);
-    g_assert (!session->backend);
-    g_assert_cmpint (session->lock, == , 1);
+    g_assert (!strlen (qof_session_get_url (session)));
+    g_assert (!qof_session_get_backend (session));
+    g_assert (!qof_session_save_in_progress (session));
     g_assert_cmpint (qof_session_get_error (session), == , ERR_BACKEND_NO_ERR);
 
     g_test_message ("Test session destroy");
@@ -112,12 +111,12 @@ test_qof_session_new_destroy (void)
 static void
 test_session_safe_save( Fixture *fixture, gconstpointer pData )
 {
-    fixture->session->backend = g_new0 (QofBackend, 1);
-    fixture->session->backend->safe_sync = safe_sync;
+    qof_book_set_backend (qof_session_get_book (fixture->session), g_new0 (QofBackend, 1));
+    qof_book_get_backend (qof_session_get_book (fixture->session))->safe_sync = safe_sync;
     qof_session_safe_save( fixture->session, percentage_fn );
     g_assert_cmpint( ERR_BACKEND_DATA_CORRUPT, == ,
                      qof_session_get_error( fixture->session ));
-    g_assert( NULL == qof_session_get_url( fixture->session ));
+    g_assert (!strlen (qof_session_get_url (fixture->session)));
 }
 
 static struct
@@ -170,7 +169,6 @@ test_qof_session_load_backend (Fixture *fixture, gconstpointer pData)
     p_qof_session_load_backend (fixture->session, "file");
     g_assert (!get_providers_initialized ());
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
-    g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "Failed to load 'file' using access_method");
     p_qof_session_clear_error (fixture->session);
 
     g_test_message ("Test with provider registered but access method not supported");
@@ -180,7 +178,6 @@ test_qof_session_load_backend (Fixture *fixture, gconstpointer pData)
     g_assert_cmpint (get_providers().size(), == , 1);
     p_qof_session_load_backend (fixture->session, "file");
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
-    g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "Failed to load 'file' using access_method");
     p_qof_session_clear_error (fixture->session);
 
     g_test_message ("Test with access method supported but type incompatible");
@@ -189,11 +186,10 @@ test_qof_session_load_backend (Fixture *fixture, gconstpointer pData)
     qof_backend_register_provider (std::move(prov));
     load_backend_struct.data_compatible = FALSE;
     load_backend_struct.check_data_type_called = FALSE;
-    fixture->session->book_id = g_strdup ("my book");
+    p_qof_session_set_book_id (fixture->session, "my book");
     p_qof_session_load_backend (fixture->session, "file");
     g_assert (load_backend_struct.check_data_type_called);
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
-    g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "Failed to load 'file' using access_method");
     p_qof_session_clear_error (fixture->session);
 
 
@@ -202,7 +198,7 @@ test_qof_session_load_backend (Fixture *fixture, gconstpointer pData)
     load_backend_struct.data_compatible = TRUE;
     load_backend_struct.check_data_type_called = FALSE;
     load_backend_struct.backend_new_called = FALSE;
-    g_assert (fixture->session->backend == NULL);
+    g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == NULL);
     book = qof_session_get_book (fixture->session);
     g_assert (book);
     g_assert (qof_book_get_backend (book) == NULL);
@@ -210,11 +206,11 @@ test_qof_session_load_backend (Fixture *fixture, gconstpointer pData)
     g_assert (load_backend_struct.check_data_type_called);
     g_assert (load_backend_struct.backend_new_called);
     g_assert (load_backend_struct.be);
-    g_assert (load_backend_struct.be == fixture->session->backend);
+    g_assert (load_backend_struct.be == qof_book_get_backend (qof_session_get_book (fixture->session)));
     g_assert (qof_book_get_backend (book) == load_backend_struct.be);
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR);
 
-    unregister_all_providers ();
+    qof_backend_unregister_all_providers ();
     g_assert_cmpint (get_providers().size(), == , 0);
 }
 
@@ -249,36 +245,36 @@ test_qof_session_load (Fixture *fixture, gconstpointer pData)
     QofBook *newbook = NULL;
 
     /* init */
-    fixture->session->book_id = g_strdup ("my book");
+    p_qof_session_set_book_id (fixture->session, "my book");
     be = g_new0 (QofBackend, 1);
     g_assert (be);
-    fixture->session->backend = be;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
     be->load = mock_load;
 
     g_test_message ("Test when no error is produced");
     g_assert (be->percentage == NULL);
     load_session_struct.be = be;
     load_session_struct.oldbook = qof_session_get_book (fixture->session);
-    g_assert (fixture->session->book);
+    g_assert (qof_session_get_book (fixture->session));
     load_session_struct.error = FALSE;
     load_session_struct.load_called = FALSE;
     qof_session_load (fixture->session, percentage_fn);
     newbook = qof_session_get_book (fixture->session);
     g_assert (newbook);
     g_assert (load_session_struct.oldbook != newbook);
-    g_assert (fixture->session->book);
+    g_assert (qof_session_get_book (fixture->session));
     g_assert (load_session_struct.load_called);
 
     g_test_message ("Test when no is produced");
     load_session_struct.oldbook = qof_session_get_book (fixture->session);
-    g_assert (fixture->session->book);
+    g_assert (qof_session_get_book (fixture->session));
     load_session_struct.error = TRUE;
     load_session_struct.load_called = FALSE;
     qof_session_load (fixture->session, percentage_fn);
     newbook = qof_session_get_book (fixture->session);
     g_assert (newbook);
     g_assert (load_session_struct.oldbook == newbook);
-    g_assert (fixture->session->book);
+    g_assert (qof_session_get_book (fixture->session));
     g_assert (load_session_struct.load_called);
 }
 
@@ -357,16 +353,15 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
 
     /* run tests */
     g_test_message ("Test when book_id is set backend is not changed");
-    fixture->session->backend = be;
-    fixture->session->book_id = g_strdup ("my book");
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
+    p_qof_session_set_book_id (fixture->session, "my book");
     qof_session_begin (fixture->session, "my book", ignore_lock, create, force);
-    g_assert (fixture->session->backend == be);
+    g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == be);
 
     g_test_message ("Test when session book_id is not set and book_id passed is null backend is not changed");
-    g_free (fixture->session->book_id);
-    fixture->session->book_id = NULL;
+    p_qof_session_set_book_id (fixture->session, NULL);
     qof_session_begin (fixture->session, NULL, ignore_lock, create, force);
-    g_assert (fixture->session->backend == be);
+    g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == be);
 
     g_test_message ("Test default access_method parsing");
     /* routine will destroy old backend
@@ -374,17 +369,15 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
      * as there is no backend registered error will be raised
      */
     qof_session_begin (fixture->session, "default_should_be_file", ignore_lock, create, force);
-    g_assert (fixture->session->backend == NULL);
-    g_assert (fixture->session->book_id == NULL);
+    g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == NULL);
+    g_assert (!strlen (qof_session_get_url (fixture->session)));
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
-    g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "Failed to load 'file' using access_method");
 
     g_test_message ("Test access_method parsing");
     qof_session_begin (fixture->session, "postgres://localhost:8080", ignore_lock, create, force);
-    g_assert (fixture->session->backend == NULL);
-    g_assert (fixture->session->book_id == NULL);
+    g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == NULL);
+    g_assert (!strlen (qof_session_get_url (fixture->session)));
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
-    g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "Failed to load 'postgres' using access_method");
 
     g_test_message ("Test with valid backend returned and session begin set; error is produced");
     session_begin_struct.session = fixture->session;
@@ -397,11 +390,11 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
     qof_backend_register_provider (std::move(prov));
 
     qof_session_begin (fixture->session, "postgres://localhost:8080", ignore_lock, create, force);
-    g_assert (fixture->session->backend);
-    g_assert (session_begin_struct.be == fixture->session->backend);
+    g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)));
+    g_assert (session_begin_struct.be == qof_book_get_backend (qof_session_get_book (fixture->session)));
     g_assert (session_begin_struct.backend_new_called == TRUE);
     g_assert (session_begin_struct.session_begin_called == TRUE);
-    g_assert (fixture->session->book_id == NULL);
+    g_assert (!strlen (qof_session_get_url (fixture->session)));
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_DATA_CORRUPT);
     g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "push any error");
 
@@ -410,15 +403,15 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
     session_begin_struct.session_begin_called = FALSE;
     session_begin_struct.produce_error = FALSE;
     qof_session_begin (fixture->session, "postgres://localhost:8080", ignore_lock, create, force);
-    g_assert (fixture->session->backend);
-    g_assert (session_begin_struct.be == fixture->session->backend);
+    g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)));
+    g_assert (session_begin_struct.be == qof_book_get_backend (qof_session_get_book (fixture->session)));
     g_assert (session_begin_struct.backend_new_called == TRUE);
     g_assert (session_begin_struct.session_begin_called == TRUE);
-    g_assert (fixture->session->book_id);
-    g_assert_cmpstr (fixture->session->book_id, == , "postgres://localhost:8080");
+    g_assert (strlen (qof_session_get_url (fixture->session)));
+    g_assert_cmpstr (qof_session_get_url (fixture->session), == , "postgres://localhost:8080");
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR);
 
-    unregister_all_providers ();
+    qof_backend_unregister_all_providers ();
 }
 
 static struct
@@ -450,22 +443,21 @@ test_qof_session_save (Fixture *fixture, gconstpointer pData)
     QofBackendProvider *prov = NULL;
 
     g_test_message ("Test when backend not set");
-    g_assert (fixture->session->backend == NULL);
+    g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == NULL);
     book = qof_session_get_book (fixture->session);
     g_assert (book);
-    qof_session_push_error (fixture->session, ERR_BACKEND_DATA_CORRUPT, "push any error");
-    g_assert_cmpint (fixture->session->lock, == , 1);
+    g_assert_cmpint (qof_session_get_error (fixture->session), !=, ERR_BACKEND_NO_HANDLER);
+    g_assert (!qof_session_save_in_progress (fixture->session));
     qof_session_save (fixture->session, NULL);
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
-    g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "failed to load backend");
-    g_assert_cmpint (fixture->session->lock, == , 1);
+    g_assert (!qof_session_save_in_progress (fixture->session));
 
     g_test_message ("Test when backend set; imitate error");
     be = g_new0 (QofBackend, 1);
     g_assert (be);
     be->sync = mock_sync;
-    fixture->session->backend = be;
-    g_assert_cmpint (fixture->session->lock, == , 1);
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
+    g_assert (!qof_session_save_in_progress (fixture->session));
     session_save_struct.sync_called = FALSE;
     session_save_struct.be = be;
     session_save_struct.book = book;
@@ -475,18 +467,18 @@ test_qof_session_save (Fixture *fixture, gconstpointer pData)
     g_assert (qof_book_get_backend (book) == be);
     g_assert (be->percentage == percentage_fn);
     g_assert (session_save_struct.sync_called);
-    g_assert_cmpint (fixture->session->lock, == , 1);
+    g_assert (!qof_session_save_in_progress (fixture->session));
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_DATA_CORRUPT);
     g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "");
 
     g_test_message ("Test when backend set; successful save");
-    g_assert_cmpint (fixture->session->lock, == , 1);
+    g_assert (!qof_session_save_in_progress (fixture->session));
     session_save_struct.sync_called = FALSE;
     qof_session_save (fixture->session, percentage_fn);
     g_assert (qof_book_get_backend (book) == be);
     g_assert (be->percentage == percentage_fn);
     g_assert (session_save_struct.sync_called);
-    g_assert_cmpint (fixture->session->lock, == , 1);
+    g_assert (!qof_session_save_in_progress (fixture->session));
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR);
 
     /* change backend testing
@@ -494,7 +486,7 @@ test_qof_session_save (Fixture *fixture, gconstpointer pData)
      * for example: qof_session_load_backend
      */
 
-    unregister_all_providers ();
+    qof_backend_unregister_all_providers ();
     g_free (prov);
 }
 
@@ -520,19 +512,19 @@ test_qof_session_destroy_backend (Fixture *fixture, gconstpointer pData)
     g_test_message ("Test with destroy backend callback not set");
     be = g_new0 (QofBackend, 1);
     g_assert (be);
-    fixture->session->backend = be;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
     p_qof_session_destroy_backend (fixture->session);
-    g_assert (!fixture->session->backend);
+    g_assert (!qof_book_get_backend (qof_session_get_book (fixture->session)));
 
     g_test_message ("Test with destroy backend callback set");
     be = g_new0 (QofBackend, 1);
     g_assert (be);
     be->destroy_backend = mock_destroy_backend;
-    fixture->session->backend = be;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
     destroy_backend_struct.called = FALSE;
     destroy_backend_struct.be = be;
     p_qof_session_destroy_backend (fixture->session);
-    g_assert (!fixture->session->backend);
+    g_assert (!qof_book_get_backend (qof_session_get_book (fixture->session)));
     g_assert (destroy_backend_struct.called);
 }
 
@@ -559,15 +551,16 @@ test_qof_session_end (Fixture *fixture, gconstpointer pData)
     be = g_new0 (QofBackend, 1);
     g_assert (be);
     be->session_end = mock_session_end;
-    fixture->session->backend = be;
-    qof_session_push_error (fixture->session, ERR_BACKEND_DATA_CORRUPT, "push any error");
-    fixture->session->book_id = g_strdup ("my book");
+    be->last_err = ERR_BACKEND_DATA_CORRUPT;
+    be->error_msg = g_strdup("push any error");
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
+    p_qof_session_set_book_id (fixture->session, "my book");
     session_end_struct.called = FALSE;
     session_end_struct.be = be;
     qof_session_end (fixture->session);
     g_assert (session_end_struct.called);
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR);
-    g_assert (!fixture->session->book_id);
+    g_assert (!strlen (qof_session_get_url (fixture->session)));
 }
 
 static struct
@@ -611,7 +604,7 @@ test_qof_session_export (Fixture *fixture, gconstpointer pData)
     g_test_message ("Test with backend set");
     be = g_new0 (QofBackend, 1);
     g_assert (be);
-    fixture->session->backend = be;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
     qof_book_set_backend (tmp_book, be);
     g_assert (!be->percentage);
     g_assert (qof_session_export (fixture->session, real_session, percentage_fn));
@@ -654,20 +647,20 @@ test_qof_session_swap_data (Fixture *fixture, gconstpointer pData)
     g_assert (be1);
     be2 = g_new0 (QofBackend, 1);
     g_assert (be2);
-    fixture->session->backend = be1;
-    session2->backend = be2;
-    book1 = fixture->session->book;
-    book2 = session2->book;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be1);
+    qof_book_set_backend (qof_session_get_book (session2), be2);
+    book1 = qof_session_get_book (fixture->session);
+    book2 = qof_session_get_book (session2);
     g_assert (book1);
     g_assert (book2);
-    qof_book_set_backend (book1, fixture->session->backend);
-    qof_book_set_backend (book2, session2->backend);
+    qof_book_set_backend (book1, qof_book_get_backend (qof_session_get_book (fixture->session)));
+    qof_book_set_backend (book2, qof_book_get_backend (qof_session_get_book (session2)));
 
 
     g_test_message ("Test book lists are swapped and backend for each book is swapped");
     qof_session_swap_data (fixture->session, session2);
-    g_assert (fixture->session->book == book2);
-    g_assert (session2->book == book1);
+    g_assert (qof_session_get_book (fixture->session) == book2);
+    g_assert (qof_session_get_book (session2) == book1);
 
     qof_session_destroy (session2);
 }
@@ -694,12 +687,12 @@ test_qof_session_events (Fixture *fixture, gconstpointer pData)
 
     g_test_message ("Test pending events null checks");
     g_assert (!qof_session_events_pending (NULL));
-    g_assert (!fixture->session->backend);
+    g_assert (!qof_book_get_backend (qof_session_get_book (fixture->session)));
     g_assert (!qof_session_events_pending (fixture->session));
     be = g_new0 (QofBackend, 1);
     g_assert (be);
     be->events_pending = NULL;
-    fixture->session->backend = be;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
     g_assert (!qof_session_events_pending (fixture->session));
 
     g_test_message ("Test pending events callback");
@@ -711,10 +704,10 @@ test_qof_session_events (Fixture *fixture, gconstpointer pData)
 
     g_test_message ("Test process events null checks");
     g_assert (!qof_session_process_events (NULL));
-    fixture->session->backend = NULL;
+    qof_book_set_backend (qof_session_get_book (fixture->session), NULL);
     g_assert (!qof_session_process_events (fixture->session));
     be->process_events = NULL;
-    fixture->session->backend = be;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
     g_assert (!qof_session_process_events (fixture->session));
 
     g_test_message ("Test process events callback");
@@ -752,7 +745,7 @@ test_qof_session_data_loaded (Fixture *fixture, gconstpointer pData)
     be = g_new0 (QofBackend, 1);
     g_assert (be);
     be->load = mock_all_data_load;
-    fixture->session->backend = be;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
 
     g_test_message ("Test load callback and artificial error");
     data_load_struct.be = be;
@@ -773,7 +766,7 @@ test_qof_session_get_book (Fixture *fixture, gconstpointer pData)
     g_assert (!qof_session_get_book (NULL));
 
     g_test_message ("Test open book is returned");
-    g_assert (fixture->session->book);
+    g_assert (qof_session_get_book (fixture->session));
     book = qof_session_get_book (fixture->session);
     g_assert (book);
     g_assert_cmpuint (book->book_open, == , 'y');
@@ -792,20 +785,11 @@ test_qof_session_get_error (Fixture *fixture, gconstpointer pData)
     g_test_message ("Test if session is null");
     g_assert_cmpint (qof_session_get_error (NULL), == , ERR_BACKEND_NO_BACKEND);
 
-    g_test_message ("Test when there is a local error");
-    fixture->session->last_err = ERR_BACKEND_DATA_CORRUPT; /* just any error */
-    g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_DATA_CORRUPT);
-
-    g_test_message ("Test if session backend is null");
-    g_assert (!fixture->session->backend);
-    fixture->session->last_err = ERR_BACKEND_NO_ERR;
-    g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR);
-
     g_test_message ("Test for backend error");
     be = g_new0 (QofBackend, 1);
     g_assert (be);
     qof_backend_set_error (be, ERR_BACKEND_CANT_CONNECT);
-    fixture->session->backend = be;
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_CANT_CONNECT);
 }
 
@@ -818,13 +802,14 @@ test_qof_session_clear_error (Fixture *fixture, gconstpointer pData)
     g_assert (be);
 
     g_test_message ("Test session and backend errors are cleared");
-    qof_session_push_error (fixture->session, ERR_BACKEND_NO_SUCH_DB, "push any error");
-    fixture->session->backend = be;
+    be->last_err = ERR_BACKEND_NO_SUCH_DB;
+    be->error_msg = g_strdup ("push any error");
+    qof_book_set_backend (qof_session_get_book (fixture->session), be);
     qof_backend_set_error (be, ERR_BACKEND_CANT_CONNECT);
     p_qof_session_clear_error (fixture->session);
     g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR);
     g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "");
-    g_assert (!fixture->session->error_message);
+    g_assert (!strlen (qof_session_get_error_message (fixture->session)));
     g_assert_cmpint (qof_backend_get_error (be), == , ERR_BACKEND_NO_ERR);
 }
 

commit 557a5e2f2d07b0daafa85966d215b72f1ced7b0d
Author: lmat <dartme18 at gmail.com>
Date:   Sun Jun 5 12:27:32 2016 -0400

    Check the appropriate locations for gmock and gtest sources
    
    Although we test libgtest_main, we don't test for libgmock_main. This
    shouldn't be necessary since gmock was absorbed by gtest in upstream,
    so I'm not planning on working hard to correct this problem robustly.
    We'll just check for the source files in the other location where they
    might be.

diff --git a/configure.ac b/configure.ac
index b3bbe9d..2a40af8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -868,7 +868,9 @@ if test x$enable_google_test != xno; then
    AC_CHECK_LIB([gtest_main], [main],
       [AC_CHECK_FILES([/usr/src/gmock/gmock-all.cc
 		       /usr/include/gtest/gtest.h
-		       /usr/include/gmock/gmock.h],
+		       /usr/include/gmock/gmock.h
+               /usr/src/gmock/src/gmock-all.cc
+               /usr/src/gtest/src/gtest-all.cc],
       	[ac_cv_gtest_system_install=yes] [ac_cv_have_gtest_libs=yes],
 	[ac_cv_gtest_system_install=no])],
       [AC_CHECK_FILES([/usr/src/gtest/src/gtest-all.cc

commit 3390886051b4ae99a35288571c4fbcea8b31ffd9
Author: lmat <dartme18 at gmail.com>
Date:   Sun Jun 5 12:26:13 2016 -0400

    Corrected "misleading" indentation
    
    gcc 6.1.1 throws an error because with 8-space tabs, it looks like a
    line is in an if statement when it isn't.

diff --git a/src/gnome/gnc-split-reg.c b/src/gnome/gnc-split-reg.c
index 1dd5367..3c002ab 100644
--- a/src/gnome/gnc-split-reg.c
+++ b/src/gnome/gnc-split-reg.c
@@ -930,7 +930,7 @@ gsr_default_associate_handler_file( GNCSplitReg *gsr, gpointer data )
     if (is_trans_readonly_and_warn(trans))
         return;
 
-	dialog = gtk_file_chooser_dialog_new ("Associate File with Transaction",
+    dialog = gtk_file_chooser_dialog_new ("Associate File with Transaction",
                                      GTK_WINDOW(gsr->window),
                                      GTK_FILE_CHOOSER_ACTION_OPEN,
                                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,



Summary of changes:
 configure.ac                                       |    4 +-
 src/app-utils/gnc-state.c                          |    6 +-
 src/app-utils/test/test-option-util.cpp            |    1 +
 src/app-utils/test/test-print-parse-amount.cpp     |    1 +
 src/app-utils/test/test-scm-query-string.cpp       |    1 +
 src/app-utils/test/test-sx.cpp                     |    1 +
 src/backend/dbi/gnc-backend-dbi.cpp                |    1 +
 src/backend/dbi/test/test-backend-dbi-basic.cpp    |    2 +-
 src/backend/dbi/test/test-backend-dbi.cpp          |    1 +
 src/backend/dbi/test/test-dbi-business-stuff.cpp   |    1 +
 src/backend/dbi/test/test-dbi-stuff.cpp            |    2 +-
 src/backend/sql/escape.cpp                         |    1 +
 src/backend/sql/gnc-account-sql.cpp                |    1 +
 src/backend/sql/gnc-address-sql.cpp                |    1 +
 src/backend/sql/gnc-backend-sql.cpp                |    1 +
 src/backend/sql/gnc-bill-term-sql.cpp              |    1 +
 src/backend/sql/gnc-book-sql.cpp                   |    1 +
 src/backend/sql/gnc-budget-sql.cpp                 |    1 +
 src/backend/sql/gnc-commodity-sql.cpp              |    1 +
 src/backend/sql/gnc-customer-sql.cpp               |    1 +
 src/backend/sql/gnc-employee-sql.cpp               |    1 +
 src/backend/sql/gnc-entry-sql.cpp                  |    1 +
 src/backend/sql/gnc-invoice-sql.cpp                |    1 +
 src/backend/sql/gnc-job-sql.cpp                    |    1 +
 src/backend/sql/gnc-lots-sql.cpp                   |    1 +
 src/backend/sql/gnc-order-sql.cpp                  |    1 +
 src/backend/sql/gnc-owner-sql.cpp                  |    1 +
 src/backend/sql/gnc-price-sql.cpp                  |    1 +
 src/backend/sql/gnc-recurrence-sql.cpp             |    1 +
 src/backend/sql/gnc-schedxaction-sql.cpp           |    1 +
 src/backend/sql/gnc-slots-sql.cpp                  |    1 +
 src/backend/sql/gnc-tax-table-sql.cpp              |    1 +
 src/backend/sql/gnc-transaction-sql.cpp            |    1 +
 src/backend/sql/gnc-vendor-sql.cpp                 |    1 +
 src/backend/sql/test/test-column-types.cpp         |    1 +
 src/backend/sql/test/test-sqlbe.cpp                |    1 +
 src/backend/sql/test/utest-gnc-backend-sql.cpp     |    1 +
 src/backend/xml/gnc-account-xml-v2.cpp             |    1 +
 src/backend/xml/gnc-address-xml-v2.cpp             |    1 +
 src/backend/xml/gnc-backend-xml.cpp                |    1 +
 src/backend/xml/gnc-bill-term-xml-v2.cpp           |    1 +
 src/backend/xml/gnc-book-xml-v2.cpp                |    1 +
 src/backend/xml/gnc-budget-xml-v2.cpp              |    1 +
 src/backend/xml/gnc-commodity-xml-v2.cpp           |    1 +
 src/backend/xml/gnc-customer-xml-v2.cpp            |    1 +
 src/backend/xml/gnc-employee-xml-v2.cpp            |    1 +
 src/backend/xml/gnc-entry-xml-v2.cpp               |    1 +
 src/backend/xml/gnc-freqspec-xml-v2.cpp            |    1 +
 src/backend/xml/gnc-invoice-xml-v2.cpp             |    1 +
 src/backend/xml/gnc-job-xml-v2.cpp                 |    1 +
 src/backend/xml/gnc-lot-xml-v2.cpp                 |    1 +
 src/backend/xml/gnc-order-xml-v2.cpp               |    1 +
 src/backend/xml/gnc-owner-xml-v2.cpp               |    1 +
 src/backend/xml/gnc-pricedb-xml-v2.cpp             |    1 +
 src/backend/xml/gnc-recurrence-xml-v2.cpp          |    1 +
 src/backend/xml/gnc-schedxaction-xml-v2.cpp        |    1 +
 src/backend/xml/gnc-tax-table-xml-v2.cpp           |    1 +
 src/backend/xml/gnc-transaction-xml-v2.cpp         |    1 +
 src/backend/xml/gnc-vendor-xml-v2.cpp              |    1 +
 src/backend/xml/io-example-account.cpp             |    1 +
 src/backend/xml/io-gncxml-gen.cpp                  |    1 +
 src/backend/xml/io-gncxml-v1.cpp                   |    1 +
 src/backend/xml/io-gncxml-v2.cpp                   |    1 +
 src/backend/xml/io-utils.cpp                       |    1 +
 src/backend/xml/sixtp-dom-generators.cpp           |    1 +
 src/backend/xml/sixtp-dom-parsers.cpp              |    1 +
 src/backend/xml/sixtp-stack.cpp                    |    1 +
 src/backend/xml/sixtp-to-dom-parser.cpp            |    1 +
 src/backend/xml/sixtp-utils.cpp                    |    1 +
 src/backend/xml/sixtp.cpp                          |    1 +
 src/backend/xml/test/test-date-converting.cpp      |    2 +-
 src/backend/xml/test/test-dom-converters1.cpp      |    1 +
 src/backend/xml/test/test-file-stuff.cpp           |    1 +
 src/backend/xml/test/test-kvp-frames.cpp           |    1 +
 src/backend/xml/test/test-load-backend.cpp         |    1 +
 src/backend/xml/test/test-load-example-account.cpp |    1 +
 src/backend/xml/test/test-load-xml2.cpp            |    1 +
 src/backend/xml/test/test-save-in-lang.cpp         |    1 +
 src/backend/xml/test/test-string-converters.cpp    |    1 +
 src/backend/xml/test/test-xml-account.cpp          |    1 +
 src/backend/xml/test/test-xml-commodity.cpp        |    1 +
 src/backend/xml/test/test-xml-pricedb.cpp          |    1 +
 src/backend/xml/test/test-xml-transaction.cpp      |    1 +
 src/backend/xml/test/test-xml2-is-file.cpp         |    1 +
 src/engine/kvp-scm.cpp                             |    1 +
 src/engine/test-core/test-engine-stuff.cpp         |    1 +
 src/engine/test/gtest-import-map.cpp               |    1 +
 src/engine/test/test-account-object.cpp            |    1 +
 src/engine/test/test-commodities.cpp               |    1 +
 src/engine/test/test-date.cpp                      |    2 +-
 src/engine/test/test-group-vs-book.cpp             |    1 +
 src/engine/test/test-guid.cpp                      |    1 +
 src/engine/test/test-lots.cpp                      |    1 +
 src/engine/test/test-numeric.cpp                   |    1 +
 src/engine/test/test-query.cpp                     |    1 +
 src/engine/test/test-scm-query.cpp                 |    1 +
 src/engine/test/test-split-vs-account.cpp          |    1 +
 src/engine/test/test-transaction-reversal.cpp      |    1 +
 src/engine/test/test-transaction-voiding.cpp       |    1 +
 src/engine/test/utest-Account.cpp                  |    1 +
 src/engine/test/utest-Split.cpp                    |    1 +
 src/engine/test/utest-Transaction.cpp              |    1 +
 src/gnome-utils/gnc-file.c                         |   10 +-
 src/gnome-utils/gnc-main-window.c                  |    4 +-
 src/gnome/gnc-split-reg.c                          |    2 +-
 src/libqof/qof/Makefile.am                         |    4 +-
 src/libqof/qof/gnc-aqbanking-templates.cpp         |    1 +
 src/libqof/qof/gnc-backend-prov.hpp                |    2 +
 src/libqof/qof/gnc-date.cpp                        |    1 +
 src/libqof/qof/gnc-timezone.cpp                    |    1 +
 src/libqof/qof/guid.cpp                            |  160 +--
 src/libqof/qof/guid.h                              |    8 +-
 src/libqof/qof/{qofevent-p.h => guid.hpp}          |   37 +-
 src/libqof/qof/kvp-value.cpp                       |    1 +
 src/libqof/qof/kvp_frame.cpp                       |    1 +
 src/libqof/qof/qof-string-cache.cpp                |    7 +-
 src/libqof/qof/qofbackend.cpp                      |    6 +-
 src/libqof/qof/qofbook.cpp                         |    5 +-
 src/libqof/qof/qofbook.h                           |    1 +
 src/libqof/qof/qofchoice.cpp                       |    5 +-
 src/libqof/qof/qofclass.cpp                        |    8 +-
 src/libqof/qof/qofevent.cpp                        |    7 +-
 src/libqof/qof/qofid.cpp                           |    8 +-
 src/libqof/qof/qofinstance.cpp                     |    1 +
 src/libqof/qof/qoflog.cpp                          |    7 +-
 src/libqof/qof/qofobject.cpp                       |    9 +-
 src/libqof/qof/qofquery.cpp                        |    7 +-
 src/libqof/qof/qofquerycore.cpp                    |    1 +
 src/libqof/qof/qofsession.cpp                      |  928 +++++++++---------
 src/libqof/qof/qofsession.h                        |    9 +-
 src/libqof/qof/{qofsession-p.h => qofsession.hpp}  |   81 +-
 src/libqof/qof/qofutil.cpp                         |    1 +
 src/libqof/qof/test/Makefile.am                    |   47 +-
 .../{test-gnc-guid.cpp => test-gnc-guid-old.cpp}   |    3 +-
 src/libqof/qof/test/test-gnc-guid.cpp              |  211 ++--
 src/libqof/qof/test/test-kvp-frame.cpp             |    1 +
 src/libqof/qof/test/test-kvp-value.cpp             |    1 +
 src/libqof/qof/test/test-qofinstance.cpp           |    2 +
 ...test-qofsession.cpp => test-qofsession-old.cpp} |  174 ++--
 src/libqof/qof/test/test-qofsession.cpp            | 1014 ++++----------------
 140 files changed, 1130 insertions(+), 1760 deletions(-)
 copy src/libqof/qof/{qofevent-p.h => guid.hpp} (65%)
 rename src/libqof/qof/{qofsession-p.h => qofsession.hpp} (52%)
 copy src/libqof/qof/test/{test-gnc-guid.cpp => test-gnc-guid-old.cpp} (98%)
 copy src/libqof/qof/test/{test-qofsession.cpp => test-qofsession-old.cpp} (83%)



More information about the gnucash-changes mailing list