[Avida-SVN] r2225 - / extras/source/targets/TestAvida extras/source/testsuites extras/source/tools

kaben at myxo.css.msu.edu kaben at myxo.css.msu.edu
Wed Dec 19 12:19:55 PST 2007


Author: kaben
Date: 2007-12-19 15:19:54 -0500 (Wed, 19 Dec 2007)
New Revision: 2225

Added:
   extras/
   extras/source/testsuites/nHelloWorld.cpp
Removed:
   extras/
Modified:
   /
   extras/source/targets/TestAvida/TestAvida.cpp
   extras/source/testsuites/nAGenotype.cpp
   extras/source/testsuites/nAnalyze.cpp
   extras/source/testsuites/nAnalyzeGenotype.cpp
   extras/source/testsuites/nChangeList.cpp
   extras/source/testsuites/nClassName.cpp
   extras/source/testsuites/nConsoleCatcher.cpp
   extras/source/testsuites/nDataEntry.cpp
   extras/source/testsuites/nDataFile.cpp
   extras/source/testsuites/nFile.cpp
   extras/source/testsuites/nFixedCoords.cpp
   extras/source/testsuites/nInitFile.cpp
   extras/source/testsuites/nRandom.cpp
   extras/source/testsuites/nString.cpp
   extras/source/testsuites/nStringList.cpp
   extras/source/testsuites/nTemplate.cpp
   extras/source/testsuites/nTestDriver.cpp
   extras/source/testsuites/nTestLib.cpp
   extras/source/testsuites/nTestSettings.cpp
   extras/source/tools/cTestDriver.cpp
   extras/source/tools/cTestDriver.h
   extras/source/tools/cTestLib.cpp
   extras/source/tools/cTestSettings.cpp
   extras/source/tools/lightweight_test.h
Log:
 r2184 at vallista:  kaben | 2007-11-04 21:18:21 -0800
 testsuites: repaired and refactored.
 - Repaired bitrot. Testsuites are usable again.
 - Refactored testsuites and testing tools.
   - Exectuable takes options in a more standard format. Type 'testsuites -h' for help.
   - Deobfuscated code.
 



Property changes on: 
___________________________________________________________________
Name: svk:merge
   - 079b078a-dbed-46b9-b3da-37668d4295ca:/avida/xcode-test:1653
   + 079b078a-dbed-46b9-b3da-37668d4295ca:/avida/xcode-test:1653
c457ea80-0a68-11dc-9323-a45eea2efad5:/private:2184

Copied: extras (from rev 1361, extras)

Modified: extras/source/targets/TestAvida/TestAvida.cpp
===================================================================
--- extras/source/targets/TestAvida/TestAvida.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/targets/TestAvida/TestAvida.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -61,7 +61,7 @@
   signal(SIGABRT, SIG_IGN);
   ERROR("received signal SIGABRT");
   td.reportErrors();
-  exit(td.testErrors());
+  exit(td.testingErrors());
 }
 
 int main(int argc, char * argv[]){

Modified: extras/source/testsuites/nAGenotype.cpp
===================================================================
--- extras/source/testsuites/nAGenotype.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nAGenotype.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -8,46 +8,17 @@
 using namespace std;
 
 /* Tests. */
-namespace nAnalyzeGenotype {
-/* Brainstorms. {{{1 */
-  /* cAnalyzeGenotype_Brainstorm_HelloWorld {{{2 */
-  namespace Brainstorm_HelloWorld {
-    void test(const cStringList &attrs){
-      if(!attrs.HasString("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
+/* Brainstorms. */
+namespace cAnalyzeGenotype_Brainstorm_HelloWorld {
+  void test(cTestSettings &settings){
+    if(!settings.HasSetting("HelloWorld")){
+      SKIP("Skipping HelloWorld test");
+      return;
     }
-    cAddTestSuite t("cAnalyzeGenotype_Brainstorm_HelloWorld", test);
+    cout << "XXX This is a test demo. It needs filling-in. @kgn" << endl;
+    TEST(true);
   }
-
-/* Unit tests. {{{1 */
-  /* cAnalyzeGenotype_UnitTest_HelloWorld {{{2 */
-  namespace UnitTest_HelloWorld {
-    void test(const cStringList &attrs){
-      if(!attrs.HasString("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cAnalyzeGenotype_UnitTest_HelloWorld", test);
-  }
-
-  // }}}1
-  /*
-  This function does nothing;
-  but if the compiler sees that this function is called, then the
-  compiler will also connect the above tests to the testing library.
-  */
-  void PhysicalLink(){}
+  cAddTestSuite t("cAnalyzeGenotype_Brainstorm_HelloWorld", test);
 }
 
 

Modified: extras/source/testsuites/nAnalyze.cpp
===================================================================
--- extras/source/testsuites/nAnalyze.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nAnalyze.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -1,6 +1,7 @@
 
 #include "cAnalyze.h"
 
+#include "avida.h"
 #include "cAvidaConfig.h"
 #include "cAnalyzeCommandDefBase.h"
 #include "cAnalyzeFlowCommand.h"
@@ -19,8 +20,11 @@
 #include "cSchedule.h"
 #include "cStringUtil.h"
 #include "cTestCPU.h"
+#include "cTestingWorldDriver.h"
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include "cWorld.h"
 #include "tDictionary.h"
 
@@ -56,6 +60,7 @@
 /* Tests. */
 namespace nAnalyze {
 /* Test-helpers. {{{1 */
+#if ENABLE_SERIALIZATION
   /* save_stuff {{{2 */
   template <class T>
   void save_stuff(const T &s, const char * filename){
@@ -71,29 +76,11 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cAnalyze_Archive", s);
   }
+#endif // ENABLE_SERIALIZATION
 
-/* Brainstorms. {{{1 */
-  /* cAnalyze_Brainstorm_HelloWorld {{{2 */
-  namespace Brainstorm_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cAnalyze_Brainstorm_HelloWorld", test);
-  }
-
   /* cAnalyze_Brainstorm_OneOffIstreamTest {{{2 */
-  namespace Brainstorm_OneOffIstreamTest {
-    void test(){
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
+  namespace cAnalyze_Brainstorm_OneOffIstreamTest {
+    void testsuite(){
       cString blah;
       for(int i=0; i<10; i++){
         blah = "blah";
@@ -101,107 +88,97 @@
         cout << blah << endl;
       }
     }
-    cAddTestSuite t("cAnalyze_Brainstorm_OneOffIstreamTest", test);
+    cAddTestSuite t("cAnalyze_Brainstorm_OneOffIstreamTest", testsuite);
   }
 
-  /* cAnalyze_Brainstorm_RunningAnalyze {{{2 */
-  namespace Brainstorm_RunningAnalyze {
+  // }}}1
+  /*
+  This function does nothing;
+  but if the compiler sees that this function is called, then the
+  compiler will also connect the above tests to the testing library.
+  */
+  void PhysicalLink(){}
+}
 
+/* cAnalyze_Brainstorm_RunningAnalyze {{{2 */
+namespace cAnalyze_Brainstorm_RunningAnalyze {
+
 #   define RIT(mt, class_name) \
-      (mt).RegTracker( \
-        (#class_name), \
-        (tMemTrack< class_name >::Instances) \
-      )
+    (mt).RegTracker( \
+      (#class_name), \
+      (tMemTrack< class_name >::Instances) \
+    )
 
-    typedef int (*tTracker)(int);
-    class cMemTracker {
+  typedef int (*tTracker)(int);
+  class cMemTracker {
+  protected:
+    class cCheckpoint {
     protected:
-      class cCheckpoint {
-      protected:
-        tTracker m_tracker;
-        int m_marks;
-      protected:
-        tTracker Tracker(){ return m_tracker; }
-      public:
-        int Instances(){
-          if(m_tracker) return (*m_tracker)(0);
-          return -1;
-        }
-        void SetTracker(tTracker tracker){ m_tracker = tracker; }
-        void Mark(){
-          m_marks = Instances();
-        }
-        void Expect(int count){ m_marks = count; }
-        int ShowMark(){ return m_marks; }
-        bool Verify(){
-          return (Tracker()) && (ShowMark() == Instances());
-        }
-
-        cCheckpoint& operator=(cCheckpoint & in)
-        {
-          SetTracker(in.Tracker());
-          Expect(in.ShowMark());
-          return *this;
-        }
-        cCheckpoint()
-        : m_tracker(0)
-        , m_marks(-1)
-        {}
-        cCheckpoint(const cCheckpoint &c)
-        : m_tracker(c.m_tracker)
-        , m_marks(c.m_marks)
-        {}
-        cCheckpoint(tTracker tracker)
-        : m_tracker(tracker)
-        , m_marks(0)
-        {
-          /*
-          bugfix : tracker can be 0, in which case we need to set
-          m_marks to -1. @kgn
-          */
-          Expect(ShowMark());
-        }
-      };
+      tTracker m_tracker;
+      int m_marks;
     protected:
-      tDictionary<cCheckpoint> m_tracker_dict;
+      tTracker Tracker(){ return m_tracker; }
     public:
-      cMemTracker& operator=(const cMemTracker &in){
-        /* Empty current dictionary */
-        {
-          tList<cString> name_list;
-          tList<cCheckpoint> value_list;
-          m_tracker_dict.AsLists(name_list, value_list);
-          tListIterator<cString> list_it(name_list);
-          while (list_it.Next() != 0) {
-            cString name(*list_it.Get());
-            m_tracker_dict.Remove(name);
-          }
-        }
-        /* Copy input dictionary */
-        {
-          tList<cString> name_list;
-          tList<cCheckpoint> value_list;
-          in.m_tracker_dict.AsLists(name_list, value_list);
-          tListIterator<cString> list_it(name_list);
-          while (list_it.Next() != 0) {
-            cString name(*list_it.Get());
-            cCheckpoint c;
-            if(in.m_tracker_dict.Find(name, c)){
-              m_tracker_dict.SetValue(name, c);
-            } else {
-              ERROR(name + " missing from input cMemTracker instance");
-            }
-          }
-        }
+      int Instances(){
+        if(m_tracker) return (*m_tracker)(0);
+        return -1;
+      }
+      void SetTracker(tTracker tracker){ m_tracker = tracker; }
+      void Mark(){
+        m_marks = Instances();
+      }
+      void Expect(int count){ m_marks = count; }
+      int ShowMark(){ return m_marks; }
+      bool Verify(){
+        return (Tracker()) && (ShowMark() == Instances());
+      }
+
+      cCheckpoint& operator=(cCheckpoint & in)
+      {
+        SetTracker(in.Tracker());
+        Expect(in.ShowMark());
         return *this;
       }
-      cMemTracker(){}
-      cMemTracker(const cMemTracker &in){
+      cCheckpoint()
+      : m_tracker(0)
+      , m_marks(-1)
+      {}
+      cCheckpoint(const cCheckpoint &c)
+      : m_tracker(c.m_tracker)
+      , m_marks(c.m_marks)
+      {}
+      cCheckpoint(tTracker tracker)
+      : m_tracker(tracker)
+      , m_marks(0)
+      {
+        /*
+        bugfix : tracker can be 0, in which case we need to set
+        m_marks to -1. @kgn
+        */
+        Expect(ShowMark());
+      }
+    };
+  protected:
+    tDictionary<cCheckpoint> m_tracker_dict;
+  public:
+    cMemTracker& operator=(const cMemTracker &in){
+      /* Empty current dictionary */
+      {
         tList<cString> name_list;
         tList<cCheckpoint> value_list;
+        m_tracker_dict.AsLists(name_list, value_list);
+        tListIterator<cString> list_it(name_list);
+        while (list_it.Next() != 0) {
+          cString name(*list_it.Get());
+          m_tracker_dict.Remove(name);
+        }
+      }
+      /* Copy input dictionary */
+      {
+        tList<cString> name_list;
+        tList<cCheckpoint> value_list;
         in.m_tracker_dict.AsLists(name_list, value_list);
         tListIterator<cString> list_it(name_list);
-
         while (list_it.Next() != 0) {
           cString name(*list_it.Get());
           cCheckpoint c;
@@ -212,521 +189,3181 @@
           }
         }
       }
-      void RegTracker(const cString &name, tTracker tracker){
-        m_tracker_dict.SetValue(name, tracker);
-      }
-      int Instances(const cString &n){
-        cString name(n);
+      return *this;
+    }
+    cMemTracker(){}
+    cMemTracker(const cMemTracker &in){
+      tList<cString> name_list;
+      tList<cCheckpoint> value_list;
+      in.m_tracker_dict.AsLists(name_list, value_list);
+      tListIterator<cString> list_it(name_list);
+
+      while (list_it.Next() != 0) {
+        cString name(*list_it.Get());
         cCheckpoint c;
-        if(m_tracker_dict.Find(name, c)){
-          return c.Instances();
+        if(in.m_tracker_dict.Find(name, c)){
+          m_tracker_dict.SetValue(name, c);
         } else {
-          return -1;
+          ERROR(name + " missing from input cMemTracker instance");
         }
       }
-      int ShowMark(const cString &n){
-        cString name(n);
-        cCheckpoint c;
-        if(m_tracker_dict.Find(name, c)){
-          return c.ShowMark();
-        } else {
-          return -1;
+    }
+    void RegTracker(const cString &name, tTracker tracker){
+      m_tracker_dict.SetValue(name, tracker);
+    }
+    int Instances(const cString &n){
+      cString name(n);
+      cCheckpoint c;
+      if(m_tracker_dict.Find(name, c)){
+        return c.Instances();
+      } else {
+        return -1;
+      }
+    }
+    int ShowMark(const cString &n){
+      cString name(n);
+      cCheckpoint c;
+      if(m_tracker_dict.Find(name, c)){
+        return c.ShowMark();
+      } else {
+        return -1;
+      }
+    }
+    bool Mark(const cString &n){
+      cString name(n);
+      cCheckpoint c;
+      if(m_tracker_dict.Find(name, c)){
+        c.Mark();
+        m_tracker_dict.SetValue(name, c);
+        return true;
+      } else {
+        return false;
+      }
+    }
+    bool Expect(const cString &n, int i){
+      cString name(n);
+      cCheckpoint c;
+      if(m_tracker_dict.Find(name, c)){
+        c.Expect(i);
+        m_tracker_dict.SetValue(name, c);
+        return true;
+      } else {
+        return false;
+      }
+    }
+    bool IncMark(const cString &n, int i){
+      cString name(n);
+      cCheckpoint c;
+      if(m_tracker_dict.Find(name, c)){
+        c.Expect(c.ShowMark() + i);
+        m_tracker_dict.SetValue(name, c);
+        return true;
+      } else {
+        return false;
+      }
+    }
+    bool Verify(const cString &n){
+      cString name(n);
+      cCheckpoint c;
+      if(m_tracker_dict.Find(name, c)){
+        return c.Verify();
+      } else {
+        ERROR(name + " is not being tracked");
+        return false;
+      }
+    }
+
+    void ShowMarks(){
+      tList<cString> name_list;
+      tList<cCheckpoint> value_list;
+      m_tracker_dict.AsLists(name_list, value_list);
+      tListIterator<cString> list_it(name_list);
+
+      while (list_it.Next() != 0) {
+        cString name(*list_it.Get());
+        cout << ShowMark(name) << " marked instances of " << name << endl;
+      }
+    }
+    void MarkAll(){
+      tList<cString> name_list;
+      tList<cCheckpoint> value_list;
+      m_tracker_dict.AsLists(name_list, value_list);
+      tListIterator<cString> list_it(name_list);
+
+      while (list_it.Next() != 0) { Mark(*list_it.Get()); }
+    }
+    void Report(){
+      tList<cString> name_list;
+      tList<cCheckpoint> value_list;
+      m_tracker_dict.AsLists(name_list, value_list);
+      tListIterator<cString> list_it(name_list);
+
+      while (list_it.Next() != 0) {
+        cString name(*list_it.Get());
+        cout << Instances(name) << " instances of " << name << endl;
+      }
+    }
+    bool Verify(){
+      tList<cString> name_list;
+      tList<cCheckpoint> value_list;
+      m_tracker_dict.AsLists(name_list, value_list);
+      tListIterator<cString> list_it(name_list);
+
+      int failures = 0;
+      while (list_it.Next() != 0) {
+        cString name(*list_it.Get());
+        if(!Verify(name)){
+          ERROR(name + " has unexpected instance count");
+          cerr << ShowMark(name) << " marked instances of " << name << endl;
+          cerr << Instances(name) << " instances of " << name << endl;
+          failures++;
         }
       }
-      bool Mark(const cString &n){
-        cString name(n);
-        cCheckpoint c;
-        if(m_tracker_dict.Find(name, c)){
-          c.Mark();
-          m_tracker_dict.SetValue(name, c);
-          return true;
-        } else {
-          return false;
+      return 0 == failures;
+    }
+  };
+
+#if USE_tMemTrack
+  class cNul {
+    tMemTrack<cNul> mt;
+  };
+#endif
+
+  void testsuite(){
+    cout << "XXX This is a testsuite demo. It needs filling-in. @kgn" << endl;
+
+  /*
+  Tests of cMemTracker.
+  */
+#if USE_tMemTrack
+    /*
+    Verifies RIT Macro
+    Verifies cMemTracker::Instances()
+    */
+    {
+      cMemTracker tmt;
+
+      TEST(-1 == tmt.Instances("cNul"));
+
+      /*
+      Verifies RIT Macro
+      */
+      RIT(tmt, cNul);
+
+      /*
+      Verifies cMemTracker::Instances()
+      */
+      TEST(0 == tmt.Instances("cNul"));
+
+      cNul n;
+
+      TEST(1 == tmt.Instances("cNul"));
+    }
+    /*
+    Verifies cMemTracker::Mark()
+    Verifies cMemTracker::ShowMark()
+    */
+    {
+      cMemTracker tmt;
+
+      TEST(-1 == tmt.Instances("cNul"));
+      TEST(-1 == tmt.ShowMark("cNul"));
+
+      RIT(tmt, cNul);
+
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt.Instances("cNul"));
+
+      cNul n;
+
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+
+      tmt.Mark("cNul");
+
+      TEST(1 == tmt.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+    }
+    /*
+    Verifies cMemTracker::Expect()
+    */
+    {
+      cMemTracker tmt;
+
+      TEST(-1 == tmt.Instances("cNul"));
+      TEST(-1 == tmt.ShowMark("cNul"));
+
+      RIT(tmt, cNul);
+
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt.Instances("cNul"));
+
+      cNul n;
+
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+
+      tmt.Expect("cNul", 1);
+
+      TEST(1 == tmt.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+    }
+    /*
+    Verifies cMemTracker::IncMark()
+    */
+    {
+      cMemTracker tmt;
+
+      TEST(-1 == tmt.Instances("cNul"));
+      TEST(-1 == tmt.ShowMark("cNul"));
+
+      RIT(tmt, cNul);
+
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt.Instances("cNul"));
+
+      cNul n;
+
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+
+      tmt.IncMark("cNul", 1);
+
+      TEST(1 == tmt.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+
+      tmt.IncMark("cNul", 2);
+
+      TEST(3 == tmt.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+    }
+    /*
+    Verifies cMemTracker copy constructor
+    */
+    {
+      cMemTracker tmt;
+
+      TEST(-1 == tmt.Instances("cNul"));
+      TEST(-1 == tmt.ShowMark("cNul"));
+
+      RIT(tmt, cNul);
+
+      cMemTracker tmt2(tmt);
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt2.ShowMark("cNul"));
+      TEST(0 == tmt.Instances("cNul"));
+
+      cNul n;
+
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt2.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+
+      tmt.IncMark("cNul", 1);
+
+      TEST(1 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt2.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+
+      tmt.IncMark("cNul", 2);
+
+      TEST(3 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt2.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+    }
+    /*
+    Verifies cMemTracker assignment operator
+    */
+    {
+      cMemTracker tmt;
+
+      TEST(-1 == tmt.Instances("cNul"));
+      TEST(-1 == tmt.ShowMark("cNul"));
+
+      RIT(tmt, cNul);
+
+      cMemTracker tmt2 = tmt;
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt2.ShowMark("cNul"));
+      TEST(0 == tmt.Instances("cNul"));
+
+      cNul n;
+
+      TEST(0 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt2.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+
+      tmt.IncMark("cNul", 1);
+
+      TEST(1 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt2.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+
+      tmt.IncMark("cNul", 2);
+
+      TEST(3 == tmt.ShowMark("cNul"));
+      TEST(0 == tmt2.ShowMark("cNul"));
+      TEST(1 == tmt.Instances("cNul"));
+    }
+#endif
+
+#if USE_tMemTrack
+    cMemTracker mt;
+    RIT(mt, cActionLibrary);
+    RIT(mt, cAnalyze);
+    RIT(mt, cAvidaConfig);
+    RIT(mt, cAvidaContext);
+    RIT(mt, cClassificationManager);
+    RIT(mt, cDataFileManager);
+    RIT(mt, cDefaultAnalyzeDriver);
+    RIT(mt, cEnvironment);
+    RIT(mt, cEventList);
+    RIT(mt, cHardwareManager);
+    RIT(mt, cPopulation);
+    RIT(mt, cRandom);
+    RIT(mt, cStats);
+    RIT(mt, cWorld);
+    RIT(mt, cWorldDriver);
+
+    mt.MarkAll();
+#endif
+    
+    ERROR("FIXME at kgn: test outcome varies with random seed");
+    char * argv[] = {
+      "cAnalyze_Brainstorm_RunningAnalyze",
+      "-s",
+      "100",
+    };
+    int argc = sizeof(argv)/sizeof(char *);
+
+    cDriverManager::Initialize();
+#if   USE_tMemTrack
+    if(true){
+      TEST(mt.Verify());
+      mt.Report();
+    }
+#endif
+
+    cAvidaConfig* cfg = new cAvidaConfig();
+    Avida::ProcessCmdLineArgs(argc, argv, cfg);
+    cWorld *world = new cWorld(cfg);
+
+#if   USE_tMemTrack
+    if(true){
+      mt.IncMark("cAvidaConfig", 1);
+      mt.IncMark("cAvidaContext", 1);
+      mt.IncMark("cClassificationManager", 1);
+      mt.IncMark("cDataFileManager", 1);
+      mt.IncMark("cEnvironment", 1);
+      mt.IncMark("cEventList", 1);
+      mt.IncMark("cHardwareManager", 1);
+      mt.IncMark("cPopulation", 1);
+      mt.IncMark("cRandom", 2);
+      mt.IncMark("cStats", 1);
+      mt.IncMark("cWorld", 1);
+      mt.IncMark("cWorldDriver", 1);
+
+      TEST(mt.Verify());
+    }
+#endif
+    cAvidaDriver* driver = new cDefaultAnalyzeDriver(
+      world,
+      (world->GetConfig().ANALYZE_MODE.Get() == 2)
+    );
+
+#if   USE_tMemTrack
+    if(true){
+      mt.IncMark("cDefaultAnalyzeDriver", 1);
+
+      TEST(mt.Verify());
+    }
+#endif
+    driver->Run();
+#if   USE_tMemTrack
+    if(true){
+      mt.IncMark("cAnalyze", 1);
+      ERROR("FIXME at kgn: cAvidaContext instance ct varies with random seed");
+      mt.IncMark("cAvidaContext", 2);
+      mt.IncMark("cRandom", 17);
+
+      TEST(mt.Verify());
+    }
+#endif
+    /*
+    Note : driver deletes world.
+    Note : world deletes cfg.
+    */
+    TEST(driver); delete driver; driver=0;
+#if   USE_tMemTrack
+    if(true){
+      mt.IncMark("cAnalyze", -1);
+      mt.IncMark("cAvidaConfig", -1);
+      ERROR("FIXME at kgn: cAvidaContext instance ct varies with random seed");
+      mt.IncMark("cAvidaContext", -2);
+      ERROR("FIXME at kgn: cClassificationManager instance ct varies with random seed");
+      mt.IncMark("cClassificationManager", -1);
+      mt.IncMark("cDataFileManager", -1);
+      mt.IncMark("cEnvironment", -1);
+      mt.IncMark("cEventList", -1);
+      mt.IncMark("cHardwareManager", -1);
+      mt.IncMark("cPopulation", -1);
+      mt.IncMark("cRandom", -3);
+      mt.IncMark("cStats", -1);
+      mt.IncMark("cWorld", -1);
+      mt.IncMark("cWorldDriver", -1);
+      mt.IncMark("cDefaultAnalyzeDriver", -1);
+
+      TEST(mt.Verify());
+      mt.Report();
+    }
+#endif
+
+#if   USE_tMemTrack
+    if(false){
+      TEST(mt.Verify());
+    }
+#endif
+  }
+  cAddTestSuite t("cAnalyze_Brainstorm_RunningAnalyze", testsuite);
+}
+
+/* cAnalyze_Brainstorm_CumulativeStemminess_fake_3 {{{2 */
+/*
+Steps, after having loaded detail and historic files containing tree into current batch:
+- 
+*/
+namespace cAnalyze_Brainstorm_CumulativeStemminess_fake_3 {
+  /* class cAGLData {{{3 */
+  class cAGLData {
+  public:
+    cAnalyzeGenotype *genotype; //
+    int id; //
+    int pid; //
+    int depth; //
+    int birth; //
+    int ppos; // convenient but redundant. but now hard-wired. remove in cleanup?
+    int offspring_count; // convenient but redundant.
+    int anc_branch_dist;
+    int anc_branch_id;
+    int anc_branch_pos;
+    int off_branch_dist_acc;
+    double cumulative_stemminess;
+    bool traversal_visited;
+    tArray<int> offspring_positions;
+
+    cAGLData()
+    : genotype(0)
+    , id(-1)
+    , pid(-1)
+    , depth(-1)
+    , birth(-1)
+    , ppos(-1)
+    , offspring_count(-1)
+    , anc_branch_dist(-1)
+    , anc_branch_id(-1)
+    , anc_branch_pos(-1)
+    , off_branch_dist_acc(-1)
+    , cumulative_stemminess(-1.)
+    , traversal_visited(false)
+    , offspring_positions(0)
+    {}
+  };
+  /* class cAGLData }}}3 */
+
+  /* class cAnalyzeGenotypeTreeStats {{{3 */
+  class cAnalyzeGenotypeTreeStats {
+  public:
+    tArray<cAGLData> m_agl;
+    tArray<cAGLData> m_agl2;
+
+    double m_stemminess_sum;
+    double m_average_stemminess;
+    int m_inner_nodes;
+    bool m_should_exclude_leaves;
+
+  public:
+    cAnalyzeGenotypeTreeStats()
+    : m_agl(0)
+    , m_agl2(0)
+    , m_stemminess_sum(0.0)
+    , m_average_stemminess(0.0)
+    , m_inner_nodes(0)
+    , m_should_exclude_leaves(true)
+    {}
+
+    tArray<cAGLData> &AGL(){ return m_agl; }
+    tArray<cAGLData> &AGL2(){ return m_agl2; }
+    double StemminessSum(){ return m_stemminess_sum; }
+    double AverageStemminess(){ return m_average_stemminess; }
+    int InnerNodes(){ return m_inner_nodes; }
+    bool ExcludesLeaves(){ return m_should_exclude_leaves; }
+
+    void AnalyzeBatchTree(tList<cAnalyzeGenotype> &genotype_list){
+      cAnalyzeGenotype * genotype = NULL;
+      tListIterator<cAnalyzeGenotype> batch_it(genotype_list);
+      const int num_gens = genotype_list.GetSize();
+
+      int array_pos = 0;
+
+      /*
+      Put all of the genotypes in an array for easy reference and collect other information on them as we process them. {{{4
+      */
+      tArray<cAnalyzeGenotype *> gen_array(num_gens);
+      tHashTable<int, int> id_hash;  // Store array pos for each id.
+      tArray<int> id_array(num_gens), pid_array(num_gens);
+      tArray<int> depth_array(num_gens), birth_array(num_gens);
+
+      array_pos = 0;
+      batch_it.Reset();
+      while ((genotype = batch_it.Next()) != NULL) {
+        id_hash.Add(genotype->GetID(), array_pos);
+        array_pos++;
+      }
+
+      m_agl.Resize(num_gens);
+      array_pos = 0;
+      batch_it.Reset();
+      while ((genotype = batch_it.Next()) != NULL) {
+        // Put the genotype in an array.
+        m_agl[array_pos].genotype = genotype;
+        m_agl[array_pos].id = genotype->GetID();
+        m_agl[array_pos].pid = genotype->GetParentID();
+        m_agl[array_pos].depth = genotype->GetDepth();
+        m_agl[array_pos].birth = genotype->GetUpdateBorn();
+        array_pos++;
+      }
+
+      //// Now collect information about the offspring of each individual. {{{4
+      tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+      offspring_count.SetAll(0);
+
+      // For each genotype, figure out how far back you need to go to get to a branch point. {{{4
+      tArray<int> anc_branch_dist_array(num_gens);
+      tArray<int> anc_branch_pos_array(num_gens);
+      anc_branch_dist_array.SetAll(-1);
+      anc_branch_pos_array.SetAll(-1);
+      bool found = true;
+      int loop_count = 0;
+
+      /*
+      Link each offspring to its parent. {{{4
+      */
+      for (int pos = 0; pos < num_gens; pos++) {
+        //cAnalyzeGenotype * genotype = gen_array[pos];
+        cAnalyzeGenotype * genotype = m_agl[pos].genotype;
+        int parent_id = genotype->GetParentID();
+        if (-1 != parent_id){
+          id_hash.Find(parent_id, m_agl[pos].ppos);
+          int parent_position = m_agl[pos].ppos;
+          m_agl[parent_position].offspring_positions.Push(pos);
+          /* XXX I think I'll be able to remove this. */
+          cAnalyzeGenotype * parent_genotype = m_agl[parent_position].genotype;
+          genotype->LinkParent(parent_genotype);
         }
       }
-      bool Expect(const cString &n, int i){
-        cString name(n);
-        cCheckpoint c;
-        if(m_tracker_dict.Find(name, c)){
-          c.Expect(i);
-          m_tracker_dict.SetValue(name, c);
-          return true;
-        } else {
-          return false;
+
+      /*
+      Count offspring of each parent. {{{4
+      */
+      for (int pos = 0; pos < num_gens; pos++) {
+        m_agl[pos].offspring_count = m_agl[pos].offspring_positions.GetSize();
+      }
+
+
+      /*
+      For each genotype, figure out how far back you need to go to get to a branch point. {{{4
+      */
+      found = true;
+      loop_count = 0;
+      while (found == true) {
+        found = false;
+        for (int pos = 0; pos < num_gens; pos++) {
+          if (m_agl[pos].anc_branch_dist > -1) continue; // continue if its set.
+          found = true;
+          int parent_pos = m_agl[pos].ppos;
+          if (parent_pos == -1) {
+            m_agl[pos].anc_branch_dist = 0;  // Org is root.
+          } else if (m_agl[parent_pos].offspring_count > 1) {        // Parent is branch.
+            m_agl[pos].anc_branch_dist = 1;
+            m_agl[pos].anc_branch_id = m_agl[parent_pos].id;
+            m_agl[pos].anc_branch_pos = parent_pos;
+          } else if (m_agl[parent_pos].anc_branch_dist > -1) {     // Parent calculated.
+            m_agl[pos].anc_branch_dist = m_agl[parent_pos].anc_branch_dist + 1;
+            m_agl[pos].anc_branch_id = m_agl[parent_pos].anc_branch_id;
+            m_agl[pos].anc_branch_pos = m_agl[parent_pos].anc_branch_pos;
+          }
+          // Otherwise, we are not yet ready to calculate this entry.
         }
+        loop_count++;
       }
-      bool IncMark(const cString &n, int i){
-        cString name(n);
-        cCheckpoint c;
-        if(m_tracker_dict.Find(name, c)){
-          c.Expect(c.ShowMark() + i);
-          m_tracker_dict.SetValue(name, c);
-          return true;
-        } else {
-          return false;
+
+      // compute number of subtree nodes.
+      int branch_tree_size = 0;
+      for (int pos = 0; pos < num_gens; pos++) {
+        if(m_agl[pos].offspring_count != 1){
+          branch_tree_size++;
         }
       }
-      bool Verify(const cString &n){
-        cString name(n);
-        cCheckpoint c;
-        if(m_tracker_dict.Find(name, c)){
-          return c.Verify();
-        } else {
-          ERROR(name + " is not being tracked");
-          return false;
+
+      m_agl2.Resize(branch_tree_size);  // Store agl data for each id.
+      tHashTable<int, int> id_hash_2;
+      int array_pos_2 = 0;
+      if (true) for (int pos = 0; pos < num_gens; pos++) {
+        int offs_count = m_agl[pos].offspring_count;
+        if (offs_count != 1){
+          m_agl2[array_pos_2].id = m_agl[pos].id;
+          m_agl2[array_pos_2].pid = m_agl[pos].pid;
+          m_agl2[array_pos_2].depth = m_agl[pos].depth;
+          m_agl2[array_pos_2].birth = m_agl[pos].birth;
+          m_agl2[array_pos_2].anc_branch_dist = m_agl[pos].anc_branch_dist;
+          m_agl2[array_pos_2].anc_branch_id = m_agl[pos].anc_branch_id;
+          /*
+          missing still are ppos (skip this), offspring_count (redundant),
+          anc_branch_pos, off_branch_dist_acc (to be calculated),
+          offspring_positions
+          */
+          id_hash_2.Add(m_agl2[array_pos_2].id, array_pos_2);
+          array_pos_2++;
         }
       }
 
-      void ShowMarks(){
-        tList<cString> name_list;
-        tList<cCheckpoint> value_list;
-        m_tracker_dict.AsLists(name_list, value_list);
-        tListIterator<cString> list_it(name_list);
+      // find branch ancestor positions. {{{4
+      for (int pos = 0; pos < branch_tree_size; pos++){
+        int anc_branch_id = m_agl2[pos].anc_branch_id;
+        id_hash_2.Find(anc_branch_id, m_agl2[pos].anc_branch_pos);
+        int anc_branch_pos = m_agl2[pos].anc_branch_pos;
+        if(0 <= anc_branch_pos){
+          m_agl2[anc_branch_pos].offspring_positions.Push(pos);
+        }
+      }
+      
+      /*
+      For DFS of branch tree, locate root. {{{4
+      */
+      cAGLData *root = 0;
+      for (int pos = 0; pos < branch_tree_size; pos++){
+        m_agl2[pos].traversal_visited = false;
+        /*
+        root : anc_branch_dist: 0 anc_branch_id: -1 anc_branch_pos: -1 
 
-        while (list_it.Next() != 0) {
-          cString name(*list_it.Get());
-          cout << ShowMark(name) << " marked instances of " << name << endl;
+        Only one of these conditions should be needed. I'm mixing-in a
+        sanity check here. I ought to move it...
+        */
+        if( (m_agl2[pos].anc_branch_dist == 0)
+          ||(m_agl2[pos].anc_branch_id == -1)
+          ||(m_agl2[pos].anc_branch_pos == -1)
+        ){
+          root = &(m_agl2[pos]);
+          /* Sanity check. */
+          if(!( (m_agl2[pos].anc_branch_dist == 0)
+              &&(m_agl2[pos].anc_branch_id == -1)
+              &&(m_agl2[pos].anc_branch_pos == -1)
+            )
+          ){
+            ERROR("while looking for root of subtree, found inconsistencies -");
+            return;
+          }
         }
       }
-      void MarkAll(){
-        tList<cString> name_list;
-        tList<cCheckpoint> value_list;
-        m_tracker_dict.AsLists(name_list, value_list);
-        tListIterator<cString> list_it(name_list);
 
-        while (list_it.Next() != 0) { Mark(*list_it.Get()); }
+      /*
+      DFS of branch tree, to accumulate branch distances. {{{4
+      */
+      tList<cAGLData> dfs_stack;
+      if(0 != root){
+        /* DFS. */
+        dfs_stack.Push(root);
+        cAGLData *node = 0;
+        while (0 < dfs_stack.GetSize()){
+          node = dfs_stack.Pop();
+          if (0 != node){
+            if (! node->traversal_visited){
+              dfs_stack.Push(node);
+              node->off_branch_dist_acc = 0;
+              for (int i = 0; i < node->offspring_positions.GetSize(); i++){
+                int pos = node->offspring_positions[i];
+                if (! m_agl2[pos].traversal_visited){
+                  dfs_stack.Push(&(m_agl2[pos]));
+                }
+              }
+              node->traversal_visited = true;
+            } else {
+              /*
+              Child nodes, if any, have been visited and have added their
+              off_branch_dist_acc to this node.
+              */
+              if(0 <= node->anc_branch_pos){
+                /*
+                Only accumulate to parent if there is a parent (i.e., this
+                is not the root.)
+                */
+                m_agl2[node->anc_branch_pos].off_branch_dist_acc += node->anc_branch_dist;
+                m_agl2[node->anc_branch_pos].off_branch_dist_acc += node->off_branch_dist_acc;
+              }
+            }
+          }
+        }
+      } else {
+        ERROR("couldn't find root of subtree -");
+        return;
       }
-      void Report(){
-        tList<cString> name_list;
-        tList<cCheckpoint> value_list;
-        m_tracker_dict.AsLists(name_list, value_list);
-        tListIterator<cString> list_it(name_list);
 
-        while (list_it.Next() != 0) {
-          cString name(*list_it.Get());
-          cout << Instances(name) << " instances of " << name << endl;
+      /*
+      Compute cumulative stemminesses. {{{4
+      */
+      for (int pos = 0; pos < branch_tree_size; pos++){
+        if (0 == m_agl2[pos].anc_branch_dist){
+          /* Correct stemminess for root... */
+          /*
+          Let me rephrase that. If anc_branch_dist is zero and all is well,
+          we're dealing with the root.
+          */
+          m_agl2[pos].cumulative_stemminess = 0.0;
+        } else {
+          m_agl2[pos].cumulative_stemminess =
+            (double)(m_agl2[pos].anc_branch_dist)
+            /
+            (
+              (double)(m_agl2[pos].off_branch_dist_acc) + (double)(m_agl2[pos].anc_branch_dist)
+            )
+            ;
         }
       }
-      bool Verify(){
-        tList<cString> name_list;
-        tList<cCheckpoint> value_list;
-        m_tracker_dict.AsLists(name_list, value_list);
-        tListIterator<cString> list_it(name_list);
 
-        int failures = 0;
-        while (list_it.Next() != 0) {
-          cString name(*list_it.Get());
-          if(!Verify(name)){
-            ERROR(name + " has unexpected instance count");
-            cerr << ShowMark(name) << " marked instances of " << name << endl;
-            cerr << Instances(name) << " instances of " << name << endl;
-            failures++;
+      /*
+      Compute average cumulative stemminess. {{{4
+      */
+      m_stemminess_sum = 0.0;
+      m_average_stemminess = 0.0;
+      m_inner_nodes = 0;
+      if (1 < branch_tree_size) {
+        for (int pos = 0; pos < branch_tree_size; pos++){
+          bool not_leaf = true;
+          if (m_should_exclude_leaves) {
+            not_leaf = (0 < m_agl2[pos].off_branch_dist_acc);
           }
+          bool not_root = (0 < m_agl2[pos].anc_branch_id);
+          if (not_leaf && not_root){
+            m_stemminess_sum += m_agl2[pos].cumulative_stemminess;
+            m_inner_nodes++;
+          }
         }
-        return 0 == failures;
       }
-    };
+      if(0 < m_inner_nodes){
+        m_average_stemminess = m_stemminess_sum / (m_inner_nodes);
+      }
 
-#if USE_tMemTrack
-    class cNul {
-      tMemTrack<cNul> mt;
-    };
-#endif
+      /*
+      Print branch tree. {{{4
+      Use to get expected data for making following test.
+      */
 
-    void test(){
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+      if (false){
+        for (int pos = 0; pos < branch_tree_size; pos++){
+          cout << "ida: " << m_agl2[pos].id;
+          cout << " offspring_count: " << m_agl2[pos].offspring_positions.GetSize();
+          cout << " anc_branch_id: " << m_agl2[pos].anc_branch_id;
+          cout << " anc_branch_dist: " << m_agl2[pos].anc_branch_dist;
+          cout << " off_branch_dist_acc: " << m_agl2[pos].off_branch_dist_acc;
+          cout << " cumulative_stemminess: " << m_agl2[pos].cumulative_stemminess;
+          cout << endl;
+          if (0 < m_agl2[pos].offspring_positions.GetSize()) {
+            cout << "  offspring ids:";
+            for (int i = 0; i < m_agl2[pos].offspring_positions.GetSize(); i++){
+              cout << " " << m_agl2[pos].offspring_positions[i];
+            }
+            cout << endl;
+          }
+        }
+        cout << "m_stemminess_sum: " << m_stemminess_sum << endl;
+        cout << "m_average_stemminess: " << m_average_stemminess << endl;
+        cout << "m_inner_nodes: " << m_inner_nodes << endl;
+      }
+    }
 
+  };
+  /* class cAnalyzeGenotypeTreeStats }}}3 */
+
+  void testsuite(){
+    cout << "XXX This is an incomplete test. @kgn" << endl;
     /*
-    Tests of cMemTracker.
+    Generate fake data files containing hand-crafted tree.  {{{3
+    We know what its stemminess should be.
     */
-#if USE_tMemTrack
+    cString detail_fake_filename("./detail-fake.pop");
+    std::ofstream detail_file(detail_fake_filename);
+    detail_file << "#filetype genotype_data" << endl;
+    detail_file << "#format id parent_id parent_dist num_cpus total_cpus length merit gest_time fitness update_born update_dead depth sequence" << endl;
+    detail_file << "" << endl;
+    detail_file << "#  1: ID" << endl;
+    detail_file << "#  2: parent ID" << endl;
+    detail_file << "#  3: depth in phylogentic tree" << endl;
+    detail_file << "" << endl;
+    detail_file << "36 35 22 #" << endl;
+    detail_file << "44 43 23 #" << endl;
+    detail_file << "56 55 21 #" << endl;
+    detail_file << "63 62 20 #" << endl;
+    detail_file << "71 70 21 #" << endl;
+    detail_file << "# This file was autogenerated to test Avida." << endl;
+    detail_file << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+    detail_file.close();
+
+    cString historic_fake_filename("./historic-fake.pop");
+    std::ofstream historic_file(historic_fake_filename);
+    historic_file << "#filetype genotype_data" << endl;
+    historic_file << "#format id parent_id parent_dist num_cpus total_cpus length merit gest_time fitness update_born update_dead depth sequence" << endl;
+    historic_file << "" << endl;
+    historic_file << "#  1: ID" << endl;
+    historic_file << "#  2: parent ID" << endl;
+    historic_file << "#  3: depth in phylogentic tree" << endl;
+    historic_file << "" << endl;
+    historic_file << "# important nodes:" << endl;
+    historic_file << " 1 -1  0 #" << endl;
+    historic_file << "16 15 15 #" << endl;
+    historic_file << "25 24  9 #" << endl;
+    historic_file << "29 28 13 #" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 14 genotypes between 1 and 16:" << endl;
+    historic_file << "2 1 1" << endl;
+    historic_file << "3 2 2" << endl;
+    historic_file << "4 3 3" << endl;
+    historic_file << "5 4 4" << endl;
+    historic_file << "6 5 5" << endl;
+    historic_file << "7 6 6" << endl;
+    historic_file << "8 7 7" << endl;
+    historic_file << "9 8 8" << endl;
+    historic_file << "10 9 9" << endl;
+    historic_file << "11 10 10" << endl;
+    historic_file << "12 11 11" << endl;
+    historic_file << "13 12 12" << endl;
+    historic_file << "14 13 13" << endl;
+    historic_file << "15 14 14" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 8 genotypes between 1 and 25:" << endl;
+    historic_file << "17  1 1" << endl;
+    historic_file << "18 17 2" << endl;
+    historic_file << "19 18 3" << endl;
+    historic_file << "20 19 4" << endl;
+    historic_file << "21 20 5" << endl;
+    historic_file << "22 21 6" << endl;
+    historic_file << "23 22 7" << endl;
+    historic_file << "24 23 8" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 3 genotypes between 25 and 29" << endl;
+    historic_file << "26 25 10" << endl;
+    historic_file << "27 26 11" << endl;
+    historic_file << "28 27 12" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 6 genotypes between 16 and 36" << endl;
+    historic_file << "30 16 16" << endl;
+    historic_file << "31 30 17" << endl;
+    historic_file << "32 31 18" << endl;
+    historic_file << "33 32 19" << endl;
+    historic_file << "34 33 20" << endl;
+    historic_file << "35 34 21" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 7 genotypes between 16 and 44" << endl;
+    historic_file << "37 16 16" << endl;
+    historic_file << "38 37 17" << endl;
+    historic_file << "39 38 18" << endl;
+    historic_file << "40 39 19" << endl;
+    historic_file << "41 40 20" << endl;
+    historic_file << "42 41 21" << endl;
+    historic_file << "43 42 22" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 11 genotypes between 25 and 56" << endl;
+    historic_file << "45 25 10" << endl;
+    historic_file << "46 45 11" << endl;
+    historic_file << "47 46 12" << endl;
+    historic_file << "48 47 13" << endl;
+    historic_file << "49 48 14" << endl;
+    historic_file << "50 49 15" << endl;
+    historic_file << "51 50 16" << endl;
+    historic_file << "52 51 17" << endl;
+    historic_file << "53 52 18" << endl;
+    historic_file << "54 53 19" << endl;
+    historic_file << "55 54 20" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 6 genotypes between 29 and 63" << endl;
+    historic_file << "57 29 14" << endl;
+    historic_file << "58 57 15" << endl;
+    historic_file << "59 58 16" << endl;
+    historic_file << "60 59 17" << endl;
+    historic_file << "61 60 18" << endl;
+    historic_file << "62 61 19" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 7 genotypes between 29 and 71" << endl;
+    historic_file << "64 29 14" << endl;
+    historic_file << "65 64 15" << endl;
+    historic_file << "66 65 16" << endl;
+    historic_file << "67 66 17" << endl;
+    historic_file << "68 67 18" << endl;
+    historic_file << "69 68 19" << endl;
+    historic_file << "70 69 20" << endl;
+    historic_file << "# This file was autogenerated to test Avida." << endl;
+    historic_file << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+    historic_file.close();
+
+    /*
+    Initialize Avida {{{3
+    */
+
+    /* Prep to run in analyze mode with args "-s 100" {{{3 */
+    cStringList arg_list;
+    arg_list.PushRear("cAnalyze_Brainstorm_CumulativeStemminess_fake_1");
+    arg_list.PushRear("-s");
+    arg_list.PushRear("100");
+
+    /* Standard init, then get analyze object. {{{3 */
+    cDriverManager::Initialize();
+    cAvidaConfig* cfg = new cAvidaConfig();
+    Avida::ProcessArgs(arg_list, cfg);
+    cWorld *world = new cWorld(cfg);
+    cAvidaDriver* driver = new cDefaultAnalyzeDriver(
+      world,
+      (world->GetConfig().ANALYZE_MODE.Get() == 2)
+    );
+    cAnalyze& a = world->GetAnalyze();
+
+    /* Load hand-crafted tree. We know what its stemminesses should be.  {{{3 */
+    a.Send("SET_BATCH 0");
+    a.Send("PURGE_BATCH");
+    a.Send(cString("LOAD ") + detail_fake_filename);
+    a.Send(cString("LOAD ") + historic_fake_filename);
+
+    //a.Send("PRINT_TREE_STATS");
+
+    std::remove(detail_fake_filename);
+    std::remove(historic_fake_filename);
+
+    {
+      const int num_gens = a.batch[a.cur_batch].List().GetSize();
+
+      cAnalyzeGenotypeTreeStats agts;
+      agts.AnalyzeBatchTree(a.batch[a.cur_batch].List());
+
+      tListIterator<cAnalyzeGenotype> batch_it(a.batch[a.cur_batch].List());
+
       /*
-      Verifies RIT Macro
-      Verifies cMemTracker::Instances()
+      Test: agl sanity check. {{{3
+
+      Fields: array-pos, id, pid, depth, birth, ppos, offspring_count,
+      anc_branch_dist, anc_branch_pos.
       */
+      cString sanitycheck_filename("./agl_sanitycheck.dat");
       {
-        cMemTracker tmt;
+        if(true) {
+          {
+            std::ofstream scf(sanitycheck_filename);
+            scf << "0 36 35 0 0 39 0 7 6" << endl;
+            scf << "1 44 43 0 0 46 0 8 6" << endl;
+            scf << "2 56 55 0 0 57 0 12 7" << endl;
+            scf << "3 63 62 0 0 63 0 7 8" << endl;
+            scf << "4 71 70 0 0 70 0 8 8" << endl;
+            scf << "5 1 -1 0 0 -1 2 0 -1" << endl;
+            scf << "6 16 15 0 0 22 2 15 5" << endl;
+            scf << "7 25 24 0 0 30 2 9 5" << endl;
+            scf << "8 29 28 0 0 33 2 4 7" << endl;
+            scf << "9 2 1 0 0 5 1 1 5" << endl;
+            scf << "10 3 2 0 0 9 1 2 5" << endl;
+            scf << "11 4 3 0 0 10 1 3 5" << endl;
+            scf << "12 5 4 0 0 11 1 4 5" << endl;
+            scf << "13 6 5 0 0 12 1 5 5" << endl;
+            scf << "14 7 6 0 0 13 1 6 5" << endl;
+            scf << "15 8 7 0 0 14 1 7 5" << endl;
+            scf << "16 9 8 0 0 15 1 8 5" << endl;
+            scf << "17 10 9 0 0 16 1 9 5" << endl;
+            scf << "18 11 10 0 0 17 1 10 5" << endl;
+            scf << "19 12 11 0 0 18 1 11 5" << endl;
+            scf << "20 13 12 0 0 19 1 12 5" << endl;
+            scf << "21 14 13 0 0 20 1 13 5" << endl;
+            scf << "22 15 14 0 0 21 1 14 5" << endl;
+            scf << "23 17 1 0 0 5 1 1 5" << endl;
+            scf << "24 18 17 0 0 23 1 2 5" << endl;
+            scf << "25 19 18 0 0 24 1 3 5" << endl;
+            scf << "26 20 19 0 0 25 1 4 5" << endl;
+            scf << "27 21 20 0 0 26 1 5 5" << endl;
+            scf << "28 22 21 0 0 27 1 6 5" << endl;
+            scf << "29 23 22 0 0 28 1 7 5" << endl;
+            scf << "30 24 23 0 0 29 1 8 5" << endl;
+            scf << "31 26 25 0 0 7 1 1 7" << endl;
+            scf << "32 27 26 0 0 31 1 2 7" << endl;
+            scf << "33 28 27 0 0 32 1 3 7" << endl;
+            scf << "34 30 16 0 0 6 1 1 6" << endl;
+            scf << "35 31 30 0 0 34 1 2 6" << endl;
+            scf << "36 32 31 0 0 35 1 3 6" << endl;
+            scf << "37 33 32 0 0 36 1 4 6" << endl;
+            scf << "38 34 33 0 0 37 1 5 6" << endl;
+            scf << "39 35 34 0 0 38 1 6 6" << endl;
+            scf << "40 37 16 0 0 6 1 1 6" << endl;
+            scf << "41 38 37 0 0 40 1 2 6" << endl;
+            scf << "42 39 38 0 0 41 1 3 6" << endl;
+            scf << "43 40 39 0 0 42 1 4 6" << endl;
+            scf << "44 41 40 0 0 43 1 5 6" << endl;
+            scf << "45 42 41 0 0 44 1 6 6" << endl;
+            scf << "46 43 42 0 0 45 1 7 6" << endl;
+            scf << "47 45 25 0 0 7 1 1 7" << endl;
+            scf << "48 46 45 0 0 47 1 2 7" << endl;
+            scf << "49 47 46 0 0 48 1 3 7" << endl;
+            scf << "50 48 47 0 0 49 1 4 7" << endl;
+            scf << "51 49 48 0 0 50 1 5 7" << endl;
+            scf << "52 50 49 0 0 51 1 6 7" << endl;
+            scf << "53 51 50 0 0 52 1 7 7" << endl;
+            scf << "54 52 51 0 0 53 1 8 7" << endl;
+            scf << "55 53 52 0 0 54 1 9 7" << endl;
+            scf << "56 54 53 0 0 55 1 10 7" << endl;
+            scf << "57 55 54 0 0 56 1 11 7" << endl;
+            scf << "58 57 29 0 0 8 1 1 8" << endl;
+            scf << "59 58 57 0 0 58 1 2 8" << endl;
+            scf << "60 59 58 0 0 59 1 3 8" << endl;
+            scf << "61 60 59 0 0 60 1 4 8" << endl;
+            scf << "62 61 60 0 0 61 1 5 8" << endl;
+            scf << "63 62 61 0 0 62 1 6 8" << endl;
+            scf << "64 64 29 0 0 8 1 1 8" << endl;
+            scf << "65 65 64 0 0 64 1 2 8" << endl;
+            scf << "66 66 65 0 0 65 1 3 8" << endl;
+            scf << "67 67 66 0 0 66 1 4 8" << endl;
+            scf << "68 68 67 0 0 67 1 5 8" << endl;
+            scf << "69 69 68 0 0 68 1 6 8" << endl;
+            scf << "70 70 69 0 0 69 1 7 8" << endl;
+            scf << "# This file was autogenerated to test Avida." << endl;
+            scf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+            scf.close();
+          }
+          {
+            std::ifstream scf(sanitycheck_filename);
+            int in;
+            for (int pos = 0; pos < num_gens; pos++) {
+              scf >> in; TEST(in == pos);
+              scf >> in; TEST(in == agts.AGL()[pos].id);
+              scf >> in; TEST(in == agts.AGL()[pos].pid);
+              scf >> in; TEST(in == agts.AGL()[pos].depth);
+              scf >> in; TEST(in == agts.AGL()[pos].birth);
+              scf >> in; TEST(in == agts.AGL()[pos].ppos);
+              scf >> in; TEST(in == agts.AGL()[pos].offspring_count);
+              scf >> in; TEST(in == agts.AGL()[pos].anc_branch_dist);
+              scf >> in; TEST(in == agts.AGL()[pos].anc_branch_pos);
+            }
+            scf.close();
+          }
+          std::remove(sanitycheck_filename);
+        }
+        if(false) {
+          /*
+          Writes the expected data to a sanitycheck file.
 
-        TEST(-1 == tmt.Instances("cNul"));
+          We then copy the file into this code, and when this test is run, the
+          file is regenerated, and we can check for unexpected changes to actual
+          data.
+          */
+          std::ofstream scf(sanitycheck_filename);
+          for (int pos = 0; pos < num_gens; pos++) {
+            scf << pos;
+            scf << " " << agts.AGL()[pos].id;
+            scf << " " << agts.AGL()[pos].pid;
+            scf << " " << agts.AGL()[pos].depth;
+            scf << " " << agts.AGL()[pos].birth;
+            scf << " " << agts.AGL()[pos].ppos;
+            scf << " " << agts.AGL()[pos].offspring_count;
+            scf << " " << agts.AGL()[pos].anc_branch_dist;
+            scf << " " << agts.AGL()[pos].anc_branch_pos;
+            scf << endl;
+          }
+          scf.close();
+        }
+      }
 
+      /*
+      Test: subtree info. {{{3
+      */
+      cString bicheck_filename("./branchinfo_check.dat");
+      {
+        {
+          std::ofstream bcf(bicheck_filename);
+          bcf << "0 36 0 16 7" << endl;
+          bcf << "1 44 0 16 8" << endl;
+          bcf << "2 56 0 25 12" << endl;
+          bcf << "3 63 0 29 7" << endl;
+          bcf << "4 71 0 29 8" << endl;
+          bcf << "5 1 2 -1 0" << endl;
+          bcf << "6 16 2 1 15" << endl;
+          bcf << "7 25 2 1 9" << endl;
+          bcf << "8 29 2 25 4" << endl;
+          bcf << "# This file was autogenerated to test Avida." << endl;
+          bcf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+          bcf.close();
+        }
+        {
+          std::ifstream bcf(bicheck_filename);
+          int in;
+          for (int pos = 0; pos < num_gens; pos++) {
+            if(agts.AGL()[pos].offspring_count != 1){
+              bcf >> in; TEST(in == pos);
+              bcf >> in; TEST(in == agts.AGL()[pos].id);
+              bcf >> in; TEST(in == agts.AGL()[pos].offspring_count);
+              bcf >> in; TEST(in == agts.AGL()[pos].anc_branch_id);
+              bcf >> in; TEST(in == agts.AGL()[pos].anc_branch_dist);
+            }
+          }
+        }
+        std::remove(bicheck_filename);
+
+        if(false) { // Use me to generate expected data for branch info check.
+          for (int pos = 0; pos < num_gens; pos++) {
+            int offs_count = agts.AGL()[pos].offspring_count;
+            if (offs_count != 1){
+              cout << pos;
+              cout << " " << agts.AGL()[pos].id;
+              cout << " " << agts.AGL()[pos].offspring_count;
+              cout << " " << agts.AGL()[pos].anc_branch_id;
+              cout << " " << agts.AGL()[pos].anc_branch_dist;
+              cout << endl;
+            }
+          }
+        }
+      }
+
+      /*
+      Try making branch-subtree. {{{3
+      - this is made a little more difficult because I don't have pointers
+        from parent to children.
+      */
+      //// compute number of subtree nodes.
+      int branch_tree_size = 0;
+      for (int pos = 0; pos < num_gens; pos++) {
+        if(agts.AGL()[pos].offspring_count != 1){
+          branch_tree_size++;
+        }
+      }
+
+      /*
+      Test computed average cumulative steminess, and steminesses. {{{3
+      */
+      {
+        bool should_exclude_leaves = true;
+
         /*
-        Verifies RIT Macro
+        Reference data. Fields, in order: id, offspring_count,
+        anc_branch_id, anc_branch_dist, off_branch_dist_acc
         */
-        RIT(tmt, cNul);
+        int expected[9][5] = {
+          {36, 0, 16, 7, 0},
+          {44, 0, 16, 8, 0},
+          {56, 0, 25, 12, 0},
+          {63, 0, 29, 7, 0},
+          {71, 0, 29, 8, 0},
+          {1, 2, -1, 0, 70},
+          {16, 2, 1, 15, 15},
+          {25, 2, 1, 9, 31},
+          {29, 2, 25, 4, 15},
+        };
+        // cumulative_stemminesses
+        double expectedf[9];
+        double sum = 0., average = 0.;
+        int nodes = 0;
+        /*
+        Reference computation.
+        */
+        for(int i = 0; i < 9; i++){
+          expectedf[i] =
+            (double)(expected[i][3])
+            /
+            (double)(expected[i][4] + expected[i][3])
+            ;
+        }
+        // set root stemminess to zero.
+        expectedf[5] = 0.0;
+        //for(int i = 0; i < 9; i++){ sum += expectedf[i]; }
+        for(int i = 0; i < 9; i++){
+          bool not_leaf = true;
+          if (should_exclude_leaves) {
+            not_leaf = (0 < expected[i][4]);
+          }
+          bool not_root = (0 < expected[i][2]);
+          if (not_leaf && not_root){
+            nodes++;
+            sum += expectedf[i];
+          }
+        }
+        average = sum / (double)nodes;
 
         /*
-        Verifies cMemTracker::Instances()
+        Verify actual against reference.
         */
-        TEST(0 == tmt.Instances("cNul"));
+        if (true) for (int pos = 0; pos < branch_tree_size; pos++){
+          TEST(expected[pos][0] == agts.AGL2()[pos].id);
+          TEST(expected[pos][1] == agts.AGL2()[pos].offspring_positions.GetSize());
+          TEST(expected[pos][2] == agts.AGL2()[pos].anc_branch_id);
+          TEST(expected[pos][3] == agts.AGL2()[pos].anc_branch_dist);
+          TEST(expected[pos][4] == agts.AGL2()[pos].off_branch_dist_acc);
+        }
 
-        cNul n;
+        TEST(sum == agts.StemminessSum());
+        TEST(average == agts.AverageStemminess());
+        TEST(nodes == agts.InnerNodes());
+      }
 
-        TEST(1 == tmt.Instances("cNul"));
-      }
       /*
-      Verifies cMemTracker::Mark()
-      Verifies cMemTracker::ShowMark()
+      Test traversing back to original ancestor. {{{3
       */
+      cString traversalcheck_filename("./traversalcheck.dat");
       {
-        cMemTracker tmt;
+        /* Below are generated expected data file for traversal sanity check.  */
+        {
+          std::ofstream tcf(traversalcheck_filename);
+          tcf << "36 35 34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "44 43 42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "56 55 54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "63 62 61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "71 70 69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "1" << endl;
+          tcf << "16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "2 1" << endl;
+          tcf << "3 2 1" << endl;
+          tcf << "4 3 2 1" << endl;
+          tcf << "5 4 3 2 1" << endl;
+          tcf << "6 5 4 3 2 1" << endl;
+          tcf << "7 6 5 4 3 2 1" << endl;
+          tcf << "8 7 6 5 4 3 2 1" << endl;
+          tcf << "9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "17 1" << endl;
+          tcf << "18 17 1" << endl;
+          tcf << "19 18 17 1" << endl;
+          tcf << "20 19 18 17 1" << endl;
+          tcf << "21 20 19 18 17 1" << endl;
+          tcf << "22 21 20 19 18 17 1" << endl;
+          tcf << "23 22 21 20 19 18 17 1" << endl;
+          tcf << "24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "35 34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "43 42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "55 54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "62 61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "70 69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "# This file was autogenerated to test Avida." << endl;
+          tcf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+          tcf.close();
+        }
+        {
+          std::ifstream tcf(traversalcheck_filename);
+          int in;
+          for (int pos = 0; pos < num_gens; pos++) {
+            cAGLData d;
+            for (d = agts.AGL()[pos]; 0 <= d.ppos; d = agts.AGL()[d.ppos]) {
+              tcf >> in; TEST(in == d.id);
+            }
+            tcf >> in; TEST(in == d.id);
+          }
+        }
+        std::remove(traversalcheck_filename);
 
-        TEST(-1 == tmt.Instances("cNul"));
-        TEST(-1 == tmt.ShowMark("cNul"));
+        if(false) { // Use me to generate expected data for traversal check.
+          cout << endl;
+          for (int pos = 0; pos < num_gens; pos++) {
+            cAGLData d;
+            for (d = agts.AGL()[pos]; 0 <= d.ppos; d = agts.AGL()[d.ppos]) {
+              cout << d.id << " ";
+            }
+            cout << d.id << endl;
+          }
+        }
+      }
+    }
+    TEST(driver); delete driver; driver=0;
 
-        RIT(tmt, cNul);
+    // }}}3
+  }
+  cAddTestSuite t("cAnalyze_Brainstorm_CumulativeStemminess_fake_3", testsuite);
+}
 
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt.Instances("cNul"));
+/* cAnalyze_Brainstorm_CumulativeStemminess_fake_2 {{{2 */
+/*
+To-Do : Seems to crash if historic-fake.pop is not loaded.
+- so apparently gaps in the phylogenetic tree are bad.
+  - FIXME at kgn
+*/
+namespace cAnalyze_Brainstorm_CumulativeStemminess_fake_2 {
+  /* struct cAGLData {{{3 */
+  struct cAGLData {
+    cAnalyzeGenotype *genotype; //
+    int id; //
+    int pid; //
+    int depth; //
+    int birth; //
+    int ppos; // convenient but redundant. but now hard-wired. remove in cleanup?
+    int offspring_count; // convenient but redundant.
+    int anc_branch_dist;
+    int anc_branch_id;
+    int anc_branch_pos;
+    int off_branch_dist_acc;
+    double cumulative_stemminess;
+    bool traversal_visited;
+    tArray<int> offspring_positions;
 
-        cNul n;
+    cAGLData()
+    : genotype(0)
+    , id(-1)
+    , pid(-1)
+    , depth(-1)
+    , birth(-1)
+    , ppos(-1)
+    , offspring_count(-1)
+    , anc_branch_dist(-1)
+    , anc_branch_id(-1)
+    , anc_branch_pos(-1)
+    , off_branch_dist_acc(-1)
+    , cumulative_stemminess(-1.)
+    , traversal_visited(false)
+    , offspring_positions(0)
+    {}
+  };
+  /* struct cAGLData }}}3 */
+  void testsuite(){
+    cout << "XXX This is an incomplete test. @kgn" << endl;
+    /*
+    Generate fake data files containing hand-crafted tree.  {{{3
+    We know what its stemminess should be.
+    */
+    cString detail_fake_filename("./detail-fake.pop");
+    std::ofstream detail_file(detail_fake_filename);
+    detail_file << "#filetype genotype_data" << endl;
+    detail_file << "#format id parent_id parent_dist num_cpus total_cpus length merit gest_time fitness update_born update_dead depth sequence" << endl;
+    detail_file << "" << endl;
+    detail_file << "#  1: ID" << endl;
+    detail_file << "#  2: parent ID" << endl;
+    detail_file << "#  3: depth in phylogentic tree" << endl;
+    detail_file << "" << endl;
+    detail_file << "36 35 22 #" << endl;
+    detail_file << "44 43 23 #" << endl;
+    detail_file << "56 55 21 #" << endl;
+    detail_file << "63 62 20 #" << endl;
+    detail_file << "71 70 21 #" << endl;
+    detail_file << "# This file was autogenerated to test Avida." << endl;
+    detail_file << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+    detail_file.close();
 
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+    cString historic_fake_filename("./historic-fake.pop");
+    std::ofstream historic_file(historic_fake_filename);
+    historic_file << "#filetype genotype_data" << endl;
+    historic_file << "#format id parent_id parent_dist num_cpus total_cpus length merit gest_time fitness update_born update_dead depth sequence" << endl;
+    historic_file << "" << endl;
+    historic_file << "#  1: ID" << endl;
+    historic_file << "#  2: parent ID" << endl;
+    historic_file << "#  3: depth in phylogentic tree" << endl;
+    historic_file << "" << endl;
+    historic_file << "# important nodes:" << endl;
+    historic_file << " 1 -1  0 #" << endl;
+    historic_file << "16 15 15 #" << endl;
+    historic_file << "25 24  9 #" << endl;
+    historic_file << "29 28 13 #" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 14 genotypes between 1 and 16:" << endl;
+    historic_file << "2 1 1" << endl;
+    historic_file << "3 2 2" << endl;
+    historic_file << "4 3 3" << endl;
+    historic_file << "5 4 4" << endl;
+    historic_file << "6 5 5" << endl;
+    historic_file << "7 6 6" << endl;
+    historic_file << "8 7 7" << endl;
+    historic_file << "9 8 8" << endl;
+    historic_file << "10 9 9" << endl;
+    historic_file << "11 10 10" << endl;
+    historic_file << "12 11 11" << endl;
+    historic_file << "13 12 12" << endl;
+    historic_file << "14 13 13" << endl;
+    historic_file << "15 14 14" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 8 genotypes between 1 and 25:" << endl;
+    historic_file << "17  1 1" << endl;
+    historic_file << "18 17 2" << endl;
+    historic_file << "19 18 3" << endl;
+    historic_file << "20 19 4" << endl;
+    historic_file << "21 20 5" << endl;
+    historic_file << "22 21 6" << endl;
+    historic_file << "23 22 7" << endl;
+    historic_file << "24 23 8" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 3 genotypes between 25 and 29" << endl;
+    historic_file << "26 25 10" << endl;
+    historic_file << "27 26 11" << endl;
+    historic_file << "28 27 12" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 6 genotypes between 16 and 36" << endl;
+    historic_file << "30 16 16" << endl;
+    historic_file << "31 30 17" << endl;
+    historic_file << "32 31 18" << endl;
+    historic_file << "33 32 19" << endl;
+    historic_file << "34 33 20" << endl;
+    historic_file << "35 34 21" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 7 genotypes between 16 and 44" << endl;
+    historic_file << "37 16 16" << endl;
+    historic_file << "38 37 17" << endl;
+    historic_file << "39 38 18" << endl;
+    historic_file << "40 39 19" << endl;
+    historic_file << "41 40 20" << endl;
+    historic_file << "42 41 21" << endl;
+    historic_file << "43 42 22" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 11 genotypes between 25 and 56" << endl;
+    historic_file << "45 25 10" << endl;
+    historic_file << "46 45 11" << endl;
+    historic_file << "47 46 12" << endl;
+    historic_file << "48 47 13" << endl;
+    historic_file << "49 48 14" << endl;
+    historic_file << "50 49 15" << endl;
+    historic_file << "51 50 16" << endl;
+    historic_file << "52 51 17" << endl;
+    historic_file << "53 52 18" << endl;
+    historic_file << "54 53 19" << endl;
+    historic_file << "55 54 20" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 6 genotypes between 29 and 63" << endl;
+    historic_file << "57 29 14" << endl;
+    historic_file << "58 57 15" << endl;
+    historic_file << "59 58 16" << endl;
+    historic_file << "60 59 17" << endl;
+    historic_file << "61 60 18" << endl;
+    historic_file << "62 61 19" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 7 genotypes between 29 and 71" << endl;
+    historic_file << "64 29 14" << endl;
+    historic_file << "65 64 15" << endl;
+    historic_file << "66 65 16" << endl;
+    historic_file << "67 66 17" << endl;
+    historic_file << "68 67 18" << endl;
+    historic_file << "69 68 19" << endl;
+    historic_file << "70 69 20" << endl;
+    historic_file << "# This file was autogenerated to test Avida." << endl;
+    historic_file << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+    historic_file.close();
 
-        tmt.Mark("cNul");
+    /*
+    Initialize Avida {{{3
+    */
 
-        TEST(1 == tmt.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+    /* Prep to run in analyze mode with args "-s 100" {{{3 */
+    cStringList arg_list;
+    arg_list.PushRear("cAnalyze_Brainstorm_CumulativeStemminess_fake_1");
+    arg_list.PushRear("-s");
+    arg_list.PushRear("100");
+
+    /* Standard init, then get analyze object. {{{3 */
+    cDriverManager::Initialize();
+    cAvidaConfig* cfg = new cAvidaConfig();
+    Avida::ProcessArgs(arg_list, cfg);
+    cWorld *world = new cWorld(cfg);
+    cAvidaDriver* driver = new cDefaultAnalyzeDriver(
+      world,
+      (world->GetConfig().ANALYZE_MODE.Get() == 2)
+    );
+    cAnalyze& a = world->GetAnalyze();
+
+    /* Load hand-crafted tree. We know what its stemminesses should be.  {{{3 */
+    a.Send("SET_BATCH 0");
+    a.Send("PURGE_BATCH");
+    a.Send(cString("LOAD ") + detail_fake_filename);
+    a.Send(cString("LOAD ") + historic_fake_filename);
+
+    //a.Send("PRINT_TREE_STATS");
+
+    std::remove(detail_fake_filename);
+    std::remove(historic_fake_filename);
+    
+    {
+      cAnalyzeGenotype * genotype = NULL;
+      tListIterator<cAnalyzeGenotype> batch_it(a.batch[a.cur_batch].List());
+      const int num_gens = a.batch[a.cur_batch].List().GetSize();
+
+      int array_pos = 0;
+
+      /*
+      Put all of the genotypes in an array for easy reference and collect other information on them as we process them. {{{3
+      */
+      tArray<cAnalyzeGenotype *> gen_array(num_gens);
+      tHashTable<int, int> id_hash;  // Store array pos for each id.
+      tArray<int> id_array(num_gens), pid_array(num_gens);
+      tArray<int> depth_array(num_gens), birth_array(num_gens);
+
+      array_pos = 0;
+      batch_it.Reset();
+      while ((genotype = batch_it.Next()) != NULL) {
+        id_hash.Add(genotype->GetID(), array_pos);
+        array_pos++;
       }
+
+      tArray<cAGLData> agl(num_gens);  // Store agl data for each id.
+      array_pos = 0;
+      batch_it.Reset();
+      while ((genotype = batch_it.Next()) != NULL) {
+        // Put the genotype in an array.
+        agl[array_pos].genotype = genotype;
+        agl[array_pos].id = genotype->GetID();
+        agl[array_pos].pid = genotype->GetParentID();
+        agl[array_pos].depth = genotype->GetDepth();
+        agl[array_pos].birth = genotype->GetUpdateBorn();
+        array_pos++;
+      }
+
+      //// Now collect information about the offspring of each individual. {{{3
+      tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+      offspring_count.SetAll(0);
+
+      // For each genotype, figure out how far back you need to go to get to a branch point. {{{3
+      tArray<int> anc_branch_dist_array(num_gens);
+      tArray<int> anc_branch_pos_array(num_gens);
+      anc_branch_dist_array.SetAll(-1);
+      anc_branch_pos_array.SetAll(-1);
+      bool found = true;
+      int loop_count = 0;
+
       /*
-      Verifies cMemTracker::Expect()
+      Link each offspring to its parent. {{{3
       */
-      {
-        cMemTracker tmt;
+      for (int pos = 0; pos < num_gens; pos++) {
+        //cAnalyzeGenotype * genotype = gen_array[pos];
+        cAnalyzeGenotype * genotype = agl[pos].genotype;
+        int parent_id = genotype->GetParentID();
+        if (-1 != parent_id){
+          id_hash.Find(parent_id, agl[pos].ppos);
+          int parent_position = agl[pos].ppos;
+          agl[parent_position].offspring_positions.Push(pos);
+          /* XXX I think I'll be able to remove this. */
+          cAnalyzeGenotype * parent_genotype = agl[parent_position].genotype;
+          genotype->LinkParent(parent_genotype);
+        }
+      }
 
-        TEST(-1 == tmt.Instances("cNul"));
-        TEST(-1 == tmt.ShowMark("cNul"));
+      /*
+      Count offspring of each parent. {{{3
+      */
+      for (int pos = 0; pos < num_gens; pos++) {
+        //cAnalyzeGenotype * genotype = agl[pos].genotype;
+        //agl[pos].offspring_count = genotype->GetChildList().GetSize();
+        agl[pos].offspring_count = agl[pos].offspring_positions.GetSize();
+      }
 
-        RIT(tmt, cNul);
 
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt.Instances("cNul"));
+      /*
+      For each genotype, figure out how far back you need to go to get to a branch point. {{{3
+      */
+      found = true;
+      loop_count = 0;
+      while (found == true) {
+        found = false;
+        for (int pos = 0; pos < num_gens; pos++) {
+          if (agl[pos].anc_branch_dist > -1) continue; // continue if its set.
+          found = true;
+          int parent_pos = agl[pos].ppos;
+          if (parent_pos == -1) {
+            agl[pos].anc_branch_dist = 0;  // Org is root.
+          } else if (agl[parent_pos].offspring_count > 1) {        // Parent is branch.
+            agl[pos].anc_branch_dist = 1;
+            agl[pos].anc_branch_id = agl[parent_pos].id;
+            agl[pos].anc_branch_pos = parent_pos;
+          } else if (agl[parent_pos].anc_branch_dist > -1) {     // Parent calculated.
+            agl[pos].anc_branch_dist = agl[parent_pos].anc_branch_dist + 1;
+            agl[pos].anc_branch_id = agl[parent_pos].anc_branch_id;
+            agl[pos].anc_branch_pos = agl[parent_pos].anc_branch_pos;
+          }
+          // Otherwise, we are not yet ready to calculate this entry.
+        }
+        loop_count++;
+      }
 
-        cNul n;
+      /*
+      Test: agl sanity check. {{{3
 
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+      Fields: array-pos, id, pid, depth, birth, ppos, offspring_count,
+      anc_branch_dist, anc_branch_pos.
+      */
+      cString sanitycheck_filename("./agl_sanitycheck.dat");
+      {
+        if(true) {
+          {
+            std::ofstream scf(sanitycheck_filename);
+            scf << "0 36 35 0 0 39 0 7 6" << endl;
+            scf << "1 44 43 0 0 46 0 8 6" << endl;
+            scf << "2 56 55 0 0 57 0 12 7" << endl;
+            scf << "3 63 62 0 0 63 0 7 8" << endl;
+            scf << "4 71 70 0 0 70 0 8 8" << endl;
+            scf << "5 1 -1 0 0 -1 2 0 -1" << endl;
+            scf << "6 16 15 0 0 22 2 15 5" << endl;
+            scf << "7 25 24 0 0 30 2 9 5" << endl;
+            scf << "8 29 28 0 0 33 2 4 7" << endl;
+            scf << "9 2 1 0 0 5 1 1 5" << endl;
+            scf << "10 3 2 0 0 9 1 2 5" << endl;
+            scf << "11 4 3 0 0 10 1 3 5" << endl;
+            scf << "12 5 4 0 0 11 1 4 5" << endl;
+            scf << "13 6 5 0 0 12 1 5 5" << endl;
+            scf << "14 7 6 0 0 13 1 6 5" << endl;
+            scf << "15 8 7 0 0 14 1 7 5" << endl;
+            scf << "16 9 8 0 0 15 1 8 5" << endl;
+            scf << "17 10 9 0 0 16 1 9 5" << endl;
+            scf << "18 11 10 0 0 17 1 10 5" << endl;
+            scf << "19 12 11 0 0 18 1 11 5" << endl;
+            scf << "20 13 12 0 0 19 1 12 5" << endl;
+            scf << "21 14 13 0 0 20 1 13 5" << endl;
+            scf << "22 15 14 0 0 21 1 14 5" << endl;
+            scf << "23 17 1 0 0 5 1 1 5" << endl;
+            scf << "24 18 17 0 0 23 1 2 5" << endl;
+            scf << "25 19 18 0 0 24 1 3 5" << endl;
+            scf << "26 20 19 0 0 25 1 4 5" << endl;
+            scf << "27 21 20 0 0 26 1 5 5" << endl;
+            scf << "28 22 21 0 0 27 1 6 5" << endl;
+            scf << "29 23 22 0 0 28 1 7 5" << endl;
+            scf << "30 24 23 0 0 29 1 8 5" << endl;
+            scf << "31 26 25 0 0 7 1 1 7" << endl;
+            scf << "32 27 26 0 0 31 1 2 7" << endl;
+            scf << "33 28 27 0 0 32 1 3 7" << endl;
+            scf << "34 30 16 0 0 6 1 1 6" << endl;
+            scf << "35 31 30 0 0 34 1 2 6" << endl;
+            scf << "36 32 31 0 0 35 1 3 6" << endl;
+            scf << "37 33 32 0 0 36 1 4 6" << endl;
+            scf << "38 34 33 0 0 37 1 5 6" << endl;
+            scf << "39 35 34 0 0 38 1 6 6" << endl;
+            scf << "40 37 16 0 0 6 1 1 6" << endl;
+            scf << "41 38 37 0 0 40 1 2 6" << endl;
+            scf << "42 39 38 0 0 41 1 3 6" << endl;
+            scf << "43 40 39 0 0 42 1 4 6" << endl;
+            scf << "44 41 40 0 0 43 1 5 6" << endl;
+            scf << "45 42 41 0 0 44 1 6 6" << endl;
+            scf << "46 43 42 0 0 45 1 7 6" << endl;
+            scf << "47 45 25 0 0 7 1 1 7" << endl;
+            scf << "48 46 45 0 0 47 1 2 7" << endl;
+            scf << "49 47 46 0 0 48 1 3 7" << endl;
+            scf << "50 48 47 0 0 49 1 4 7" << endl;
+            scf << "51 49 48 0 0 50 1 5 7" << endl;
+            scf << "52 50 49 0 0 51 1 6 7" << endl;
+            scf << "53 51 50 0 0 52 1 7 7" << endl;
+            scf << "54 52 51 0 0 53 1 8 7" << endl;
+            scf << "55 53 52 0 0 54 1 9 7" << endl;
+            scf << "56 54 53 0 0 55 1 10 7" << endl;
+            scf << "57 55 54 0 0 56 1 11 7" << endl;
+            scf << "58 57 29 0 0 8 1 1 8" << endl;
+            scf << "59 58 57 0 0 58 1 2 8" << endl;
+            scf << "60 59 58 0 0 59 1 3 8" << endl;
+            scf << "61 60 59 0 0 60 1 4 8" << endl;
+            scf << "62 61 60 0 0 61 1 5 8" << endl;
+            scf << "63 62 61 0 0 62 1 6 8" << endl;
+            scf << "64 64 29 0 0 8 1 1 8" << endl;
+            scf << "65 65 64 0 0 64 1 2 8" << endl;
+            scf << "66 66 65 0 0 65 1 3 8" << endl;
+            scf << "67 67 66 0 0 66 1 4 8" << endl;
+            scf << "68 68 67 0 0 67 1 5 8" << endl;
+            scf << "69 69 68 0 0 68 1 6 8" << endl;
+            scf << "70 70 69 0 0 69 1 7 8" << endl;
+            scf << "# This file was autogenerated to test Avida." << endl;
+            scf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+            scf.close();
+          }
+          {
+            std::ifstream scf(sanitycheck_filename);
+            int in;
+            for (int pos = 0; pos < num_gens; pos++) {
+              scf >> in; TEST(in == pos);
+              scf >> in; TEST(in == agl[pos].id);
+              scf >> in; TEST(in == agl[pos].pid);
+              scf >> in; TEST(in == agl[pos].depth);
+              scf >> in; TEST(in == agl[pos].birth);
+              scf >> in; TEST(in == agl[pos].ppos);
+              scf >> in; TEST(in == agl[pos].offspring_count);
+              scf >> in; TEST(in == agl[pos].anc_branch_dist);
+              scf >> in; TEST(in == agl[pos].anc_branch_pos);
+            }
+            scf.close();
+          }
+          std::remove(sanitycheck_filename);
+        }
+        if(false) {
+          /*
+          Writes the expected data to a sanitycheck file.
 
-        tmt.Expect("cNul", 1);
+          We then copy the file into this code, and when this test is run, the
+          file is regenerated, and we can check for unexpected changes to actual
+          data.
+          */
+          std::ofstream scf(sanitycheck_filename);
+          for (int pos = 0; pos < num_gens; pos++) {
+            scf << pos;
+            scf << " " << agl[pos].id;
+            scf << " " << agl[pos].pid;
+            scf << " " << agl[pos].depth;
+            scf << " " << agl[pos].birth;
+            scf << " " << agl[pos].ppos;
+            scf << " " << agl[pos].offspring_count;
+            scf << " " << agl[pos].anc_branch_dist;
+            scf << " " << agl[pos].anc_branch_pos;
+            scf << endl;
+          }
+          scf.close();
+        }
+      }
 
-        TEST(1 == tmt.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+      /*
+      Test: branch-subtree info. {{{3
+      */
+      ERROR("TODO at kgn: rename 'branch subtree' and 'branch tree' to something better -");
+      cString bicheck_filename("./branchinfo_check.dat");
+      {
+        {
+          std::ofstream bcf(bicheck_filename);
+          bcf << "0 36 0 16 7" << endl;
+          bcf << "1 44 0 16 8" << endl;
+          bcf << "2 56 0 25 12" << endl;
+          bcf << "3 63 0 29 7" << endl;
+          bcf << "4 71 0 29 8" << endl;
+          bcf << "5 1 2 -1 0" << endl;
+          bcf << "6 16 2 1 15" << endl;
+          bcf << "7 25 2 1 9" << endl;
+          bcf << "8 29 2 25 4" << endl;
+          bcf << "# This file was autogenerated to test Avida." << endl;
+          bcf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+          bcf.close();
+        }
+        {
+          std::ifstream bcf(bicheck_filename);
+          int in;
+          for (int pos = 0; pos < num_gens; pos++) {
+            if(agl[pos].offspring_count != 1){
+              bcf >> in; TEST(in == pos);
+              bcf >> in; TEST(in == agl[pos].id);
+              bcf >> in; TEST(in == agl[pos].offspring_count);
+              bcf >> in; TEST(in == agl[pos].anc_branch_id);
+              bcf >> in; TEST(in == agl[pos].anc_branch_dist);
+            }
+          }
+        }
+        std::remove(bicheck_filename);
+
+        if(false) { // Use me to generate expected data for branch info check.
+          for (int pos = 0; pos < num_gens; pos++) {
+            int offs_count = agl[pos].offspring_count;
+            if (offs_count != 1){
+              cout << pos;
+              cout << " " << agl[pos].id;
+              cout << " " << agl[pos].offspring_count;
+              cout << " " << agl[pos].anc_branch_id;
+              cout << " " << agl[pos].anc_branch_dist;
+              cout << endl;
+            }
+          }
+        }
       }
+
       /*
-      Verifies cMemTracker::IncMark()
+      Try making branch-subtree. {{{3
+      - this is made a little more difficult because I don't have pointers
+        from parent to children.
       */
       {
-        cMemTracker tmt;
+        // compute number of subtree nodes.
+        int branch_tree_size = 0;
+        for (int pos = 0; pos < num_gens; pos++) {
+          if(agl[pos].offspring_count != 1){
+            branch_tree_size++;
+          }
+        }
 
-        TEST(-1 == tmt.Instances("cNul"));
-        TEST(-1 == tmt.ShowMark("cNul"));
+        tArray<cAGLData> agl2(branch_tree_size);  // Store agl data for each id.
+        tHashTable<int, int> id_hash_2;
+        int array_pos_2 = 0;
+        if (true) for (int pos = 0; pos < num_gens; pos++) {
+          int offs_count = agl[pos].offspring_count;
+          if (offs_count != 1){
+            agl2[array_pos_2].id = agl[pos].id;
+            agl2[array_pos_2].pid = agl[pos].pid;
+            agl2[array_pos_2].depth = agl[pos].depth;
+            agl2[array_pos_2].birth = agl[pos].birth;
+            agl2[array_pos_2].anc_branch_dist = agl[pos].anc_branch_dist;
+            agl2[array_pos_2].anc_branch_id = agl[pos].anc_branch_id;
+            /*
+            missing still are ppos (skip this), offspring_count (redundant),
+            anc_branch_pos, off_branch_dist_acc (to be calculated),
+            offspring_positions
+            */
+            id_hash_2.Add(agl2[array_pos_2].id, array_pos_2);
+            array_pos_2++;
+          }
+        }
 
-        RIT(tmt, cNul);
+        // find branch ancestor positions. {{{3
+        for (int pos = 0; pos < branch_tree_size; pos++){
+          int anc_branch_id = agl2[pos].anc_branch_id;
+          id_hash_2.Find(anc_branch_id, agl2[pos].anc_branch_pos);
+          int anc_branch_pos = agl2[pos].anc_branch_pos;
+          if(0 <= anc_branch_pos){
+            agl2[anc_branch_pos].offspring_positions.Push(pos);
+          }
+        }
+        
+        /*
+        For DFS of branch tree, locate root. {{{3
+        */
+        cAGLData *root = 0;
+        for (int pos = 0; pos < branch_tree_size; pos++){
+          agl2[pos].traversal_visited = false;
+          /*
+          root : anc_branch_dist: 0 anc_branch_id: -1 anc_branch_pos: -1 
 
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt.Instances("cNul"));
+          Only one of these conditions should be needed. I'm mixing-in a
+          sanity check here. I ought to move it...
+          */
+          if( (agl2[pos].anc_branch_dist == 0)
+            ||(agl2[pos].anc_branch_id == -1)
+            ||(agl2[pos].anc_branch_pos == -1)
+          ){
+            root = &(agl2[pos]);
+            /* Sanity check. */
+            if(!( (agl2[pos].anc_branch_dist == 0)
+                &&(agl2[pos].anc_branch_id == -1)
+                &&(agl2[pos].anc_branch_pos == -1)
+              )
+            ){
+              ERROR("while looking for root of 'branches' tree, found inconsistencies -");
+            }
+          }
+        }
 
-        cNul n;
+        /*
+        DFS of branch tree, to accumulate branch distances. {{{3
+        */
+        tList<cAGLData> dfs_stack;
+        if(0 != root){
+          /* DFS. */
+          dfs_stack.Push(root);
+          cAGLData *node = 0;
+          while (0 < dfs_stack.GetSize()){
+            node = dfs_stack.Pop();
+            /* Sanity check. */
+            TEST(0 != node);
+            if (0 != node){
+              if (! node->traversal_visited){
+                dfs_stack.Push(node);
+                node->off_branch_dist_acc = 0;
+                for (int i = 0; i < node->offspring_positions.GetSize(); i++){
+                  int pos = node->offspring_positions[i];
+                  if (! agl2[pos].traversal_visited){
+                    dfs_stack.Push(&(agl2[pos]));
+                  }
+                }
+                node->traversal_visited = true;
+              } else {
+                /*
+                Child nodes, if any, have been visited and have added their
+                off_branch_dist_acc to this node.
+                */
+                if(0 <= node->anc_branch_pos){
+                  /*
+                  Only accumulate to parent if there is a parent (i.e., this
+                  is not the root.)
+                  */
+                  agl2[node->anc_branch_pos].off_branch_dist_acc += node->anc_branch_dist;
+                  agl2[node->anc_branch_pos].off_branch_dist_acc += node->off_branch_dist_acc;
+                }
+              }
+            }
+          }
+        } else {
+          ERROR("couldn't find root of 'branches' tree -");
+        }
 
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+        /*
+        Compute cumulative stemminesses. {{{3
+        */
+        for (int pos = 0; pos < branch_tree_size; pos++){
+          if (0 == agl2[pos].anc_branch_dist){
+            /* Correct stemminess for root... */
+            /*
+            Let me rephrase that. If anc_branch_dist is zero and all is well,
+            we're dealing with the root.
+            */
+            agl2[pos].cumulative_stemminess = 0.0;
+          } else {
+            agl2[pos].cumulative_stemminess =
+              (double)(agl2[pos].anc_branch_dist)
+              /
+              (
+                (double)(agl2[pos].off_branch_dist_acc) + (double)(agl2[pos].anc_branch_dist)
+              )
+              ;
+          }
+        }
+        TEST(0.0 == root->cumulative_stemminess);
 
-        tmt.IncMark("cNul", 1);
+        /*
+        Compute average cumulative stemminess. {{{3
+        */
+        double stemminess_sum = 0.0;
+        double average_stemminess = 0.0;
+        int inner_nodes = 0;
+        bool should_exclude_leaves = true;
+        if (1 < branch_tree_size) {
+          for (int pos = 0; pos < branch_tree_size; pos++){
+            bool not_leaf = true;
+            if (should_exclude_leaves) {
+              not_leaf = (0 < agl2[pos].off_branch_dist_acc);
+            }
+            bool not_root = (0 < agl2[pos].anc_branch_id);
+            if (not_leaf && not_root){
+              stemminess_sum += agl2[pos].cumulative_stemminess;
+              inner_nodes++;
+            }
+          }
+        }
+        if(0 < inner_nodes){
+          average_stemminess = stemminess_sum / (inner_nodes);
+        }
+        //root->cumulative_stemminess = average_stemminess;
 
-        TEST(1 == tmt.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+        /*
+        Print branch tree. {{{3
+        Use to get expected data for making following test.
+        */
+        if (true) for (int pos = 0; pos < branch_tree_size; pos++){
+          cout << "id: " << agl2[pos].id;
+          cout << " offspring_count: " << agl2[pos].offspring_positions.GetSize();
+          cout << " anc_branch_id: " << agl2[pos].anc_branch_id;
+          cout << " anc_branch_dist: " << agl2[pos].anc_branch_dist;
+          cout << " off_branch_dist_acc: " << agl2[pos].off_branch_dist_acc;
+          cout << " cumulative_stemminess: " << agl2[pos].cumulative_stemminess;
+          cout << endl;
+          if (0 < agl2[pos].offspring_positions.GetSize()) {
+            cout << "  offspring ids:";
+            for (int i = 0; i < agl2[pos].offspring_positions.GetSize(); i++){
+              cout << " " << agl2[pos].offspring_positions[i];
+            }
+            cout << endl;
+          }
+        }
+        cout << "stemminess_sum: " << stemminess_sum << endl;
+        cout << "average_stemminess: " << average_stemminess << endl;
+        cout << "inner_nodes: " << inner_nodes << endl;
 
-        tmt.IncMark("cNul", 2);
+        /*
+        Test computed average cumulative steminess, and steminesses. {{{3
+        */
+        {
+          /*
+          Reference data. Fields, in order: id, offspring_count,
+          anc_branch_id, anc_branch_dist, off_branch_dist_acc
+          */
+          int expected[9][5] = {
+            {36, 0, 16, 7, 0},
+            {44, 0, 16, 8, 0},
+            {56, 0, 25, 12, 0},
+            {63, 0, 29, 7, 0},
+            {71, 0, 29, 8, 0},
+            {1, 2, -1, 0, 70},
+            {16, 2, 1, 15, 15},
+            {25, 2, 1, 9, 31},
+            {29, 2, 25, 4, 15},
+          };
+          // cumulative_stemminesses
+          double expectedf[9];
+          double sum = 0., average = 0.;
+          int nodes = 0;
+          /*
+          Reference computation.
+          */
+          for(int i = 0; i < 9; i++){
+            expectedf[i] =
+              (double)(expected[i][3])
+              /
+              (double)(expected[i][4] + expected[i][3])
+              ;
+          }
+          // set root stemminess to zero.
+          expectedf[5] = 0.0;
+          for(int i = 0; i < 9; i++){ sum += expectedf[i]; }
+          for(int i = 0; i < 9; i++){
+            bool not_leaf = true;
+            if (should_exclude_leaves) {
+              not_leaf = (0 < expected[i][4]);
+            }
+            bool not_root = (0 < expected[i][2]);
+            if (not_leaf && not_root){ nodes++; }
+          }
+          average = sum / (double)nodes;
 
-        TEST(3 == tmt.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+          /*
+          Verify actual against reference.
+          */
+          if (true) for (int pos = 0; pos < branch_tree_size; pos++){
+            TEST(expected[pos][0] == agl2[pos].id);
+            TEST(expected[pos][1] == agl2[pos].offspring_positions.GetSize());
+            TEST(expected[pos][2] == agl2[pos].anc_branch_id);
+            TEST(expected[pos][3] == agl2[pos].anc_branch_dist);
+            TEST(expected[pos][4] == agl2[pos].off_branch_dist_acc);
+          }
+          cout << "sum: " << sum << endl
+               << "average: " << average << endl
+               << endl;
+          TEST(sum == stemminess_sum);
+          TEST(average == average_stemminess);
+          TEST(nodes == inner_nodes);
+        }
       }
+
       /*
-      Verifies cMemTracker copy constructor
+      Test traversing back to original ancestor. {{{3
       */
+      cString traversalcheck_filename("./traversalcheck.dat");
       {
-        cMemTracker tmt;
+        /* Below are generated expected data file for traversal sanity check.  */
+        {
+          std::ofstream tcf(traversalcheck_filename);
+          tcf << "36 35 34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "44 43 42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "56 55 54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "63 62 61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "71 70 69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "1" << endl;
+          tcf << "16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "2 1" << endl;
+          tcf << "3 2 1" << endl;
+          tcf << "4 3 2 1" << endl;
+          tcf << "5 4 3 2 1" << endl;
+          tcf << "6 5 4 3 2 1" << endl;
+          tcf << "7 6 5 4 3 2 1" << endl;
+          tcf << "8 7 6 5 4 3 2 1" << endl;
+          tcf << "9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "17 1" << endl;
+          tcf << "18 17 1" << endl;
+          tcf << "19 18 17 1" << endl;
+          tcf << "20 19 18 17 1" << endl;
+          tcf << "21 20 19 18 17 1" << endl;
+          tcf << "22 21 20 19 18 17 1" << endl;
+          tcf << "23 22 21 20 19 18 17 1" << endl;
+          tcf << "24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "35 34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "43 42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "55 54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "62 61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "70 69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "# This file was autogenerated to test Avida." << endl;
+          tcf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+          tcf.close();
+        }
+        {
+          std::ifstream tcf(traversalcheck_filename);
+          int in;
+          for (int pos = 0; pos < num_gens; pos++) {
+            cAGLData d;
+            for (d = agl[pos]; 0 <= d.ppos; d = agl[d.ppos]) {
+              tcf >> in; TEST(in == d.id);
+            }
+            tcf >> in; TEST(in == d.id);
+          }
+        }
+        std::remove(traversalcheck_filename);
 
-        TEST(-1 == tmt.Instances("cNul"));
-        TEST(-1 == tmt.ShowMark("cNul"));
+        if(false) { // Use me to generate expected data for traversal check.
+          cout << endl;
+          for (int pos = 0; pos < num_gens; pos++) {
+            cAGLData d;
+            for (d = agl[pos]; 0 <= d.ppos; d = agl[d.ppos]) {
+              cout << d.id << " ";
+            }
+            cout << d.id << endl;
+          }
+        }
+      }
+    }
+    TEST(driver); delete driver; driver=0;
 
-        RIT(tmt, cNul);
+    // }}}3
+  }
+  cAddTestSuite t("cAnalyze_Brainstorm_CumulativeStemminess_fake_2", testsuite);
+}
 
-        cMemTracker tmt2(tmt);
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt2.ShowMark("cNul"));
-        TEST(0 == tmt.Instances("cNul"));
+/* cAnalyze_Brainstorm_CumulativeStemminess_fake_1 {{{2 */
+/*
+To-Do : Seems to crash if historic-fake.pop is not loaded.
+- so apparently gaps in the phylogenetic tree are bad.
+  - FIXME at kgn
+*/
+namespace cAnalyze_Brainstorm_CumulativeStemminess_fake_1 {
+  /* struct cAGLData {{{3 */
+  struct cAGLData {
+    cAnalyzeGenotype *genotype; //
+    int id; //
+    int pid; //
+    int depth; //
+    int birth; //
+    int ppos; // convenient but redundant. but now hard-wired. remove in cleanup?
+    int offspring_count; // convenient but redundant.
+    int anc_branch_dist;
+    int anc_branch_id;
+    int anc_branch_pos;
+    int off_branch_dist_acc;
+    double cumulative_stemminess;
+    bool traversal_visited;
+    tArray<int> offspring_positions;
 
-        cNul n;
+    cAGLData()
+    : genotype(0)
+    , id(-1)
+    , pid(-1)
+    , depth(-1)
+    , birth(-1)
+    , ppos(-1)
+    , offspring_count(-1)
+    , anc_branch_dist(-1)
+    , anc_branch_id(-1)
+    , anc_branch_pos(-1)
+    , off_branch_dist_acc(-1)
+    , cumulative_stemminess(-1.)
+    , traversal_visited(false)
+    , offspring_positions(0)
+    {}
+  };
+  /* struct cAGLData }}}3 */
+  void testsuite(){
+    cout << "XXX This is an incomplete test. @kgn" << endl;
+    /*
+    Generate fake data files containing hand-crafted tree.  {{{3
+    We know what its stemminess should be.
+    */
+    cString detail_fake_filename("./detail-fake.pop");
+    std::ofstream detail_file(detail_fake_filename);
+    detail_file << "#filetype genotype_data" << endl;
+    detail_file << "#format id parent_id parent_dist num_cpus total_cpus length merit gest_time fitness update_born update_dead depth sequence" << endl;
+    detail_file << "" << endl;
+    detail_file << "#  1: ID" << endl;
+    detail_file << "#  2: parent ID" << endl;
+    detail_file << "#  3: depth in phylogentic tree" << endl;
+    detail_file << "" << endl;
+    detail_file << "36 35 22 #" << endl;
+    detail_file << "44 43 23 #" << endl;
+    detail_file << "56 55 21 #" << endl;
+    detail_file << "63 62 20 #" << endl;
+    detail_file << "71 70 21 #" << endl;
+    detail_file << "# This file was autogenerated to test Avida." << endl;
+    detail_file << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+    detail_file.close();
 
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt2.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+    cString historic_fake_filename("./historic-fake.pop");
+    std::ofstream historic_file(historic_fake_filename);
+    historic_file << "#filetype genotype_data" << endl;
+    historic_file << "#format id parent_id parent_dist num_cpus total_cpus length merit gest_time fitness update_born update_dead depth sequence" << endl;
+    historic_file << "" << endl;
+    historic_file << "#  1: ID" << endl;
+    historic_file << "#  2: parent ID" << endl;
+    historic_file << "#  3: depth in phylogentic tree" << endl;
+    historic_file << "" << endl;
+    historic_file << "# important nodes:" << endl;
+    historic_file << " 1 -1  0 #" << endl;
+    historic_file << "16 15 15 #" << endl;
+    historic_file << "25 24  9 #" << endl;
+    historic_file << "29 28 13 #" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 14 genotypes between 1 and 16:" << endl;
+    historic_file << "2 1 1" << endl;
+    historic_file << "3 2 2" << endl;
+    historic_file << "4 3 3" << endl;
+    historic_file << "5 4 4" << endl;
+    historic_file << "6 5 5" << endl;
+    historic_file << "7 6 6" << endl;
+    historic_file << "8 7 7" << endl;
+    historic_file << "9 8 8" << endl;
+    historic_file << "10 9 9" << endl;
+    historic_file << "11 10 10" << endl;
+    historic_file << "12 11 11" << endl;
+    historic_file << "13 12 12" << endl;
+    historic_file << "14 13 13" << endl;
+    historic_file << "15 14 14" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 8 genotypes between 1 and 25:" << endl;
+    historic_file << "17  1 1" << endl;
+    historic_file << "18 17 2" << endl;
+    historic_file << "19 18 3" << endl;
+    historic_file << "20 19 4" << endl;
+    historic_file << "21 20 5" << endl;
+    historic_file << "22 21 6" << endl;
+    historic_file << "23 22 7" << endl;
+    historic_file << "24 23 8" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 3 genotypes between 25 and 29" << endl;
+    historic_file << "26 25 10" << endl;
+    historic_file << "27 26 11" << endl;
+    historic_file << "28 27 12" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 6 genotypes between 16 and 36" << endl;
+    historic_file << "30 16 16" << endl;
+    historic_file << "31 30 17" << endl;
+    historic_file << "32 31 18" << endl;
+    historic_file << "33 32 19" << endl;
+    historic_file << "34 33 20" << endl;
+    historic_file << "35 34 21" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 7 genotypes between 16 and 44" << endl;
+    historic_file << "37 16 16" << endl;
+    historic_file << "38 37 17" << endl;
+    historic_file << "39 38 18" << endl;
+    historic_file << "40 39 19" << endl;
+    historic_file << "41 40 20" << endl;
+    historic_file << "42 41 21" << endl;
+    historic_file << "43 42 22" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 11 genotypes between 25 and 56" << endl;
+    historic_file << "45 25 10" << endl;
+    historic_file << "46 45 11" << endl;
+    historic_file << "47 46 12" << endl;
+    historic_file << "48 47 13" << endl;
+    historic_file << "49 48 14" << endl;
+    historic_file << "50 49 15" << endl;
+    historic_file << "51 50 16" << endl;
+    historic_file << "52 51 17" << endl;
+    historic_file << "53 52 18" << endl;
+    historic_file << "54 53 19" << endl;
+    historic_file << "55 54 20" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 6 genotypes between 29 and 63" << endl;
+    historic_file << "57 29 14" << endl;
+    historic_file << "58 57 15" << endl;
+    historic_file << "59 58 16" << endl;
+    historic_file << "60 59 17" << endl;
+    historic_file << "61 60 18" << endl;
+    historic_file << "62 61 19" << endl;
+    historic_file << "" << endl;
+    historic_file << "# the 7 genotypes between 29 and 71" << endl;
+    historic_file << "64 29 14" << endl;
+    historic_file << "65 64 15" << endl;
+    historic_file << "66 65 16" << endl;
+    historic_file << "67 66 17" << endl;
+    historic_file << "68 67 18" << endl;
+    historic_file << "69 68 19" << endl;
+    historic_file << "70 69 20" << endl;
+    historic_file << "# This file was autogenerated to test Avida." << endl;
+    historic_file << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+    historic_file.close();
 
-        tmt.IncMark("cNul", 1);
+    /*
+    Initialize Avida {{{3
+    */
 
-        TEST(1 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt2.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+    /* Prep to run in analyze mode with args "-s 100" {{{3 */
+    cStringList arg_list;
+    arg_list.PushRear("cAnalyze_Brainstorm_CumulativeStemminess_fake_1");
+    arg_list.PushRear("-s");
+    arg_list.PushRear("100");
 
-        tmt.IncMark("cNul", 2);
+    /* Standard init, then get analyze object. {{{3 */
+    cDriverManager::Initialize();
+    cAvidaConfig* cfg = new cAvidaConfig();
+    Avida::ProcessArgs(arg_list, cfg);
+    cWorld *world = new cWorld(cfg);
+    cAvidaDriver* driver = new cDefaultAnalyzeDriver(
+      world,
+      (world->GetConfig().ANALYZE_MODE.Get() == 2)
+    );
+    cAnalyze& a = world->GetAnalyze();
 
-        TEST(3 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt2.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
-      }
+    /* Load hand-crafted tree. We know what its stemminesses should be.  {{{3 */
+    a.Send("SET_BATCH 0");
+    a.Send("PURGE_BATCH");
+    a.Send(cString("LOAD ") + detail_fake_filename);
+    a.Send(cString("LOAD ") + historic_fake_filename);
+
+    //a.Send("PRINT_TREE_STATS");
+
+    std::remove(detail_fake_filename);
+    std::remove(historic_fake_filename);
+    
+    {
+      cAnalyzeGenotype * genotype = NULL;
+      tListIterator<cAnalyzeGenotype> batch_it(a.batch[a.cur_batch].List());
+      const int num_gens = a.batch[a.cur_batch].List().GetSize();
+
+      int array_pos = 0;
+
       /*
-      Verifies cMemTracker assignment operator
+      Put all of the genotypes in an array for easy reference and collect other information on them as we process them. {{{3
       */
-      {
-        cMemTracker tmt;
+      tArray<cAnalyzeGenotype *> gen_array(num_gens);
+      tHashTable<int, int> id_hash;  // Store array pos for each id.
+      tArray<int> id_array(num_gens), pid_array(num_gens);
+      tArray<int> depth_array(num_gens), birth_array(num_gens);
 
-        TEST(-1 == tmt.Instances("cNul"));
-        TEST(-1 == tmt.ShowMark("cNul"));
+      array_pos = 0;
+      batch_it.Reset();
+      while ((genotype = batch_it.Next()) != NULL) {
+        id_hash.Add(genotype->GetID(), array_pos);
+        array_pos++;
+      }
 
-        RIT(tmt, cNul);
+      array_pos = 0;
+      batch_it.Reset();
+      while ((genotype = batch_it.Next()) != NULL) {
+        // Put the genotype in an array.
+        gen_array[array_pos] = genotype;
+        id_array[array_pos] = genotype->GetID();
+        pid_array[array_pos] = genotype->GetParentID();
+        depth_array[array_pos] = genotype->GetDepth();
+        birth_array[array_pos] = genotype->GetUpdateBorn();
+        array_pos++;
+      }
 
-        cMemTracker tmt2 = tmt;
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt2.ShowMark("cNul"));
-        TEST(0 == tmt.Instances("cNul"));
+      tArray<cAGLData> agl(num_gens);  // Store agl data for each id.
+      array_pos = 0;
+      batch_it.Reset();
+      while ((genotype = batch_it.Next()) != NULL) {
+        // Put the genotype in an array.
+        agl[array_pos].genotype = genotype;
+        agl[array_pos].id = genotype->GetID();
+        agl[array_pos].pid = genotype->GetParentID();
+        agl[array_pos].depth = genotype->GetDepth();
+        agl[array_pos].birth = genotype->GetUpdateBorn();
+        array_pos++;
+      }
 
-        cNul n;
+      ///*
+      //Link each offspring to its parent.
+      //*/
+      //for (int pos = 0; pos < num_gens; pos++) {
+      //  cAnalyzeGenotype * genotype = gen_array[pos];
+      //  int parent_id = genotype->GetParentID();
+      //  if (-1 != parent_id){
+      //    id_hash.Find(parent_id, agl[pos].ppos);
+      //    int parent_position = agl[pos].ppos;
+      //    agl[parent_position].offspring_positions.Push(pos);
+      //    //cAnalyzeGenotype * parent_genotype = gen_array[agl[pos].ppos];
+      //    //genotype->LinkParent(parent_genotype);
+      //  }
+      //}
 
-        TEST(0 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt2.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
 
-        tmt.IncMark("cNul", 1);
+      // Now collect information about the offspring of each individual. {{{3
+      tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+      offspring_count.SetAll(0);
+      for (int pos = 0; pos < num_gens; pos++) {
+        int parent_id = gen_array[pos]->GetParentID();
+        if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
+          ppos_array[pos] = -1;
+          continue;
+        }
+        int parent_pos = -1;
+        id_hash.Find(parent_id, parent_pos);
+        ppos_array[pos] = parent_pos;
+        offspring_count[parent_pos]++;
+      }
 
-        TEST(1 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt2.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+      // For each genotype, figure out how far back you need to go to get to a branch point. {{{3
+      tArray<int> anc_branch_dist_array(num_gens);
+      tArray<int> anc_branch_pos_array(num_gens);
+      anc_branch_dist_array.SetAll(-1);
+      anc_branch_pos_array.SetAll(-1);
+      bool found = true;
+      int loop_count = 0;
+      while (found == true) {
+        /*
+        'found == false' means we can't find anybody else ready for
+        calculation, which should mean that we're done (tho I don't think
+        this is guaranteed -- we could have a bad graph, for example).
 
-        tmt.IncMark("cNul", 2);
+        So 'found == true' should mean that we have more work to do.
+        */
+        found = false;
+        for (int pos = 0; pos < num_gens; pos++) {
+          // continue if its set. No work to do on this node.
+          if (anc_branch_dist_array[pos] > -1) {
+            continue;
+          }
+          // We have more work to do! so set flag.
+          found = true;
+          int parent_pos = ppos_array[pos];
+          if (parent_pos == -1) {
+            // Org is root.
+            anc_branch_dist_array[pos] = 0;
+          }
+          else if (offspring_count[parent_pos] > 1) {
+            // Parent is branch.
+            anc_branch_dist_array[pos] = 1;
+            anc_branch_pos_array[pos] = parent_pos;
+          }
+          else if (anc_branch_dist_array[parent_pos] > -1) {
+            // Parent calculated.
+            anc_branch_dist_array[pos] = anc_branch_dist_array[parent_pos]+1;
+            anc_branch_pos_array[pos] = anc_branch_pos_array[parent_pos];
+          }
+          // Otherwise, we are not yet ready to calculate this entry.
+        }
+        loop_count++;
+      }
 
-        TEST(3 == tmt.ShowMark("cNul"));
-        TEST(0 == tmt2.ShowMark("cNul"));
-        TEST(1 == tmt.Instances("cNul"));
+      /*
+      Link each offspring to its parent. {{{3
+      */
+      for (int pos = 0; pos < num_gens; pos++) {
+        cAnalyzeGenotype * genotype = gen_array[pos];
+        int parent_id = genotype->GetParentID();
+        if (-1 != parent_id){
+          id_hash.Find(parent_id, agl[pos].ppos);
+          int parent_position = agl[pos].ppos;
+          agl[parent_position].offspring_positions.Push(pos);
+          /* XXX I think I'll be able to remove this. */
+          cAnalyzeGenotype * parent_genotype = agl[parent_position].genotype;
+          genotype->LinkParent(parent_genotype);
+        }
       }
-#endif
 
-#if USE_tMemTrack
-      cMemTracker mt;
-      RIT(mt, cActionLibrary);
-      RIT(mt, cAnalyze);
-      RIT(mt, cAvidaConfig);
-      RIT(mt, cAvidaContext);
-      RIT(mt, cClassificationManager);
-      RIT(mt, cDataFileManager);
-      RIT(mt, cDefaultAnalyzeDriver);
-      RIT(mt, cEnvironment);
-      RIT(mt, cEventList);
-      RIT(mt, cHardwareManager);
-      RIT(mt, cPopulation);
-      RIT(mt, cRandom);
-      RIT(mt, cStats);
-      RIT(mt, cWorld);
-      RIT(mt, cWorldDriver);
+      /*
+      Count offspring of each parent. {{{3
+      */
+      for (int pos = 0; pos < num_gens; pos++) {
+        //cAnalyzeGenotype * genotype = agl[pos].genotype;
+        //agl[pos].offspring_count = genotype->GetChildList().GetSize();
+        agl[pos].offspring_count = agl[pos].offspring_positions.GetSize();
+      }
 
-      mt.MarkAll();
-#endif
-      
-      ERROR("kgn at FIXME: test outcome varies with random seed");
-      char * argv[] = {
-        "cAnalyze_Brainstorm_RunningAnalyze",
-        "-s",
-        "100",
-      };
-      int argc = sizeof(argv)/sizeof(char *);
 
-      cDriverManager::Initialize();
-#if   USE_tMemTrack
-      if(true){
-        TEST(mt.Verify());
-        mt.Report();
+      /*
+      For each genotype, figure out how far back you need to go to get to a branch point. {{{3
+      */
+      found = true;
+      loop_count = 0;
+      while (found == true) {
+        found = false;
+        for (int pos = 0; pos < num_gens; pos++) {
+          if (agl[pos].anc_branch_dist > -1) continue; // continue if its set.
+          found = true;
+          int parent_pos = agl[pos].ppos;
+          if (parent_pos == -1) {
+            agl[pos].anc_branch_dist = 0;  // Org is root.
+          } else if (agl[parent_pos].offspring_count > 1) {        // Parent is branch.
+            agl[pos].anc_branch_dist = 1;
+            agl[pos].anc_branch_id = agl[parent_pos].id;
+            agl[pos].anc_branch_pos = parent_pos;
+          } else if (agl[parent_pos].anc_branch_dist > -1) {     // Parent calculated.
+            agl[pos].anc_branch_dist = agl[parent_pos].anc_branch_dist + 1;
+            agl[pos].anc_branch_id = agl[parent_pos].anc_branch_id;
+            agl[pos].anc_branch_pos = agl[parent_pos].anc_branch_pos;
+          }
+          // Otherwise, we are not yet ready to calculate this entry.
+        }
+        loop_count++;
       }
-#endif
 
-      cWorld *world = new cWorld(
-        cAvidaConfig::LoadWithCmdLineArgs(argc, argv)
-      );
+      /*
+      Generate expected data file for agl sanity check. {{{3
 
-#if   USE_tMemTrack
-      if(true){
-        mt.IncMark("cAvidaConfig", 1);
-        mt.IncMark("cAvidaContext", 1);
-        mt.IncMark("cClassificationManager", 1);
-        mt.IncMark("cDataFileManager", 1);
-        mt.IncMark("cEnvironment", 1);
-        mt.IncMark("cEventList", 1);
-        mt.IncMark("cHardwareManager", 1);
-        mt.IncMark("cPopulation", 1);
-        mt.IncMark("cRandom", 2);
-        mt.IncMark("cStats", 1);
-        mt.IncMark("cWorld", 1);
-        mt.IncMark("cWorldDriver", 1);
+      Fields: array-pos, id, pid, depth, birth, ppos, offspring_count,
+      anc_branch_dist, anc_branch_pos.
+      */
+      cString sanitycheck_filename("./agl_sanitycheck.dat");
+      {
+        if(true) {
+          {
+            std::ofstream scf(sanitycheck_filename);
+            scf << "0 36 35 0 0 39 0 7 6" << endl;
+            scf << "1 44 43 0 0 46 0 8 6" << endl;
+            scf << "2 56 55 0 0 57 0 12 7" << endl;
+            scf << "3 63 62 0 0 63 0 7 8" << endl;
+            scf << "4 71 70 0 0 70 0 8 8" << endl;
+            scf << "5 1 -1 0 0 -1 2 0 -1" << endl;
+            scf << "6 16 15 0 0 22 2 15 5" << endl;
+            scf << "7 25 24 0 0 30 2 9 5" << endl;
+            scf << "8 29 28 0 0 33 2 4 7" << endl;
+            scf << "9 2 1 0 0 5 1 1 5" << endl;
+            scf << "10 3 2 0 0 9 1 2 5" << endl;
+            scf << "11 4 3 0 0 10 1 3 5" << endl;
+            scf << "12 5 4 0 0 11 1 4 5" << endl;
+            scf << "13 6 5 0 0 12 1 5 5" << endl;
+            scf << "14 7 6 0 0 13 1 6 5" << endl;
+            scf << "15 8 7 0 0 14 1 7 5" << endl;
+            scf << "16 9 8 0 0 15 1 8 5" << endl;
+            scf << "17 10 9 0 0 16 1 9 5" << endl;
+            scf << "18 11 10 0 0 17 1 10 5" << endl;
+            scf << "19 12 11 0 0 18 1 11 5" << endl;
+            scf << "20 13 12 0 0 19 1 12 5" << endl;
+            scf << "21 14 13 0 0 20 1 13 5" << endl;
+            scf << "22 15 14 0 0 21 1 14 5" << endl;
+            scf << "23 17 1 0 0 5 1 1 5" << endl;
+            scf << "24 18 17 0 0 23 1 2 5" << endl;
+            scf << "25 19 18 0 0 24 1 3 5" << endl;
+            scf << "26 20 19 0 0 25 1 4 5" << endl;
+            scf << "27 21 20 0 0 26 1 5 5" << endl;
+            scf << "28 22 21 0 0 27 1 6 5" << endl;
+            scf << "29 23 22 0 0 28 1 7 5" << endl;
+            scf << "30 24 23 0 0 29 1 8 5" << endl;
+            scf << "31 26 25 0 0 7 1 1 7" << endl;
+            scf << "32 27 26 0 0 31 1 2 7" << endl;
+            scf << "33 28 27 0 0 32 1 3 7" << endl;
+            scf << "34 30 16 0 0 6 1 1 6" << endl;
+            scf << "35 31 30 0 0 34 1 2 6" << endl;
+            scf << "36 32 31 0 0 35 1 3 6" << endl;
+            scf << "37 33 32 0 0 36 1 4 6" << endl;
+            scf << "38 34 33 0 0 37 1 5 6" << endl;
+            scf << "39 35 34 0 0 38 1 6 6" << endl;
+            scf << "40 37 16 0 0 6 1 1 6" << endl;
+            scf << "41 38 37 0 0 40 1 2 6" << endl;
+            scf << "42 39 38 0 0 41 1 3 6" << endl;
+            scf << "43 40 39 0 0 42 1 4 6" << endl;
+            scf << "44 41 40 0 0 43 1 5 6" << endl;
+            scf << "45 42 41 0 0 44 1 6 6" << endl;
+            scf << "46 43 42 0 0 45 1 7 6" << endl;
+            scf << "47 45 25 0 0 7 1 1 7" << endl;
+            scf << "48 46 45 0 0 47 1 2 7" << endl;
+            scf << "49 47 46 0 0 48 1 3 7" << endl;
+            scf << "50 48 47 0 0 49 1 4 7" << endl;
+            scf << "51 49 48 0 0 50 1 5 7" << endl;
+            scf << "52 50 49 0 0 51 1 6 7" << endl;
+            scf << "53 51 50 0 0 52 1 7 7" << endl;
+            scf << "54 52 51 0 0 53 1 8 7" << endl;
+            scf << "55 53 52 0 0 54 1 9 7" << endl;
+            scf << "56 54 53 0 0 55 1 10 7" << endl;
+            scf << "57 55 54 0 0 56 1 11 7" << endl;
+            scf << "58 57 29 0 0 8 1 1 8" << endl;
+            scf << "59 58 57 0 0 58 1 2 8" << endl;
+            scf << "60 59 58 0 0 59 1 3 8" << endl;
+            scf << "61 60 59 0 0 60 1 4 8" << endl;
+            scf << "62 61 60 0 0 61 1 5 8" << endl;
+            scf << "63 62 61 0 0 62 1 6 8" << endl;
+            scf << "64 64 29 0 0 8 1 1 8" << endl;
+            scf << "65 65 64 0 0 64 1 2 8" << endl;
+            scf << "66 66 65 0 0 65 1 3 8" << endl;
+            scf << "67 67 66 0 0 66 1 4 8" << endl;
+            scf << "68 68 67 0 0 67 1 5 8" << endl;
+            scf << "69 69 68 0 0 68 1 6 8" << endl;
+            scf << "70 70 69 0 0 69 1 7 8" << endl;
+            scf << "# This file was autogenerated to test Avida." << endl;
+            scf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+            scf.close();
+          }
+          {
+            std::ifstream scf(sanitycheck_filename);
+            int in;
+            for (int pos = 0; pos < num_gens; pos++) {
+              scf >> in; TEST(in == pos);
+              scf >> in; TEST(in == agl[pos].id);
+              scf >> in; TEST(in == agl[pos].pid);
+              scf >> in; TEST(in == agl[pos].depth);
+              scf >> in; TEST(in == agl[pos].birth);
+              scf >> in; TEST(in == agl[pos].ppos);
+              scf >> in; TEST(in == agl[pos].offspring_count);
+              scf >> in; TEST(in == agl[pos].anc_branch_dist);
+              scf >> in; TEST(in == agl[pos].anc_branch_pos);
+            }
+            scf.close();
+          }
+          std::remove(sanitycheck_filename);
+        }
+        if(false) {
+          /*
+          Writes the expected data to a sanitycheck file.
 
-        TEST(mt.Verify());
+          We then copy the file into this code, and when this test is run, the
+          file is regenerated, and we can check for unexpected changes to actual
+          data.
+          */
+          std::ofstream scf(sanitycheck_filename);
+          for (int pos = 0; pos < num_gens; pos++) {
+            scf << pos;
+            scf << " " << agl[pos].id;
+            scf << " " << agl[pos].pid;
+            scf << " " << agl[pos].depth;
+            scf << " " << agl[pos].birth;
+            scf << " " << agl[pos].ppos;
+            scf << " " << agl[pos].offspring_count;
+            scf << " " << agl[pos].anc_branch_dist;
+            scf << " " << agl[pos].anc_branch_pos;
+            scf << endl;
+          }
+          scf.close();
+        }
       }
-#endif
-      cAvidaDriver* driver = new cDefaultAnalyzeDriver(
-        world,
-        (world->GetConfig().ANALYZE_MODE.Get() == 2)
-      );
 
-#if   USE_tMemTrack
-      if(true){
-        mt.IncMark("cDefaultAnalyzeDriver", 1);
+      /*
+      Test printing branch-subtree info. {{{3
+      */
+      cString bicheck_filename("./branchinfo_check.dat");
+      {
+        {
+          std::ofstream bcf(bicheck_filename);
+          bcf << "0 36 0 16 7" << endl;
+          bcf << "1 44 0 16 8" << endl;
+          bcf << "2 56 0 25 12" << endl;
+          bcf << "3 63 0 29 7" << endl;
+          bcf << "4 71 0 29 8" << endl;
+          bcf << "5 1 2 -1 0" << endl;
+          bcf << "6 16 2 1 15" << endl;
+          bcf << "7 25 2 1 9" << endl;
+          bcf << "8 29 2 25 4" << endl;
+          bcf << "# This file was autogenerated to test Avida." << endl;
+          bcf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+          bcf.close();
+        }
+        {
+          std::ifstream bcf(bicheck_filename);
+          int in;
+          for (int pos = 0; pos < num_gens; pos++) {
+            if(agl[pos].offspring_count != 1){
+              bcf >> in; TEST(in == pos);
+              bcf >> in; TEST(in == agl[pos].id);
+              bcf >> in; TEST(in == agl[pos].offspring_count);
+              bcf >> in; TEST(in == agl[pos].anc_branch_id);
+              bcf >> in; TEST(in == agl[pos].anc_branch_dist);
+            }
+          }
+        }
+        std::remove(bicheck_filename);
 
-        TEST(mt.Verify());
+        if(false) { // Use me to generate expected data for branch info check.
+          for (int pos = 0; pos < num_gens; pos++) {
+            int offs_count = agl[pos].offspring_count;
+            if (offs_count != 1){
+              cout << pos;
+              cout << " " << agl[pos].id;
+              cout << " " << agl[pos].offspring_count;
+              cout << " " << agl[pos].anc_branch_id;
+              cout << " " << agl[pos].anc_branch_dist;
+              cout << endl;
+            }
+          }
+        }
       }
-#endif
-      driver->Run();
-#if   USE_tMemTrack
-      if(true){
-        mt.IncMark("cAnalyze", 1);
-        ERROR("kgn at FIXME: cAvidaContext instance ct varies with random seed");
-        mt.IncMark("cAvidaContext", 2);
-        mt.IncMark("cRandom", 17);
 
-        TEST(mt.Verify());
-      }
-#endif
       /*
-      FIXME : driver currently deletes world.
+      Try making branch-subtree. {{{3
+      - this is made a little more difficult because I don't have pointers
+        from parent to children.
       */
-      ERROR("kgn at FIXME: driver deletes world. is this intended?");
-      TEST(driver); delete driver; driver=0;
-#if   USE_tMemTrack
-      if(true){
-        mt.IncMark("cAnalyze", -1);
-        mt.IncMark("cAvidaConfig", -1);
-        ERROR("kgn at FIXME: cAvidaContext instance ct varies with random seed");
-        mt.IncMark("cAvidaContext", -2);
-        ERROR("kgn at FIXME: cClassificationManager instance ct varies with random seed");
-        mt.IncMark("cClassificationManager", -1);
-        mt.IncMark("cDataFileManager", -1);
-        mt.IncMark("cEnvironment", -1);
-        mt.IncMark("cEventList", -1);
-        mt.IncMark("cHardwareManager", -1);
-        mt.IncMark("cPopulation", -1);
-        mt.IncMark("cRandom", -3);
-        mt.IncMark("cStats", -1);
-        mt.IncMark("cWorld", -1);
-        mt.IncMark("cWorldDriver", -1);
-        mt.IncMark("cDefaultAnalyzeDriver", -1);
+      {
+        // compute number of subtree nodes.
+        int branch_tree_size = 0;
+        for (int pos = 0; pos < num_gens; pos++) {
+          if(agl[pos].offspring_count != 1){
+            branch_tree_size++;
+          }
+        }
 
-        TEST(mt.Verify());
-        mt.Report();
+        tArray<cAGLData> agl2(branch_tree_size);  // Store agl data for each id.
+        tHashTable<int, int> id_hash_2;
+        int array_pos_2 = 0;
+        if (true) for (int pos = 0; pos < num_gens; pos++) {
+          int offs_count = agl[pos].offspring_count;
+          if (offs_count != 1){
+            agl2[array_pos_2].id = agl[pos].id;
+            agl2[array_pos_2].pid = agl[pos].pid;
+            agl2[array_pos_2].depth = agl[pos].depth;
+            agl2[array_pos_2].birth = agl[pos].birth;
+            agl2[array_pos_2].anc_branch_dist = agl[pos].anc_branch_dist;
+            agl2[array_pos_2].anc_branch_id = agl[pos].anc_branch_id;
+            /*
+            missing still are ppos (skip this), offspring_count (redundant),
+            anc_branch_pos, off_branch_dist_acc (to be calculated),
+            offspring_positions
+            */
+            id_hash_2.Add(agl2[array_pos_2].id, array_pos_2);
+            array_pos_2++;
+          }
+        }
+
+        // find branch ancestor positions. {{{3
+        for (int pos = 0; pos < branch_tree_size; pos++){
+          int anc_branch_id = agl2[pos].anc_branch_id;
+          id_hash_2.Find(anc_branch_id, agl2[pos].anc_branch_pos);
+          int anc_branch_pos = agl2[pos].anc_branch_pos;
+          if(0 <= anc_branch_pos){
+            agl2[anc_branch_pos].offspring_positions.Push(pos);
+          }
+        }
+        
+        /*
+        For DFS of branch tree, locate root. {{{3
+        */
+        cAGLData *root = 0;
+        for (int pos = 0; pos < branch_tree_size; pos++){
+          agl2[pos].traversal_visited = false;
+          /*
+          root : anc_branch_dist: 0 anc_branch_id: -1 anc_branch_pos: -1 
+
+          Only one of these conditions should be needed. I'm mixing-in a
+          sanity check here. I ought to move it...
+          */
+          if( (agl2[pos].anc_branch_dist == 0)
+            ||(agl2[pos].anc_branch_id == -1)
+            ||(agl2[pos].anc_branch_pos == -1)
+          ){
+            root = &(agl2[pos]);
+            /* Sanity check. */
+            if(!( (agl2[pos].anc_branch_dist == 0)
+                &&(agl2[pos].anc_branch_id == -1)
+                &&(agl2[pos].anc_branch_pos == -1)
+              )
+            ){
+              ERROR("while looking for root of 'branches' tree, found inconsistencies -");
+            }
+          }
+        }
+
+        /*
+        DFS of branch tree, to accumulate branch distances. {{{3
+        */
+        tList<cAGLData> dfs_stack;
+        if(0 != root){
+          /* DFS. */
+          dfs_stack.Push(root);
+          cAGLData *node = 0;
+          while (0 < dfs_stack.GetSize()){
+            node = dfs_stack.Pop();
+            /* Sanity check. */
+            TEST(0 != node);
+            if (0 != node){
+              if (! node->traversal_visited){
+                dfs_stack.Push(node);
+                node->off_branch_dist_acc = 0;
+                for (int i = 0; i < node->offspring_positions.GetSize(); i++){
+                  int pos = node->offspring_positions[i];
+                  if (! agl2[pos].traversal_visited){
+                    dfs_stack.Push(&(agl2[pos]));
+                  }
+                }
+                node->traversal_visited = true;
+              } else {
+                /*
+                Child nodes, if any, have been visited and have added their
+                off_branch_dist_acc to this node.
+                */
+                if(0 <= node->anc_branch_pos){
+                  /*
+                  Only accumulate to parent if there is a parent (i.e., this
+                  is not the root.)
+                  */
+                  agl2[node->anc_branch_pos].off_branch_dist_acc += node->anc_branch_dist;
+                  agl2[node->anc_branch_pos].off_branch_dist_acc += node->off_branch_dist_acc;
+                }
+              }
+            }
+          }
+        } else {
+          ERROR("couldn't find root of 'branches' tree -");
+        }
+
+        /*
+        Compute cumulative stemminesses. {{{3
+        */
+        for (int pos = 0; pos < branch_tree_size; pos++){
+          if (0 == agl2[pos].anc_branch_dist){
+            /* Correct stemminess for root... */
+            /*
+            Let me rephrase that. If anc_branch_dist is zero and all is well,
+            we're dealing with the root.
+            */
+            agl2[pos].cumulative_stemminess = 0.0;
+          } else {
+            agl2[pos].cumulative_stemminess = (
+              (double)(agl2[pos].off_branch_dist_acc) + (double)(agl2[pos].anc_branch_dist)
+            ) / (double)(agl2[pos].anc_branch_dist);
+          }
+        }
+        TEST(0.0 == root->cumulative_stemminess);
+
+        /*
+        Compute average cumulative stemminess. {{{3
+        */
+        double stemminess_sum = 0.0;
+        double average_stemminess = 0.0;
+        int inner_nodes = 0;
+        bool should_exclude_leaves = false;
+        if (1 < branch_tree_size) {
+          for (int pos = 0; pos < branch_tree_size; pos++){
+            bool not_leaf = true;
+            if (should_exclude_leaves) {
+              not_leaf = (0 < agl2[pos].off_branch_dist_acc);
+            }
+            bool not_root = (0 < agl2[pos].anc_branch_id);
+            if (not_leaf && not_root){
+              stemminess_sum += agl2[pos].cumulative_stemminess;
+              inner_nodes++;
+            }
+          }
+        }
+        if(0 < inner_nodes){
+          average_stemminess = stemminess_sum / (inner_nodes);
+        }
+        //root->cumulative_stemminess = average_stemminess;
+
+        /*
+        Print branch tree. {{{3
+        Use to get expected data for making following test.
+        */
+        if (false) for (int pos = 0; pos < branch_tree_size; pos++){
+          cout << "id: " << agl2[pos].id;
+          cout << " offspring_count: " << agl2[pos].offspring_positions.GetSize();
+          cout << " anc_branch_id: " << agl2[pos].anc_branch_id;
+          cout << " anc_branch_dist: " << agl2[pos].anc_branch_dist;
+          cout << " off_branch_dist_acc: " << agl2[pos].off_branch_dist_acc;
+          cout << " cumulative_stemminess: " << agl2[pos].cumulative_stemminess;
+          cout << endl;
+          if (0 < agl2[pos].offspring_positions.GetSize()) {
+            cout << "  offspring ids:";
+            for (int i = 0; i < agl2[pos].offspring_positions.GetSize(); i++){
+              cout << " " << agl2[pos].offspring_positions[i];
+            }
+            cout << endl;
+          }
+        }
+        cout << "stemminess_sum: " << stemminess_sum << endl;
+        cout << "average_stemminess: " << average_stemminess << endl;
+        cout << "inner_nodes: " << inner_nodes << endl;
+
+        /*
+        Test computed average cumulative steminess, and steminesses. {{{3
+        */
+        {
+          /*
+          Reference data. Fields, in order: id, offspring_count,
+          anc_branch_id, anc_branch_dist, off_branch_dist_acc
+          */
+          int expected[9][5] = {
+            {36, 0, 16, 7, 0},
+            {44, 0, 16, 8, 0},
+            {56, 0, 25, 12, 0},
+            {63, 0, 29, 7, 0},
+            {71, 0, 29, 8, 0},
+            {1, 2, -1, 0, 70},
+            {16, 2, 1, 15, 15},
+            {25, 2, 1, 9, 31},
+            {29, 2, 25, 4, 15},
+          };
+          // cumulative_stemminesses
+          double expectedf[9];
+          double sum = 0., average = 0.;
+          int nodes = 0;
+          /*
+          Reference computation.
+          */
+          for(int i = 0; i < 9; i++){
+            expectedf[i] =
+              (double)( expected[i][4] + expected[i][3]) / (double)(expected[i][3]);
+          }
+          // set root stemminess to zero.
+          expectedf[5] = 0.0;
+          for(int i = 0; i < 9; i++){ sum += expectedf[i]; }
+          for(int i = 0; i < 9; i++){
+            bool not_leaf = true;
+            if (should_exclude_leaves) {
+              not_leaf = (0 < expected[i][4]);
+            }
+            bool not_root = (0 < expected[i][2]);
+            if (not_leaf && not_root){ nodes++; }
+          }
+          average = sum / (double)nodes;
+
+          /*
+          Verify actual against reference.
+          */
+          if (true) for (int pos = 0; pos < branch_tree_size; pos++){
+            TEST(expected[pos][0] == agl2[pos].id);
+            TEST(expected[pos][1] == agl2[pos].offspring_positions.GetSize());
+            TEST(expected[pos][2] == agl2[pos].anc_branch_id);
+            TEST(expected[pos][3] == agl2[pos].anc_branch_dist);
+            TEST(expected[pos][4] == agl2[pos].off_branch_dist_acc);
+          }
+          TEST(sum == stemminess_sum);
+          TEST(average == average_stemminess);
+          TEST(nodes == inner_nodes);
+        }
       }
-#endif
 
-      //TEST(world); delete world; world=0;
+      /*
+      Test traversing back to original ancestor. {{{3
+      */
+      cString traversalcheck_filename("./traversalcheck.dat");
+      {
+        /* Below are generated expected data file for traversal sanity check.  */
+        {
+          std::ofstream tcf(traversalcheck_filename);
+          tcf << "36 35 34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "44 43 42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "56 55 54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "63 62 61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "71 70 69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "1" << endl;
+          tcf << "16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "2 1" << endl;
+          tcf << "3 2 1" << endl;
+          tcf << "4 3 2 1" << endl;
+          tcf << "5 4 3 2 1" << endl;
+          tcf << "6 5 4 3 2 1" << endl;
+          tcf << "7 6 5 4 3 2 1" << endl;
+          tcf << "8 7 6 5 4 3 2 1" << endl;
+          tcf << "9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "17 1" << endl;
+          tcf << "18 17 1" << endl;
+          tcf << "19 18 17 1" << endl;
+          tcf << "20 19 18 17 1" << endl;
+          tcf << "21 20 19 18 17 1" << endl;
+          tcf << "22 21 20 19 18 17 1" << endl;
+          tcf << "23 22 21 20 19 18 17 1" << endl;
+          tcf << "24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "35 34 33 32 31 30 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "43 42 41 40 39 38 37 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1" << endl;
+          tcf << "45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "55 54 53 52 51 50 49 48 47 46 45 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "62 61 60 59 58 57 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "70 69 68 67 66 65 64 29 28 27 26 25 24 23 22 21 20 19 18 17 1" << endl;
+          tcf << "# This file was autogenerated to test Avida." << endl;
+          tcf << "# Test: Brainstorm_CumulativeStemminess_fake_1." << endl;
+          tcf.close();
+        }
+        {
+          std::ifstream tcf(traversalcheck_filename);
+          int in;
+          for (int pos = 0; pos < num_gens; pos++) {
+            cAGLData d;
+            for (d = agl[pos]; 0 <= d.ppos; d = agl[d.ppos]) {
+              tcf >> in; TEST(in == d.id);
+            }
+            tcf >> in; TEST(in == d.id);
+          }
+        }
+        std::remove(traversalcheck_filename);
 
-#if   USE_tMemTrack
-      if(false){
-        TEST(mt.Verify());
+        if(false) { // Use me to generate expected data for traversal check.
+          cout << endl;
+          for (int pos = 0; pos < num_gens; pos++) {
+            cAGLData d;
+            for (d = agl[pos]; 0 <= d.ppos; d = agl[d.ppos]) {
+              cout << d.id << " ";
+            }
+            cout << d.id << endl;
+          }
+        }
       }
-#endif
     }
-    cAddTestSuite t("cAnalyze_Brainstorm_RunningAnalyze", test);
+    TEST(driver); delete driver; driver=0;
+
+    // }}}3
   }
+  cAddTestSuite t("cAnalyze_Brainstorm_CumulativeStemminess_fake_1", testsuite);
+}
 
-  /* cAnalyze_Brainstorm_CumulativeStemminess {{{2 */
-  namespace Brainstorm_CumulativeStemminess {
-    struct cAGLData {
-      cAnalyzeGenotype *genotype; //
-      int id; //
-      int pid; //
-      int depth; //
-      int birth; //
-      int ppos; // convenient but redundant.
-      int offspring_count; // convenient but redundant.
-      int branch_dist;
-      int branch_pos;
+/* cAnalyze_Brainstorm_CumulativeStemminess {{{2 */
+namespace cAnalyze_Brainstorm_CumulativeStemminess {
+  struct cAGLData {
+    cAnalyzeGenotype *genotype; //
+    int id; //
+    int pid; //
+    int depth; //
+    int birth; //
+    int ppos; // convenient but redundant.
+    int offspring_count; // convenient but redundant.
+    int anc_branch_dist;
+    int anc_branch_pos;
 
-      cAGLData()
-      : genotype(0)
-      , id(-1)
-      , pid(-1)
-      , depth(-1)
-      , birth(-1)
-      , ppos(-1)
-      , offspring_count(-1)
-      , branch_dist(-1)
-      , branch_pos(-1)
-      {}
-    };
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("KnownIssues")){
-        ERROR("kgn at FIXME : Skipping Known Issue - this test triggers an abrupt exit -");
-        return;
-      }
-      if(!settings.HasSetting("DevelBase") || (settings.Setting("DevelBase") == "")){
-        cout << "XXX Skipping test : DevelBase not set." << endl;
-        return;
-      }
-      if(!settings.HasSetting("ExtrasBase") || (settings.Setting("ExtrasBase") == "")){
-        cout << "XXX Skipping test : ExtrasBase not set." << endl;
-        return;
-      }
-      cout << "XXX This is an incomplete test. @kgn" << endl;
+    cAGLData()
+    : genotype(0)
+    , id(-1)
+    , pid(-1)
+    , depth(-1)
+    , birth(-1)
+    , ppos(-1)
+    , offspring_count(-1)
+    , anc_branch_dist(-1)
+    , anc_branch_pos(-1)
+    {}
+  };
+  void testsuite(cTestSettings &settings){
+    if(!settings.HasSetting("KnownIssues")){
+      SKIP("Skipping test because KnownIssue is not enabled");
+      ERROR("FIXME at kgn : Known Issue - this test triggers an abrupt exit -");
+      return;
+    }
+    if(!settings.HasSetting("DevelBase") || (settings.Setting("DevelBase") == "")){
+      SKIP("Skipping : DevelBase not set");
+      return;
+    }
+    if(!settings.HasSetting("ExtrasBase") || (settings.Setting("ExtrasBase") == "")){
+      SKIP("Skipping : ExtrasBase not set");
+      return;
+    }
+    cout << "XXX This is an incomplete test. @kgn" << endl;
 
-      ERROR("kgn at FIXME: I should verify the path to data files -");
-      cString data_dir = settings.Setting("ExtrasBase") + "/source/testsuites/nAnalyze/Brainstorm/CumulativeStemminess/data";
+    ERROR("FIXME at kgn: I should verify the path to data files -");
+    cString data_dir = settings.Setting("ExtrasBase") + "/source/testsuites/nAnalyze/Brainstorm/CumulativeStemminess/data";
 
-      /*
-      Initialize
-      */
-      cStringList arg_list;
-      arg_list.PushRear("cAnalyze_Brainstorm_CumulativeStemminess");
-      arg_list.PushRear("-s");
-      arg_list.PushRear("100");
+    /*
+    Initialize
+    */
+    cStringList arg_list;
+    arg_list.PushRear("cAnalyze_Brainstorm_CumulativeStemminess");
+    arg_list.PushRear("-s");
+    arg_list.PushRear("100");
 
-      cDriverManager::Initialize();
-      cWorld *world = new cWorld(cAvidaConfig::LoadWithArgs(arg_list));
+    cDriverManager::Initialize();
+    cAvidaConfig* cfg = new cAvidaConfig();
+    Avida::ProcessArgs(arg_list, cfg);
+    cWorld *world = new cWorld(cfg);
+    cAvidaDriver* driver = new cDefaultAnalyzeDriver(
+      world,
+      (world->GetConfig().ANALYZE_MODE.Get() == 2)
+    );
 
-      cAvidaDriver* driver = new cDefaultAnalyzeDriver(
-        world,
-        (world->GetConfig().ANALYZE_MODE.Get() == 2)
-      );
+    cAnalyze& a = world->GetAnalyze();
 
-      cAnalyze& a = world->GetAnalyze();
+    a.Send(cString("SET d ") + data_dir);
+    a.Send("SET_BATCH 0");
 
-      a.Send(cString("SET d ") + data_dir);
-      a.Send("SET_BATCH 0");
+    a.Send("PURGE_BATCH");
+    a.Send("LOAD $d/detail-5000.pop");
+    a.Send("LOAD $d/historic-5000.pop");
 
-      a.Send("PURGE_BATCH");
-      a.Send("LOAD $d/detail-5000.pop");
-      a.Send("LOAD $d/historic-5000.pop");
+    //a.Send("PRINT_TREE_STATS");
+    
+    if(true){
+      cAnalyzeGenotype * genotype = NULL;
+      tListIterator<cAnalyzeGenotype> batch_it(a.batch[a.cur_batch].List());
+      const int num_gens = a.batch[a.cur_batch].List().GetSize();
+      cout << "num_gens:" << num_gens << endl;
 
-      //a.Send("PRINT_TREE_STATS");
-      
-      if(true){
-        cAnalyzeGenotype * genotype = NULL;
-        tListIterator<cAnalyzeGenotype> batch_it(a.batch[a.cur_batch].List());
-        const int num_gens = a.batch[a.cur_batch].List().GetSize();
-        cout << "num_gens:" << num_gens << endl;
+      // Put all of the genotypes in an array for easy reference and collect
+      // other information on them as we process them.
+      tArray<cAnalyzeGenotype *> gen_array(num_gens);
+      tHashTable<int, int> id_hash;  // Store array pos for each id.
+      tArray<int> id_array(num_gens), pid_array(num_gens);
+      tArray<int> depth_array(num_gens), birth_array(num_gens);
+      int array_pos = 0;
+      while ((genotype = batch_it.Next()) != NULL) {
+        // Put the genotype in an array.
+        gen_array[array_pos] = genotype;
+        id_hash.Add(genotype->GetID(), array_pos);
+        id_array[array_pos] = genotype->GetID();
+        pid_array[array_pos] = genotype->GetParentID();
+        depth_array[array_pos] = genotype->GetDepth();
+        birth_array[array_pos] = genotype->GetUpdateBorn();
+        array_pos++;
+      }
 
-        // Put all of the genotypes in an array for easy reference and collect
-        // other information on them as we process them.
-        tArray<cAnalyzeGenotype *> gen_array(num_gens);
-        tHashTable<int, int> id_hash;  // Store array pos for each id.
-        tArray<int> id_array(num_gens), pid_array(num_gens);
-        tArray<int> depth_array(num_gens), birth_array(num_gens);
-        int array_pos = 0;
-        while ((genotype = batch_it.Next()) != NULL) {
-          // Put the genotype in an array.
-          gen_array[array_pos] = genotype;
-          id_hash.Add(genotype->GetID(), array_pos);
-          id_array[array_pos] = genotype->GetID();
-          pid_array[array_pos] = genotype->GetParentID();
-          depth_array[array_pos] = genotype->GetDepth();
-          birth_array[array_pos] = genotype->GetUpdateBorn();
-          array_pos++;
-        }
-
 /**/tArray<cAGLData> agl(num_gens);  // Store agl data for each id.
 
 /**/array_pos = 0;
@@ -756,48 +3393,48 @@
 /**/  TEST(0 == agl[pos].genotype->GetParent());
 /**/}
 
-        // Now collect information about the offspring of each individual.
-        tArray<int> ppos_array(num_gens), offspring_count(num_gens);
-        offspring_count.SetAll(0);
-        for (int pos = 0; pos < num_gens; pos++) {
-          int parent_id = gen_array[pos]->GetParentID();
-          if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
-            ppos_array[pos] = -1;
-            continue;
-          }
-          int parent_pos = -1;
-          id_hash.Find(parent_id, parent_pos);
-          ppos_array[pos] = parent_pos;
-          offspring_count[parent_pos]++;
+      // Now collect information about the offspring of each individual.
+      tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+      offspring_count.SetAll(0);
+      for (int pos = 0; pos < num_gens; pos++) {
+        int parent_id = gen_array[pos]->GetParentID();
+        if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
+          ppos_array[pos] = -1;
+          continue;
         }
+        int parent_pos = -1;
+        id_hash.Find(parent_id, parent_pos);
+        ppos_array[pos] = parent_pos;
+        offspring_count[parent_pos]++;
+      }
 
-        // For each genotype, figure out how far back you need to go to get to a
-        // branch point.
-        tArray<int> branch_dist_array(num_gens);
-        tArray<int> branch_pos_array(num_gens);
-        branch_dist_array.SetAll(-1);
-        branch_pos_array.SetAll(-1);
-        bool found = true;
-        int loop_count = 0;
-        while (found == true) {
-          found = false;
-          for (int pos = 0; pos < num_gens; pos++) {
-            if (branch_dist_array[pos] > -1) continue; // continue if its set.
-            found = true;
-            int parent_pos = ppos_array[pos];
-            if (parent_pos == -1) branch_dist_array[pos] = 0;  // Org is root.
-            else if (offspring_count[parent_pos] > 1) {        // Parent is branch.
-              branch_dist_array[pos] = 1;
-              branch_pos_array[pos] = parent_pos;
-            }
-            else if (branch_dist_array[parent_pos] > -1) {     // Parent calculated.
-              branch_dist_array[pos] = branch_dist_array[parent_pos]+1;
-              branch_pos_array[pos] = branch_pos_array[parent_pos];
-            }
-            // Otherwise, we are not yet ready to calculate this entry.
+      // For each genotype, figure out how far back you need to go to get to a
+      // branch point.
+      tArray<int> anc_branch_dist_array(num_gens);
+      tArray<int> anc_branch_pos_array(num_gens);
+      anc_branch_dist_array.SetAll(-1);
+      anc_branch_pos_array.SetAll(-1);
+      bool found = true;
+      int loop_count = 0;
+      while (found == true) {
+        found = false;
+        for (int pos = 0; pos < num_gens; pos++) {
+          if (anc_branch_dist_array[pos] > -1) continue; // continue if its set.
+          found = true;
+          int parent_pos = ppos_array[pos];
+          if (parent_pos == -1) anc_branch_dist_array[pos] = 0;  // Org is root.
+          else if (offspring_count[parent_pos] > 1) {        // Parent is branch.
+            anc_branch_dist_array[pos] = 1;
+            anc_branch_pos_array[pos] = parent_pos;
           }
-          loop_count++;
+          else if (anc_branch_dist_array[parent_pos] > -1) {     // Parent calculated.
+            anc_branch_dist_array[pos] = anc_branch_dist_array[parent_pos]+1;
+            anc_branch_pos_array[pos] = anc_branch_pos_array[parent_pos];
+          }
+          // Otherwise, we are not yet ready to calculate this entry.
         }
+        loop_count++;
+      }
 
 /*
 Link each offspring to its parent.
@@ -825,47 +3462,47 @@
 /**/while (found == true) {
 /**/  found = false;
 /**/  for (int pos = 0; pos < num_gens; pos++) {
-/**/    if (agl[pos].branch_dist > -1) continue; // continue if its set.
+/**/    if (agl[pos].anc_branch_dist > -1) continue; // continue if its set.
 /**/    found = true;
 /**/    int parent_pos = agl[pos].ppos;
-/**/    if (parent_pos == -1)  agl[pos].branch_dist = 0;  // Org is root.
+/**/    if (parent_pos == -1)  agl[pos].anc_branch_dist = 0;  // Org is root.
 /**/    else if (agl[parent_pos].offspring_count > 1) {        // Parent is branch.
-/**/      agl[pos].branch_dist = 1;
-/**/      agl[pos].branch_pos = parent_pos;
+/**/      agl[pos].anc_branch_dist = 1;
+/**/      agl[pos].anc_branch_pos = parent_pos;
 /**/    }
-/**/    else if (agl[parent_pos].branch_dist > -1) {     // Parent calculated.
-/**/      agl[pos].branch_dist = agl[parent_pos].branch_dist + 1;
-/**/      agl[pos].branch_pos = agl[parent_pos].branch_pos;
+/**/    else if (agl[parent_pos].anc_branch_dist > -1) {     // Parent calculated.
+/**/      agl[pos].anc_branch_dist = agl[parent_pos].anc_branch_dist + 1;
+/**/      agl[pos].anc_branch_pos = agl[parent_pos].anc_branch_pos;
 /**/    }
 /**/    // Otherwise, we are not yet ready to calculate this entry.
 /**/  }
 /**/  loop_count++;
 /**/}
 
-        // Cumulative Stemminess
-        for (int pos = 0; pos < num_gens; pos++) {
-          // We're only interested in internal n-furcating nodes.
-          if (pid_array[pos] == -1) continue;  // Don't want root.
-          if (offspring_count[pos] <= 1) continue; // No leaves or nonfurcating nodes
+      // Cumulative Stemminess
+      for (int pos = 0; pos < num_gens; pos++) {
+        // We're only interested in internal n-furcating nodes.
+        if (pid_array[pos] == -1) continue;  // Don't want root.
+        if (offspring_count[pos] <= 1) continue; // No leaves or nonfurcating nodes
 
-          // @CAO Find distance to all children.
-          // @CAO Find distance to parent branch.
-          // @CAO DO math.
-        }
+        // @CAO Find distance to all children.
+        // @CAO Find distance to parent branch.
+        // @CAO DO math.
+      }
 
 
-        //cout << "LOOP COUNT:" << loop_count << endl;
-        //for (int i = 0; i < num_gens; i++) {
-        //  int branch_pos = branch_pos_array[i];
-        //  int branch_id = (branch_pos == -1) ? -1 : id_array[branch_pos];
-        //  cout
-        //    << "i:" << i << ", "
-        //    << "id:" << id_array[i] << ", "
-        //    << "offspring_ct:" << offspring_count[i] << ", "
-        //    << "branch_dist:" << branch_dist_array[i] << ", "
-        //    << "branch_id:" << branch_id << ", "
-        //    << endl;
-        //}
+      //cout << "LOOP COUNT:" << loop_count << endl;
+      //for (int i = 0; i < num_gens; i++) {
+      //  int anc_branch_pos = anc_branch_pos_array[i];
+      //  int anc_branch_id = (anc_branch_pos == -1) ? -1 : id_array[anc_branch_pos];
+      //  cout
+      //    << "i:" << i << ", "
+      //    << "id:" << id_array[i] << ", "
+      //    << "offspring_ct:" << offspring_count[i] << ", "
+      //    << "anc_branch_dist:" << anc_branch_dist_array[i] << ", "
+      //    << "anc_branch_id:" << anc_branch_id << ", "
+      //    << endl;
+      //}
 
 /*
 XXX
@@ -882,596 +3519,562 @@
 /**/  TEST(agl[pos].birth == birth_array[pos]);
 /**/  TEST(agl[pos].ppos == ppos_array[pos]);
 /**/  TEST(agl[pos].offspring_count == offspring_count[pos]);
-/**/  TEST(agl[pos].branch_dist == branch_dist_array[pos]);
-/**/  TEST(agl[pos].branch_pos == branch_pos_array[pos]);
+/**/  TEST(agl[pos].anc_branch_dist == anc_branch_dist_array[pos]);
+/**/  TEST(agl[pos].anc_branch_pos == anc_branch_pos_array[pos]);
 /**/}
 
-
-        
-      }
-      TEST(driver); delete driver; driver=0;
-
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      //TEST(false);
+      
     }
-    cAddTestSuite t("cAnalyze_Brainstorm_CumulativeStemminess", test);
+    TEST(driver); delete driver; driver=0;
   }
+  cAddTestSuite t("cAnalyze_Brainstorm_CumulativeStemminess", testsuite);
+}
 
-  /* cAnalyze_Brainstorm_SynchronousVsContinuous {{{2 */
-  namespace Brainstorm_SynchronousVsContinuous {
-    void test(cTestSettings &settings){
-      /* Check settings. {{{3 */
-      if(!settings.HasSetting("KnownIssues")){
-        ERROR("kgn at FIXME : Skipping Known Issue - this test triggers an abrupt exit -");
-        return;
-      }
-      if(!settings.HasSetting("SlowTests")){
-        cout << "XXX Skipping : SlowTests not enabled." << endl;
-        return;
-      }
-      if(
-        (!settings.HasSetting("ExtrasBase"))
-        ||
-        (settings.Setting("ExtrasBase") == "")
-      ){
-        cout << "XXX Skipping : ExtrasBase not set." << endl;
-        return;
-      }
+/* cAnalyze_Brainstorm_SynchronousVsContinuous {{{2 */
+namespace cAnalyze_Brainstorm_SynchronousVsContinuous {
+  void testsuite(cTestSettings &settings){
+    /* Check settings. {{{3 */
+    if(!settings.HasSetting("KnownIssues")){
+      SKIP("Skipping test because KnownIssue is not enabled");
+      ERROR("FIXME at kgn : Known Issue - this test triggers an abrupt exit -");
+      return;
+    }
+    if(!settings.HasSetting("SlowTests")){
+      SKIP("Skipping : SlowTests not enabled");
+      return;
+    }
+    if(
+      (!settings.HasSetting("ExtrasBase"))
+      ||
+      (settings.Setting("ExtrasBase") == "")
+    ){
+      SKIP("Skipping : ExtrasBase not set");
+      return;
+    }
 
-      ERROR("kgn at FIXME: should verify paths to config files and data dir -");
+    ERROR("FIXME at kgn: should verify paths to config files and data dir -");
 
-      /* Initialize. {{{3 */
-      cDriverManager::Initialize();
-      cStringList args;
+    /* Initialize. {{{3 */
+    cDriverManager::Initialize();
+    cStringList args;
 
-      cString config_dir
-      = settings.Setting("DevelBase")
-      + "/support/config";
+    cString config_dir
+    = settings.Setting("DevelBase")
+    + "/support/config";
 
-      cString local_config_dir
-      = settings.Setting("ExtrasBase")
-      + "/source/testsuites/nAnalyze/Brainstorm/SynchronousVsContinuous/config";
+    cString local_config_dir
+    = settings.Setting("ExtrasBase")
+    + "/source/testsuites/nAnalyze/Brainstorm/SynchronousVsContinuous/config";
 
-      cString data_dir
-      = settings.Setting("ExtrasBase")
-      + "/source/testsuites/nAnalyze/Brainstorm/SynchronousVsContinuous/data";
+    cString data_dir
+    = settings.Setting("ExtrasBase")
+    + "/source/testsuites/nAnalyze/Brainstorm/SynchronousVsContinuous/data";
 
-      args.PushRear("cAnalyze_Brainstorm_SynchronousVsContinuous");
+    args.PushRear("cAnalyze_Brainstorm_SynchronousVsContinuous");
 
-      args.PushRear("-c");
-      args.PushRear(config_dir + "/avida.cfg");
+    args.PushRear("-c");
+    args.PushRear(config_dir + "/avida.cfg");
 
-      args.PushRear("-s");
-      args.PushRear("100");
+    args.PushRear("-s");
+    args.PushRear("100");
 
-      args.PushRear("-set");
-      args.PushRear("WORLD_X");
-      args.PushRear("100");
+    args.PushRear("-set");
+    args.PushRear("WORLD_X");
+    args.PushRear("100");
 
-      args.PushRear("-set");
-      args.PushRear("WORLD_Y");
-      args.PushRear("100");
+    args.PushRear("-set");
+    args.PushRear("WORLD_Y");
+    args.PushRear("100");
 
-      args.PushRear("-set");
-      args.PushRear("EVENT_FILE");
-      args.PushRear(local_config_dir + "/events.cfg");
+    args.PushRear("-set");
+    args.PushRear("EVENT_FILE");
+    args.PushRear(local_config_dir + "/events.cfg");
 
-      args.PushRear("-set");
-      args.PushRear("START_CREATURE");
-      args.PushRear(local_config_dir + "/default-classic.org");
+    args.PushRear("-set");
+    args.PushRear("START_CREATURE");
+    args.PushRear(local_config_dir + "/default-classic.org");
 
-      args.PushRear("-set");
-      args.PushRear("DATA_DIR");
-      args.PushRear(data_dir);
+    args.PushRear("-set");
+    args.PushRear("DATA_DIR");
+    args.PushRear(data_dir);
 
-      /* Run Avida in standard mode to generate data files. {{{3 */
-      if(false){
-        cout << "------ Starting standard Avida run." << endl;
+    /* Run Avida in standard mode to generate data files. {{{3 */
+    if(false){
+      cout << "------ Starting standard Avida run." << endl;
 
-        cWorld *world = new cWorld(cAvidaConfig::LoadWithArgs(args));
-        ERROR("kgn at FIXME: write unit test verifying args list is not destroyed in cAvidaConfig::LoadWithArgs() -");
-        TEST(world);
-        if(world){
-          cAvidaDriver* driver = new cDefaultRunDriver(world);
-          TEST(driver);
-          if(driver){
-            driver->Run();
-            delete driver; driver=0;
-          }
-          cout << "------ Finished standard Avida run." << endl;
+      cAvidaConfig* cfg = new cAvidaConfig();
+      Avida::ProcessArgs(args, cfg);
+      cWorld *world = new cWorld(cfg);
+      ERROR("FIXME at kgn: write unit test verifying args list is not destroyed in cAvidaConfig::LoadWithArgs() -");
+      TEST(world);
+      if(world){
+        cAvidaDriver* driver = new cDefaultRunDriver(world);
+        TEST(driver);
+        if(driver){
+          driver->Run();
+          delete driver; driver=0;
         }
-        // note: driver deletes world deletes config.
+        cout << "------ Finished standard Avida run." << endl;
       }
-      /* Run Avida in analyze mode to analyze data files. {{{3 */
-      if(true){
-        cout << "------ Starting Avida analysis." << endl;
-        /* Setup of Analyze mode. {{{4 */
-        ERROR("kgn at FIXME: write unit test verifying args list is not destroyed in cAvidaConfig::LoadWithArgs() -");
-        cWorld *world = new cWorld(cAvidaConfig::LoadWithArgs(args));
-        if(!world){
-          ERROR("Couldn't instantiate cWorld -");
-          return;
-        }
+      // note: driver deletes world deletes config.
+    }
+    /* Run Avida in analyze mode to analyze data files. {{{3 */
+    if(true){
+      cout << "------ Starting Avida analysis." << endl;
+      /* Setup of Analyze mode. {{{4 */
+      ERROR("FIXME at kgn: write unit test verifying args list is not destroyed in cAvidaConfig::LoadWithArgs() -");
+      cAvidaConfig* cfg = new cAvidaConfig();
+      Avida::ProcessArgs(args, cfg);
+      cWorld *world = new cWorld(cfg);
+      if(!world){
+        ERROR("Couldn't instantiate cWorld -");
+        return;
+      }
 
-        cAvidaDriver* driver = new cDefaultAnalyzeDriver(world, false);
-        if(!driver){
-          ERROR("Couldn't instantiate cDefaultAnalyzeDriver -");
-          return;
-        }
+      cAvidaDriver* driver = new cDefaultAnalyzeDriver(world, false);
+      if(!driver){
+        ERROR("Couldn't instantiate cDefaultAnalyzeDriver -");
+        return;
+      }
 
-        cAnalyze& a = world->GetAnalyze();
-        cString s;
+      cAnalyze& a = world->GetAnalyze();
+      cString s;
 
-        /* Begin Analyze script. {{{4 */
-        a.Send("VERBOSE");
-        a.Send("SET_BATCH 0");
-        a.Send("PURGE_BATCH");
+      /* Begin Analyze script. {{{4 */
+      a.Send("VERBOSE");
+      a.Send("SET_BATCH 0");
+      a.Send("PURGE_BATCH");
+      {
+        s = "LOAD_ORGANISM ";
+        s += local_config_dir;
+        s += "/default-classic.org";
+      }
+      a.Send(s);
+      //a.Send("RECALCULATE");
+      //a.Send("DETAIL archive_0/detail.dat id parent_id num_cpus fitness viable length sequence");
+
+      /* 'num_gens' synchronous generations. {{{4 */
+      int num_gens = 10;
+      for(int g=0; g<num_gens; g++){
+        /* Mock-up of arguments to COMPETE command. {{{5 */
+        int world_x = world->GetConfig().WORLD_X.Get();
+        int world_y = world->GetConfig().WORLD_Y.Get();
+
+        int batch_size = world_x * world_y;
+        int batch_from = g;
+        int batch_to = g + 1;
+
         {
-          s = "LOAD_ORGANISM ";
-          s += local_config_dir;
-          s += "/default-classic.org";
+          s = "SET s ";
+          s += cStringUtil::Convert(batch_size);
         }
         a.Send(s);
-        //a.Send("RECALCULATE");
-        //a.Send("DETAIL archive_0/detail.dat id parent_id num_cpus fitness viable length sequence");
 
-        /* 'num_gens' synchronous generations. {{{4 */
-        int num_gens = 10;
-        for(int g=0; g<num_gens; g++){
-          /* Mock-up of arguments to COMPETE command. {{{5 */
-          int world_x = world->GetConfig().WORLD_X.Get();
-          int world_y = world->GetConfig().WORLD_Y.Get();
+        {
+          s = "SET f ";
+          s += cStringUtil::Convert(batch_from);
+        }
+        a.Send(s);
 
-          int batch_size = world_x * world_y;
-          int batch_from = g;
-          int batch_to = g + 1;
+        {
+          s = "SET t ";
+          s += cStringUtil::Convert(batch_to);
+        }
+        a.Send(s);
 
-          {
-            s = "SET s ";
-            s += cStringUtil::Convert(batch_size);
-          }
-          a.Send(s);
+        a.Send("SET_BATCH $f");
+        a.Send("RECALCULATE");
+        a.Send("DETAIL detail.dat id parent_id update_born viable fitness length sequence");
 
-          {
-            s = "SET f ";
-            s += cStringUtil::Convert(batch_from);
-          }
-          a.Send(s);
+        a.Send("SET_BATCH $t");
+        a.Send("PURGE_BATCH");
 
-          {
-            s = "SET t ";
-            s += cStringUtil::Convert(batch_to);
-          }
-          a.Send(s);
+        a.Send("COMPETE $s $f $t");
 
-          a.Send("SET_BATCH $f");
-          a.Send("RECALCULATE");
-          a.Send("DETAIL detail.dat id parent_id update_born viable fitness length sequence");
+        a.Send("SET_BATCH $f");
+        a.Send("PURGE_BATCH");
+      }
 
-          a.Send("SET_BATCH $t");
-          a.Send("PURGE_BATCH");
+      a.Send("SET_BATCH $t");
+      a.Send("RECALCULATE");
+      a.Send("DETAIL detail.dat id parent_id update_born viable fitness length sequence");
 
-          a.Send("COMPETE $s $f $t");
 
-          a.Send("SET_BATCH $f");
-          a.Send("PURGE_BATCH");
-        }
-
-        a.Send("SET_BATCH $t");
-        a.Send("RECALCULATE");
-        a.Send("DETAIL detail.dat id parent_id update_born viable fitness length sequence");
-
-
-        delete driver; driver=0;
-        // note: driver deletes world deletes config.
-        
-        cout << "------ Finished Avida analysis." << endl;
-      }
+      delete driver; driver=0;
+      // note: driver deletes world deletes config.
+      
+      cout << "------ Finished Avida analysis." << endl;
     }
-    cAddTestSuite t("cAnalyze_Brainstorm_SynchronousVsContinuous", test);
   }
+  cAddTestSuite t("cAnalyze_Brainstorm_SynchronousVsContinuous", testsuite);
+}
 
 /* Regressions. {{{1 */
-  /* cAnalyze_Regression_HelloWorld {{{2 */
-  namespace Regression_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
+/* cAnalyze_Regression_Ticket1_ {{{2 */
+namespace cAnalyze_Regression_Ticket1_ {
+  /* Test. {{{3 */
+  void testsuite(cTestSettings &settings){
+    /* Check settings. {{{4 */
+    if(!settings.HasSetting("KnownIssues")){
+      SKIP("Skipping test because KnownIssue is not enabled");
+      ERROR("FIXME at kgn : Known Issue - this test triggers an abrupt exit -");
+      return;
     }
-    cAddTestSuite t("cAnalyze_Regression_HelloWorld", test);
-  }
-  /* cAnalyze_Regression_Ticket1_ {{{2 */
-  namespace Regression_Ticket1_ {
-    /* Test. {{{3 */
-    void test(cTestSettings &settings){
-      /* Check settings. {{{4 */
-      if(!settings.HasSetting("KnownIssues")){
-        ERROR("kgn at FIXME : Skipping Known Issue - this test triggers an abrupt exit -");
-        return;
-      }
-      if((!settings.HasSetting("DevelBase")) || (settings.Setting("DevelBase") == "")){
-        cout << "XXX Skipping : DevelBase not set." << endl;
-        return;
-      }
-      if((!settings.HasSetting("ExtrasBase")) || (settings.Setting("ExtrasBase") == "")){
-        cout << "XXX Skipping : ExtrasBase not set." << endl;
-        return;
-      }
+    if((!settings.HasSetting("DevelBase")) || (settings.Setting("DevelBase") == "")){
+      SKIP("Skipping : DevelBase not set");
+      return;
+    }
+    if((!settings.HasSetting("ExtrasBase")) || (settings.Setting("ExtrasBase") == "")){
+      SKIP("Skipping : ExtrasBase not set");
+      return;
+    }
 
-      ERROR("kgn at FIXME - incomplete test -");
-      ERROR("kgn at FIXME - should verify paths to config files and data dir -");
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
+    ERROR("FIXME at kgn - incomplete test -");
+    ERROR("FIXME at kgn - should verify paths to config files and data dir -");
 
-      /* Initialize. {{{4 */
-      cDriverManager::Initialize();
-      cStringList args;
+    /* Initialize. {{{4 */
+    cDriverManager::Initialize();
+    cStringList args;
 
-      cString config_dir
-      = settings.Setting("ExtrasBase")
-      + "/source/testsuites/nAnalyze/Regression/Ticket1_/config";
+    cString config_dir
+    = settings.Setting("ExtrasBase")
+    + "/source/testsuites/nAnalyze/Regression/Ticket1_/config";
 
-      cString data_dir
-      = settings.Setting("ExtrasBase")
-      + "/source/testsuites/nAnalyze/Regression/Ticket1_/data";
+    cString data_dir
+    = settings.Setting("ExtrasBase")
+    + "/source/testsuites/nAnalyze/Regression/Ticket1_/data";
 
-      args.PushRear("cAnalyze_Brainstorm_SynchronousVsContinuous");
+    args.PushRear("cAnalyze_Brainstorm_SynchronousVsContinuous");
 
-      args.PushRear("-c");
-      args.PushRear(config_dir + "/avida.cfg");
+    args.PushRear("-c");
+    args.PushRear(config_dir + "/avida.cfg");
 
-      args.PushRear("-set");
-      args.PushRear("ANALYZE_FILE");
-      args.PushRear(config_dir + "/analyze.cfg");
+    args.PushRear("-set");
+    args.PushRear("ANALYZE_FILE");
+    args.PushRear(config_dir + "/analyze.cfg");
 
-      /* Run Avida. {{{4 */
-      if(true){
-        cout << "------ Starting Avida run." << endl;
+    /* Run Avida. {{{4 */
+    if(true){
+      cout << "------ Starting Avida run." << endl;
 
-        cWorld *world = new cWorld(cAvidaConfig::LoadWithArgs(args));
-        if(!world){
-          ERROR("Couldn't instantiate cWorld -");
-          return;
-        }
-        cAvidaDriver* driver = new cDefaultAnalyzeDriver(world, false);
-        if(!driver){
-          ERROR("Couldn't instantiate cDefaultAnalyzeDriver -");
-          return;
-        }
+      cAvidaConfig* cfg = new cAvidaConfig();
+      Avida::ProcessArgs(args, cfg);
+      cWorld *world = new cWorld(cfg);
+      if(!world){
+        ERROR("Couldn't instantiate cWorld -");
+        return;
+      }
+      cAvidaDriver* driver = new cDefaultAnalyzeDriver(world, false);
+      if(!driver){
+        ERROR("Couldn't instantiate cDefaultAnalyzeDriver -");
+        return;
+      }
 
-        driver->Run();
+      driver->Run();
 
-        //if(false){
-        //  cAnalyze& a = world->GetAnalyze();
-        //  a.RunFile("/Users/kaben/Projects/Software/Avida/svk/avida-extras/source/testsuites/nAnalyze/Regression/Ticket1_/config/analyze.cfg");
-        //}
+      //if(false){
+      //  cAnalyze& a = world->GetAnalyze();
+      //  a.RunFile("/Users/kaben/Projects/Software/Avida/svk/avida-extras/source/testsuites/nAnalyze/Regression/Ticket1_/config/analyze.cfg");
+      //}
 
-        delete driver; driver=0;
-        // note: driver deletes world deletes config.
+      delete driver; driver=0;
+      // note: driver deletes world deletes config.
 
-        cout << "------ Finished Avida run." << endl;
-      }
+      cout << "------ Finished Avida run." << endl;
     }
-    cAddTestSuite t("cAnalyze_Regression_Ticket1_", test);
   }
-  // }}}1
+  cAddTestSuite t("cAnalyze_Regression_Ticket1_", testsuite);
+}
+// }}}1
 /* Unit tests. {{{1 */
-  /* cAnalyze_UnitTest_HelloWorld {{{2 */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cAnalyze_UnitTest_HelloWorld", test);
+/* cAnalyze_UnitTest_cAvidaConfigDestruction {{{2 */
+namespace cAnalyze_UnitTest_cAvidaConfigDestruction {
+  void testsuite(cTestSettings &settings){
+    cout << "XXX This is a test demo. It needs filling-in. @kgn" << endl;
+    /* Make sure testing is working with successes and failures. @kgn */
+
+    cAvidaConfig* cfg = new cAvidaConfig();
+    delete cfg;
   }
+  cAddTestSuite t("cAnalyze_UnitTest_cAvidaConfigDestruction", testsuite);
+}
 
-  /* cAnalyze_UnitTest_cAvidaConfigDestruction {{{2 */
-  namespace UnitTest_cAvidaConfigDestruction {
-    void test(cTestSettings &settings){
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-
-      cAvidaConfig* cfg = new cAvidaConfig();
-      delete cfg;
+/* cAnalyze_UnitTest_Destructor {{{2 */
+namespace cAnalyze_UnitTest_Destructor {
+  void testsuite(cTestSettings &settings){
+    if(!settings.HasSetting("KnownIssues")){
+      SKIP("Skipping test because KnownIssue is not enabled");
+      ERROR("FIXME at kgn : Known Issue - this test triggers an abrupt exit -");
+      return;
     }
-    cAddTestSuite t("cAnalyze_UnitTest_cAvidaConfigDestruction", test);
-  }
+    cout << "FIXME : interim test. I'm trying to track-down" << endl;
+    cout << "bad destruction of cWorld. When I figure out" << endl;
+    cout << "what's wrong, move this test to reflect the" << endl;
+    cout << "source of the bug. @kgn" << endl;
+    cout << "XXX This is a test demo. It needs filling-in. @kgn" << endl;
 
-  /* cAnalyze_UnitTest_Destructor {{{2 */
-  namespace UnitTest_Destructor {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("KnownIssues")){
-        ERROR("kgn at FIXME : Skipping Known Issue - this test triggers an abrupt exit -");
-        return;
-      }
-      cout << "FIXME : interim test. I'm trying to track-down" << endl;
-      cout << "bad destruction of cWorld. When I figure out" << endl;
-      cout << "what's wrong, move this test to reflect the" << endl;
-      cout << "source of the bug. @kgn" << endl;
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+    char * argv[] = {
+      "cAnalyze_UnitTest_Destructor",
+      "-c", "gcs_avida.cfg",
+    };
+    int argc = sizeof(argv)/sizeof(char *);
 
-      char * argv[] = {
-        "cAnalyze_UnitTest_Destructor",
-        "-c", "gcs_avida.cfg",
-      };
-      int argc = sizeof(argv)/sizeof(char *);
+    cout << "argc : " << argc << endl;
 
-      cout << "argc : " << argc << endl;
+    cAvidaConfig* cfg = new cAvidaConfig();
+    Avida::ProcessCmdLineArgs(argc, argv, cfg);
+    cWorld *world = new cWorld(cfg);
+    cDriverManager::Initialize();
+    cAvidaDriver* driver = NULL;
 
-      cDriverManager::Initialize();
-      cWorld *world = new cWorld(
-        cAvidaConfig::LoadWithCmdLineArgs(argc, argv)
-      );
-      cAvidaDriver* driver = NULL;
+    if (world->GetConfig().ANALYZE_MODE.Get() > 0) {
+      driver = new cDefaultAnalyzeDriver(world, (world->GetConfig().ANALYZE_MODE.Get() == 2));
+    } else {
+      driver = new cDefaultRunDriver(world);
+    }
 
-      if (world->GetConfig().ANALYZE_MODE.Get() > 0) {
-        driver = new cDefaultAnalyzeDriver(world, (world->GetConfig().ANALYZE_MODE.Get() == 2));
-      } else {
-        driver = new cDefaultRunDriver(world);
-      }
-  
-      driver->Run();
+    driver->Run();
 
-      /*
-      FIXME : driver currently deletes world.
-      */
-      delete driver;
-      //delete world;
-    }
-    cAddTestSuite t("cAnalyze_UnitTest_Destructor", test);
+    /*
+    FIXME : driver currently deletes world.
+    */
+    delete driver;
+    //delete world;
   }
+  cAddTestSuite t("cAnalyze_UnitTest_Destructor", testsuite);
+}
 
-  /* cAnalyze_UnitTest_Archiving {{{2 */
-  namespace UnitTest_Archiving {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("Template")){
-        cout << "XXX Skipping Template test." << endl;
-        return;
-      }
+/* cAnalyze_UnitTest_Archiving {{{2 */
+namespace cAnalyze_UnitTest_Archiving {
+  void testsuite(cTestSettings &settings){
+    if(!settings.HasSetting("TemplateTests")){
+      SKIP("Skipping : TemplateTests not enabled");
+      return;
+    }
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      //std::string filename("./cAnalyze_basic_serialization.xml");
+    cout << "XXX This is a test demo. It needs filling-in. @kgn" << endl;
+    //std::string filename("./cAnalyze_basic_serialization.xml");
 
-      //{
-      //  cAnalyze o();
-      //  save_stuff<>(o, filename.c_str());
-      //}
+    //{
+    //  cAnalyze o();
+    //  nAnalyze::save_stuff<>(o, filename.c_str());
+    //}
 
-      //{
-      //  cAnalyze o;
+    //{
+    //  cAnalyze o;
 
-      //  restore_stuff<>(o, filename.c_str());
-      //  TEST(true);
-      //}
+    //  nAnalyze::restore_stuff<>(o, filename.c_str());
+    //  TEST(true);
+    //}
 
-      //std::remove(filename.c_str());
+    //std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
-    }
-    cAddTestSuite t("cAnalyze_UnitTest_Archiving", test);
   }
+  cAddTestSuite t("cAnalyze_UnitTest_Archiving", testsuite);
+}
 
-  /* cAnalyze_UnitTest_SynchronousVsContinuous_temporary_next_id {{{2 */
-  namespace UnitTest_SynchronousVsContinuous_temporary_next_id {
-    void set_batch(
-      cAnalyze& a,
-      int batch
-    ){
-      cString command = cStringUtil::Stringf(
-        "SET_BATCH %d",
-        batch
-      );
-      a.Send(command);
+/* cAnalyze_UnitTest_SynchronousVsContinuous_temporary_next_id {{{2 */
+namespace cAnalyze_UnitTest_SynchronousVsContinuous_temporary_next_id {
+  void set_batch(
+    cAnalyze& a,
+    int batch
+  ){
+    cString command = cStringUtil::Stringf(
+      "SET_BATCH %d",
+      batch
+    );
+    a.Send(command);
+  }
+  void load_organism(
+    cAnalyze& a,
+    cString s
+  ){
+    cString command("LOAD_ORGANISM ");
+    a.Send(command + s);
+  }
+  void compete(
+    cAnalyze& a,
+    int batch_size,
+    int batch_from,
+    int batch_to,
+    int initial_next_id,
+    int initial_next_update
+  ){
+    cString command = cStringUtil::Stringf(
+      "COMPETE %d %d %d %d %d",
+      batch_size,
+      batch_from,
+      batch_to,
+      initial_next_id,
+      initial_next_update
+    );
+    a.Send(command);
+  }
+  void testsuite(cTestSettings &settings){
+    /* Check settings. {{{3 */
+    if(!settings.HasSetting("KnownIssues")){
+      SKIP("Skipping test because KnownIssue is not enabled");
+      ERROR("FIXME at kgn : Known Issue - this test triggers an abrupt exit -");
+      return;
     }
-    void load_organism(
-      cAnalyze& a,
-      cString s
+    if(
+      (!settings.HasSetting("DevelBase"))
+      ||
+      (settings.Setting("DevelBase") == "")
     ){
-      cString command("LOAD_ORGANISM ");
-      a.Send(command + s);
+      SKIP("Skipping : DevelBase not set");
+      return;
     }
-    void compete(
-      cAnalyze& a,
-      int batch_size,
-      int batch_from,
-      int batch_to,
-      int initial_next_id,
-      int initial_next_update
+    if(
+      (!settings.HasSetting("ExtrasBase"))
+      ||
+      (settings.Setting("ExtrasBase") == "")
     ){
-      cString command = cStringUtil::Stringf(
-        "COMPETE %d %d %d %d %d",
-        batch_size,
-        batch_from,
-        batch_to,
-        initial_next_id,
-        initial_next_update
-      );
-      a.Send(command);
+      SKIP("Skipping : ExtrasBase not set");
+      return;
     }
-    void test(cTestSettings &settings){
-      /* Check settings. {{{3 */
-      if(!settings.HasSetting("KnownIssues")){
-        ERROR("kgn at FIXME : Skipping Known Issue - this test triggers an abrupt exit -");
-        return;
-      }
-      if(
-        (!settings.HasSetting("DevelBase"))
-        ||
-        (settings.Setting("DevelBase") == "")
-      ){
-        cout << "XXX Skipping : DevelBase not set." << endl;
-        return;
-      }
-      if(
-        (!settings.HasSetting("ExtrasBase"))
-        ||
-        (settings.Setting("ExtrasBase") == "")
-      ){
-        cout << "XXX Skipping : ExtrasBase not set." << endl;
-        return;
-      }
 
-      {
-        cDriverManager::Initialize();
-        cStringList args;
+    {
+      cDriverManager::Initialize();
+      cStringList args;
 
-        cString config_dir
-        = settings.Setting("DevelBase")
-        + "/support/config";
+      cString config_dir
+      = settings.Setting("DevelBase")
+      + "/support/config";
 
-        cString local_config_dir
-        = settings.Setting("ExtrasBase")
-        + "/source/testsuites/nAnalyze/Brainstorm/SynchronousVsContinuous/config";
+      cString local_config_dir
+      = settings.Setting("ExtrasBase")
+      + "/source/testsuites/nAnalyze/Brainstorm/SynchronousVsContinuous/config";
 
-        cString data_dir
-        = settings.Setting("ExtrasBase")
-        + "/source/testsuites/nAnalyze/Brainstorm/SynchronousVsContinuous/data";
+      cString data_dir
+      = settings.Setting("ExtrasBase")
+      + "/source/testsuites/nAnalyze/Brainstorm/SynchronousVsContinuous/data";
 
-        args.PushRear("cAnalyze_Brainstorm_SynchronousVsContinuous");
+      args.PushRear("cAnalyze_Brainstorm_SynchronousVsContinuous");
 
-        args.PushRear("-c");
-        args.PushRear(config_dir + "/avida.cfg");
+      args.PushRear("-c");
+      args.PushRear(config_dir + "/avida.cfg");
 
-        args.PushRear("-s");
-        args.PushRear("100");
+      args.PushRear("-s");
+      args.PushRear("100");
 
-        args.PushRear("-set");
-        args.PushRear("EVENT_FILE");
-        args.PushRear(local_config_dir + "/events.cfg");
+      args.PushRear("-set");
+      args.PushRear("EVENT_FILE");
+      args.PushRear(local_config_dir + "/events.cfg");
 
-        args.PushRear("-set");
-        args.PushRear("DATA_DIR");
-        args.PushRear(data_dir);
+      args.PushRear("-set");
+      args.PushRear("DATA_DIR");
+      args.PushRear(data_dir);
 
-        if(true){
-          cout << "------ Starting Avida analysis." << endl;
-          /* Setup of Analyze mode. {{{4 */
-          cWorld *world = new cWorld(cAvidaConfig::LoadWithArgs(args));
-          if(!world){
-            ERROR("Couldn't instantiate cWorld -");
-            return;
-          }
-          cAvidaDriver* driver = new cDefaultAnalyzeDriver(world, false);
-          if(!driver){
-            ERROR("Couldn't instantiate cDefaultAnalyzeDriver -");
-            return;
-          }
+      if(true){
+        cout << "------ Starting Avida analysis." << endl;
+        /* Setup of Analyze mode. {{{4 */
+        cAvidaConfig* cfg = new cAvidaConfig();
+        Avida::ProcessArgs(args, cfg);
+        cWorld *world = new cWorld(cfg);
+        if(!world){
+          ERROR("Couldn't instantiate cWorld -");
+          return;
+        }
+        cAvidaDriver* driver = new cDefaultAnalyzeDriver(world, false);
+        if(!driver){
+          ERROR("Couldn't instantiate cDefaultAnalyzeDriver -");
+          return;
+        }
 
-          int batch_size;
-          int batch_from;
-          int batch_to;
-          int initial_next_id;
-          int initial_next_update;
+        int batch_size;
+        int batch_from;
+        int batch_to;
+        int initial_next_id;
+        int initial_next_update;
 
-          cAnalyze& a = world->GetAnalyze();
+        cAnalyze& a = world->GetAnalyze();
 
-          a.Send("VERBOSE");
+        a.Send("VERBOSE");
 
-          /* Verify temporary_next_id is initially zero. */
-          TEST(0 == a.GetTempNextID());
-          TEST(0 == a.GetTempNextUpdate());
+        /* Verify temporary_next_id is initially zero. */
+        TEST(0 == a.GetTempNextID());
+        TEST(0 == a.GetTempNextUpdate());
 
-          /* Verify initial_next_id == -1 leaves temporary_next_id unchanged. */
-          /* Verify temporary_next_id is incremented "batch_size" times. */
-          {
-            batch_size = 20;
-            batch_from = 0;
-            batch_to = 1;
-            initial_next_id = -1;
-            initial_next_update = -1;
+        /* Verify initial_next_id == -1 leaves temporary_next_id unchanged. */
+        /* Verify temporary_next_id is incremented "batch_size" times. */
+        {
+          batch_size = 20;
+          batch_from = 0;
+          batch_to = 1;
+          initial_next_id = -1;
+          initial_next_update = -1;
 
-            set_batch(a, batch_from);
-            a.Send("PURGE_BATCH");
-            load_organism(a, local_config_dir + "/default-classic.org");
-            a.Send("RECALCULATE");
-            set_batch(a, batch_to);
-            a.Send("PURGE_BATCH");
-            compete(a, batch_size, batch_from, batch_to, initial_next_id, initial_next_update);
+          set_batch(a, batch_from);
+          a.Send("PURGE_BATCH");
+          load_organism(a, local_config_dir + "/default-classic.org");
+          a.Send("RECALCULATE");
+          set_batch(a, batch_to);
+          a.Send("PURGE_BATCH");
+          compete(a, batch_size, batch_from, batch_to, initial_next_id, initial_next_update);
 
-            TEST(20 == a.GetTempNextID());
-            TEST(1 == a.GetTempNextUpdate());
-          }
+          TEST(20 == a.GetTempNextID());
+          TEST(1 == a.GetTempNextUpdate());
+        }
 
-          /* Verify temporary_next_id is now 20. */
-          /* Verify initial_next_id == -1 leaves temporary_next_id unchanged. */
-          /* Verify temporary_next_id is incremented "batch_size" times. */
-          {
-            batch_size = 20;
-            batch_from = 0;
-            batch_to = 1;
-            initial_next_id = -1;
-            initial_next_update = -1;
+        /* Verify temporary_next_id is now 20. */
+        /* Verify initial_next_id == -1 leaves temporary_next_id unchanged. */
+        /* Verify temporary_next_id is incremented "batch_size" times. */
+        {
+          batch_size = 20;
+          batch_from = 0;
+          batch_to = 1;
+          initial_next_id = -1;
+          initial_next_update = -1;
 
-            TEST(20 == a.GetTempNextID());
-            TEST(1 == a.GetTempNextUpdate());
+          TEST(20 == a.GetTempNextID());
+          TEST(1 == a.GetTempNextUpdate());
 
-            set_batch(a, batch_from);
-            a.Send("PURGE_BATCH");
-            load_organism(a, local_config_dir + "/default-classic.org");
-            a.Send("RECALCULATE");
-            set_batch(a, batch_to);
-            a.Send("PURGE_BATCH");
-            compete(a, batch_size, batch_from, batch_to, initial_next_id, initial_next_update);
+          set_batch(a, batch_from);
+          a.Send("PURGE_BATCH");
+          load_organism(a, local_config_dir + "/default-classic.org");
+          a.Send("RECALCULATE");
+          set_batch(a, batch_to);
+          a.Send("PURGE_BATCH");
+          compete(a, batch_size, batch_from, batch_to, initial_next_id, initial_next_update);
 
-            TEST(40 == a.GetTempNextID());
-            TEST(2 == a.GetTempNextUpdate());
-          }
+          TEST(40 == a.GetTempNextID());
+          TEST(2 == a.GetTempNextUpdate());
+        }
 
-          /* Verify temporary_next_id is now 40. */
-          /* Verify initial_next_id == 43 alters temporary_next_id. */
-          /* Verify temporary_next_id is incremented "batch_size" times. */
-          {
-            batch_size = 20;
-            batch_from = 0;
-            batch_to = 1;
-            initial_next_id = 43;
-            initial_next_update = 3;
+        /* Verify temporary_next_id is now 40. */
+        /* Verify initial_next_id == 43 alters temporary_next_id. */
+        /* Verify temporary_next_id is incremented "batch_size" times. */
+        {
+          batch_size = 20;
+          batch_from = 0;
+          batch_to = 1;
+          initial_next_id = 43;
+          initial_next_update = 3;
 
-            TEST(40 == a.GetTempNextID());
-            TEST(2 == a.GetTempNextUpdate());
+          TEST(40 == a.GetTempNextID());
+          TEST(2 == a.GetTempNextUpdate());
 
-            set_batch(a, batch_from);
-            a.Send("PURGE_BATCH");
-            load_organism(a, local_config_dir + "/default-classic.org");
-            a.Send("RECALCULATE");
-            set_batch(a, batch_to);
-            a.Send("PURGE_BATCH");
-            compete(a, batch_size, batch_from, batch_to, initial_next_id, initial_next_update);
+          set_batch(a, batch_from);
+          a.Send("PURGE_BATCH");
+          load_organism(a, local_config_dir + "/default-classic.org");
+          a.Send("RECALCULATE");
+          set_batch(a, batch_to);
+          a.Send("PURGE_BATCH");
+          compete(a, batch_size, batch_from, batch_to, initial_next_id, initial_next_update);
 
-            TEST(63 == a.GetTempNextID());
-            TEST(4 == a.GetTempNextUpdate());
-          }
+          TEST(63 == a.GetTempNextID());
+          TEST(4 == a.GetTempNextUpdate());
+        }
 
-          delete driver; driver=0;
-          // note: driver deletes world deletes config.
-          
-          cout << "------ Finished Avida analysis." << endl;
-        }
+        delete driver; driver=0;
+        // note: driver deletes world deletes config.
+        
+        cout << "------ Finished Avida analysis." << endl;
       }
     }
-    cAddTestSuite t("cAnalyze_UnitTest_SynchronousVsContinuous_temporary_next_id", test);
   }
-
-  // }}}1
-  /*
-  This function does nothing;
-  but if the compiler sees that this function is called, then the
-  compiler will also connect the above tests to the testing library.
-  */
-  void PhysicalLink(){}
+  cAddTestSuite t("cAnalyze_UnitTest_SynchronousVsContinuous_temporary_next_id", testsuite);
 }

Modified: extras/source/testsuites/nAnalyzeGenotype.cpp
===================================================================
--- extras/source/testsuites/nAnalyzeGenotype.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nAnalyzeGenotype.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -1,7 +1,9 @@
 #include "cAnalyzeGenotype.h"
 
+#include "Avida.h"
 #include "cDriverManager.h"
 #include "cHardwareManager.h"
+#include "cTestingWorldDriver.h"
 #include "cTestLib.h"
 #include "cWorld.h"
 
@@ -12,1004 +14,981 @@
 using namespace std;
 
 /* Tests. */
-namespace nAnalyzeGenotype {
 /* Brainstorms. {{{1 */
-  /* cAnalyzeGenotype_Brainstorm_HelloWorld {{{2 */
-  namespace Brainstorm_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cAnalyzeGenotype_Brainstorm_HelloWorld", test);
-  }
-  /* cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink {{{2 */
+/* XXX Questions: {{{3
+- Should I add Verify() or Okay() functions?
 
-  /* XXX Questions: {{{3
-  - Should I add Verify() or Okay() functions?
+- We have copy constructor semantics in cAnalyzeGenotype. What does
+  this mean for semantics of cAnalyzeGenotypeLink operations?
+  - I think it means we have possible automatic inconsistency:
 
-  - We have copy constructor semantics in cAnalyzeGenotype. What does
-    this mean for semantics of cAnalyzeGenotypeLink operations?
-    - I think it means we have possible automatic inconsistency:
+    we can have two distinct cAnalyzeGenotype instances representing
+    the same genotype (i.e., same ID). In that case we'll have
+    inconsistency in a lineage tree containing both instances.
 
-      we can have two distinct cAnalyzeGenotype instances representing
-      the same genotype (i.e., same ID). In that case we'll have
-      inconsistency in a lineage tree containing both instances.
+  - If we assume that no batch contains multiple instances of the same
+    genotype, we have no inconsistency.
 
-    - If we assume that no batch contains multiple instances of the same
-      genotype, we have no inconsistency.
+    Do we have any batch operations which could produce multiple
+    instances of the same genotype?
+*/
 
-      Do we have any batch operations which could produce multiple
-      instances of the same genotype?
-  */
+/* XXX Done: {{{3
+- Verify cAnalyzeGenotype destructor properly destroys
+  cAnalyzeGenotypeLink.
+- Verify cAnalyzeGenotype constructor properly initializes
+  cAnalyzeGenotypeLink.
+- Verify cAnalyzeGenotype::LinkParent(0).
+- Verify that adding same child twice does not create two entries in
+  child list.
+- Write / verify cAnalyzeGenotypeLink constructor.
+- Write / verify cAnalyzeGenotypeLink::SetParent().
+- Write / verify cAnalyzeGenotypeLink::GetParent().
+- Write / verify cAnalyzeGenotypeLink::GetChildList().
+- Write / verify cAnalyzeGenotypeLink::ClearChildren().
+- Write / verify cAnalyzeGenotypeLink::FindChild().
+- Write / verify cAnalyzeGenotypeLink::RemoveChild().
+- Write / verify cAnalyzeGenotypeLink::AddChild().
+- Write / verify cAnalyzeGenotype::GetLink().
+- Write / verify cAnalyzeGenotype::LinkParent().
+- Write / verify cAnalyzeGenotype::LinkChild().
+- Write / verify cAnalyzeGenotype::UnlinkParent().
+- Write / verify cAnalyzeGenotype::UnlinkChildren().
+- Write / verify cAnalyzeGenotype::Unlink().
+- Write / verify cAnalyzeGenotype::GetParent().
+- Write / verify cAnalyzeGenotype::HasChild().
+- Write / verify cAnalyzeGenotype::UnlinkChild().
+- Write / verify cAnalyzeGenotype::GetChildList().
+*/
 
-  /* XXX Done: {{{3
-  - Verify cAnalyzeGenotype destructor properly destroys
-    cAnalyzeGenotypeLink.
-  - Verify cAnalyzeGenotype constructor properly initializes
-    cAnalyzeGenotypeLink.
-  - Verify cAnalyzeGenotype::LinkParent(0).
-  - Verify that adding same child twice does not create two entries in
-    child list.
-  - Write / verify cAnalyzeGenotypeLink constructor.
-  - Write / verify cAnalyzeGenotypeLink::SetParent().
-  - Write / verify cAnalyzeGenotypeLink::GetParent().
-  - Write / verify cAnalyzeGenotypeLink::GetChildList().
-  - Write / verify cAnalyzeGenotypeLink::ClearChildren().
-  - Write / verify cAnalyzeGenotypeLink::FindChild().
-  - Write / verify cAnalyzeGenotypeLink::RemoveChild().
-  - Write / verify cAnalyzeGenotypeLink::AddChild().
-  - Write / verify cAnalyzeGenotype::GetLink().
-  - Write / verify cAnalyzeGenotype::LinkParent().
-  - Write / verify cAnalyzeGenotype::LinkChild().
-  - Write / verify cAnalyzeGenotype::UnlinkParent().
-  - Write / verify cAnalyzeGenotype::UnlinkChildren().
-  - Write / verify cAnalyzeGenotype::Unlink().
-  - Write / verify cAnalyzeGenotype::GetParent().
-  - Write / verify cAnalyzeGenotype::HasChild().
-  - Write / verify cAnalyzeGenotype::UnlinkChild().
-  - Write / verify cAnalyzeGenotype::GetChildList().
+/* {{{3 */
+namespace cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink {
+  /*
+  This is a convenience function to instantiate cAnalyzeGenotype
+  instances.
   */
-
-  /* {{{3 */
-  namespace Brainstorm_cAnalyzeGenotypeLink {
+  cAnalyzeGenotype AGFactory(cWorld &world, cString symbol_string){
+    return cAnalyzeGenotype(&world, symbol_string, world.GetHardwareManager().GetInstSet());
+  }
+  void testsuite(cTestSettings &settings){
+    if(!settings.HasSetting("DevelBase") || (settings.Setting("DevelBase") == "")){
+      SKIP("Skipping : DevelBase not set");
+      return;
+    }
+    if(!settings.HasSetting("ExtrasBase") || (settings.Setting("ExtrasBase") == "")){
+      SKIP("Skipping : ExtrasBase not set");
+      return;
+    }
+    /* Common test setup. {{{3 */
     /*
-    This is a convenience function to instantiate cAnalyzeGenotype
-    instances.
+    cWorld instance to give us a working context.
     */
-    cAnalyzeGenotype AGFactory(cWorld &world, cString symbol_string){
-      return cAnalyzeGenotype(&world, symbol_string, world.GetHardwareManager().GetInstSet());
-    }
-    void test(){
-      /* Common test setup. {{{3 */
-      /*
-      cWorld instance to give us a working context.
-      */
-      char * argv[] = { "cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink", };
-      int argc = sizeof(argv)/sizeof(char *);
+    char * argv[] = { "cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink", };
+    int argc = sizeof(argv)/sizeof(char *);
 
-      cDriverManager::Initialize();
-      cWorld *world = new cWorld( cAvidaConfig::LoadWithCmdLineArgs(argc, argv));
+    cDriverManager::Initialize();
+    cAvidaConfig* cfg = new cAvidaConfig();
+    Avida::ProcessCmdLineArgs(argc, argv, cfg);
+    cWorld *world = new cWorld(cfg);      
 
-      /* Test very basic cAnalyzeGenotypeLink functions GetChildList(), SetParent(), FindChild(), RemoveChild(), ClearChildren(). {{{3 */
-      if(true){
-        cAnalyzeGenotype
-          p(AGFactory(*world, "ccc")),
-          f1a(AGFactory(*world, "ccc")),
-          f1b(AGFactory(*world, "ccc")),
-          f2a(AGFactory(*world, "ccc")),
-          f2b(AGFactory(*world, "ccc"));
+    /* Test very basic cAnalyzeGenotypeLink functions GetChildList(), SetParent(), FindChild(), RemoveChild(), ClearChildren(). {{{3 */
+    cout << "XXX Brainstorm_cAnalyzeGenotypeLink checkpoint 1. @kgn" << endl;
+    if(true){
+      cAnalyzeGenotype
+        p(AGFactory(*world, "ccc")),
+        f1a(AGFactory(*world, "ccc")),
+        f1b(AGFactory(*world, "ccc")),
+        f2a(AGFactory(*world, "ccc")),
+        f2b(AGFactory(*world, "ccc"));
 
-        cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
+      cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
 
-        pl.SetParent(0);
+      pl.SetParent(0);
 
-        pl.GetChildList().PushRear(&f1a);
-        f1al.SetParent(&p);
+      pl.GetChildList().PushRear(&f1a);
+      f1al.SetParent(&p);
 
-        pl.GetChildList().PushRear(&f1b);
-        f1bl.SetParent(&p);
+      pl.GetChildList().PushRear(&f1b);
+      f1bl.SetParent(&p);
 
-        f1al.GetChildList().PushRear(&f2a);
-        f2al.SetParent(&f1a);
+      f1al.GetChildList().PushRear(&f2a);
+      f2al.SetParent(&f1a);
 
-        f1al.GetChildList().PushRear(&f2b);
-        f2bl.SetParent(&f1a);
+      f1al.GetChildList().PushRear(&f2b);
+      f2bl.SetParent(&f1a);
 
-        /* 
-        pl should have no parent
-        pl should have children f1a and f1b
-        f1al should have parent p
-        f1al should have children f2a and f2b
-        f1bl should have parent p
-        f1bl should have no children
-        f2al should have parent f1a
-        f2al should have no children
-        f2bl should have parent f1a
-        f2bl should have no children
-        */
-        if(true){
-          TEST(pl.GetParent() == 0);
-          TEST(pl.GetChildList().FindPtr(&p) == 0);
-          TEST(pl.GetChildList().FindPtr(&f1a) == &f1a);
-          TEST(pl.GetChildList().FindPtr(&f1b) == &f1b);
-          TEST(pl.GetChildList().FindPtr(&f2a) == 0);
-          TEST(pl.GetChildList().FindPtr(&f2b) == 0);
+      /* 
+      pl should have no parent
+      pl should have children f1a and f1b
+      f1al should have parent p
+      f1al should have children f2a and f2b
+      f1bl should have parent p
+      f1bl should have no children
+      f2al should have parent f1a
+      f2al should have no children
+      f2bl should have parent f1a
+      f2bl should have no children
+      */
+      if(true){
+        TEST(pl.GetParent() == 0);
+        TEST(pl.GetChildList().FindPtr(&p) == 0);
+        TEST(pl.GetChildList().FindPtr(&f1a) == &f1a);
+        TEST(pl.GetChildList().FindPtr(&f1b) == &f1b);
+        TEST(pl.GetChildList().FindPtr(&f2a) == 0);
+        TEST(pl.GetChildList().FindPtr(&f2b) == 0);
 
-          TEST(f1al.GetParent() == &p);
-          TEST(f1al.GetChildList().FindPtr(&p) == 0);
-          TEST(f1al.GetChildList().FindPtr(&f1a) == 0);
-          TEST(f1al.GetChildList().FindPtr(&f1b) == 0);
-          TEST(f1al.GetChildList().FindPtr(&f2a) == &f2a);
-          TEST(f1al.GetChildList().FindPtr(&f2b) == &f2b);
+        TEST(f1al.GetParent() == &p);
+        TEST(f1al.GetChildList().FindPtr(&p) == 0);
+        TEST(f1al.GetChildList().FindPtr(&f1a) == 0);
+        TEST(f1al.GetChildList().FindPtr(&f1b) == 0);
+        TEST(f1al.GetChildList().FindPtr(&f2a) == &f2a);
+        TEST(f1al.GetChildList().FindPtr(&f2b) == &f2b);
 
-          TEST(f1bl.GetParent() == &p);
-          TEST(f1bl.GetChildList().FindPtr(&p) == 0);
-          TEST(f1bl.GetChildList().FindPtr(&f1a) == 0);
-          TEST(f1bl.GetChildList().FindPtr(&f1b) == 0);
-          TEST(f1bl.GetChildList().FindPtr(&f2a) == 0);
-          TEST(f1bl.GetChildList().FindPtr(&f2b) == 0);
+        TEST(f1bl.GetParent() == &p);
+        TEST(f1bl.GetChildList().FindPtr(&p) == 0);
+        TEST(f1bl.GetChildList().FindPtr(&f1a) == 0);
+        TEST(f1bl.GetChildList().FindPtr(&f1b) == 0);
+        TEST(f1bl.GetChildList().FindPtr(&f2a) == 0);
+        TEST(f1bl.GetChildList().FindPtr(&f2b) == 0);
 
-          TEST(f2al.GetParent() == &f1a);
-          TEST(f2al.GetChildList().FindPtr(&p) == 0);
-          TEST(f2al.GetChildList().FindPtr(&f1a) == 0);
-          TEST(f2al.GetChildList().FindPtr(&f1b) == 0);
-          TEST(f2al.GetChildList().FindPtr(&f2a) == 0);
-          TEST(f2al.GetChildList().FindPtr(&f2b) == 0);
+        TEST(f2al.GetParent() == &f1a);
+        TEST(f2al.GetChildList().FindPtr(&p) == 0);
+        TEST(f2al.GetChildList().FindPtr(&f1a) == 0);
+        TEST(f2al.GetChildList().FindPtr(&f1b) == 0);
+        TEST(f2al.GetChildList().FindPtr(&f2a) == 0);
+        TEST(f2al.GetChildList().FindPtr(&f2b) == 0);
 
-          TEST(f2bl.GetParent() == &f1a);
-          TEST(f2bl.GetChildList().FindPtr(&p) == 0);
-          TEST(f2bl.GetChildList().FindPtr(&f1a) == 0);
-          TEST(f2bl.GetChildList().FindPtr(&f1b) == 0);
-          TEST(f2bl.GetChildList().FindPtr(&f2a) == 0);
-          TEST(f2bl.GetChildList().FindPtr(&f2b) == 0);
-        }
+        TEST(f2bl.GetParent() == &f1a);
+        TEST(f2bl.GetChildList().FindPtr(&p) == 0);
+        TEST(f2bl.GetChildList().FindPtr(&f1a) == 0);
+        TEST(f2bl.GetChildList().FindPtr(&f1b) == 0);
+        TEST(f2bl.GetChildList().FindPtr(&f2a) == 0);
+        TEST(f2bl.GetChildList().FindPtr(&f2b) == 0);
+      }
 
-        /* 
-        pl should have no parent
-        pl should have children f1a and f1b
-        f1al should have parent p
-        f1al should have children f2a and f2b
-        f1bl should have parent p
-        f1bl should have no children
-        f2al should have parent f1a
-        f2al should have no children
-        f2bl should have parent f1a
-        f2bl should have no children
-        */
-        {
-          TEST(pl.GetParent() == 0);
-          TEST(pl.FindChild(&p) == 0);
-          TEST(pl.FindChild(&f1a) == &f1a);
-          TEST(pl.FindChild(&f1b) == &f1b);
-          TEST(pl.FindChild(&f2a) == 0);
-          TEST(pl.FindChild(&f2b) == 0);
+      /* 
+      pl should have no parent
+      pl should have children f1a and f1b
+      f1al should have parent p
+      f1al should have children f2a and f2b
+      f1bl should have parent p
+      f1bl should have no children
+      f2al should have parent f1a
+      f2al should have no children
+      f2bl should have parent f1a
+      f2bl should have no children
+      */
+      {
+        TEST(pl.GetParent() == 0);
+        TEST(pl.FindChild(&p) == 0);
+        TEST(pl.FindChild(&f1a) == &f1a);
+        TEST(pl.FindChild(&f1b) == &f1b);
+        TEST(pl.FindChild(&f2a) == 0);
+        TEST(pl.FindChild(&f2b) == 0);
 
-          TEST(f1al.GetParent() == &p);
-          TEST(f1al.FindChild(&p) == 0);
-          TEST(f1al.FindChild(&f1a) == 0);
-          TEST(f1al.FindChild(&f1b) == 0);
-          TEST(f1al.FindChild(&f2a) == &f2a);
-          TEST(f1al.FindChild(&f2b) == &f2b);
+        TEST(f1al.GetParent() == &p);
+        TEST(f1al.FindChild(&p) == 0);
+        TEST(f1al.FindChild(&f1a) == 0);
+        TEST(f1al.FindChild(&f1b) == 0);
+        TEST(f1al.FindChild(&f2a) == &f2a);
+        TEST(f1al.FindChild(&f2b) == &f2b);
 
-          TEST(f1bl.GetParent() == &p);
-          TEST(f1bl.FindChild(&p) == 0);
-          TEST(f1bl.FindChild(&f1a) == 0);
-          TEST(f1bl.FindChild(&f1b) == 0);
-          TEST(f1bl.FindChild(&f2a) == 0);
-          TEST(f1bl.FindChild(&f2b) == 0);
+        TEST(f1bl.GetParent() == &p);
+        TEST(f1bl.FindChild(&p) == 0);
+        TEST(f1bl.FindChild(&f1a) == 0);
+        TEST(f1bl.FindChild(&f1b) == 0);
+        TEST(f1bl.FindChild(&f2a) == 0);
+        TEST(f1bl.FindChild(&f2b) == 0);
 
-          TEST(f2al.GetParent() == &f1a);
-          TEST(f2al.FindChild(&p) == 0);
-          TEST(f2al.FindChild(&f1a) == 0);
-          TEST(f2al.FindChild(&f1b) == 0);
-          TEST(f2al.FindChild(&f2a) == 0);
-          TEST(f2al.FindChild(&f2b) == 0);
+        TEST(f2al.GetParent() == &f1a);
+        TEST(f2al.FindChild(&p) == 0);
+        TEST(f2al.FindChild(&f1a) == 0);
+        TEST(f2al.FindChild(&f1b) == 0);
+        TEST(f2al.FindChild(&f2a) == 0);
+        TEST(f2al.FindChild(&f2b) == 0);
 
-          TEST(f2bl.GetParent() == &f1a);
-          TEST(f2bl.FindChild(&p) == 0);
-          TEST(f2bl.FindChild(&f1a) == 0);
-          TEST(f2bl.FindChild(&f1b) == 0);
-          TEST(f2bl.FindChild(&f2a) == 0);
-          TEST(f2bl.FindChild(&f2b) == 0);
-        }
+        TEST(f2bl.GetParent() == &f1a);
+        TEST(f2bl.FindChild(&p) == 0);
+        TEST(f2bl.FindChild(&f1a) == 0);
+        TEST(f2bl.FindChild(&f1b) == 0);
+        TEST(f2bl.FindChild(&f2a) == 0);
+        TEST(f2bl.FindChild(&f2b) == 0);
+      }
 
-        pl.GetChildList().Clear();
-        /* 
-        pl should have no parent
-        pl should have no children
-        f1al should still have parent p
-        f1al should have children f2a and f2b
-        f1bl should still have parent p
-        f1bl should have no children
-        f2al should have parent f1a
-        f2al should have no children
-        f2bl should have parent f1a
-        f2bl should have no children
-        */
-        {
-          TEST(pl.GetParent() == 0);
-          TEST(pl.FindChild(&p) == 0);
-          TEST(pl.FindChild(&f1a) == 0);
-          TEST(pl.FindChild(&f1b) == 0);
-          TEST(pl.FindChild(&f2a) == 0);
-          TEST(pl.FindChild(&f2b) == 0);
+      pl.GetChildList().Clear();
+      /* 
+      pl should have no parent
+      pl should have no children
+      f1al should still have parent p
+      f1al should have children f2a and f2b
+      f1bl should still have parent p
+      f1bl should have no children
+      f2al should have parent f1a
+      f2al should have no children
+      f2bl should have parent f1a
+      f2bl should have no children
+      */
+      {
+        TEST(pl.GetParent() == 0);
+        TEST(pl.FindChild(&p) == 0);
+        TEST(pl.FindChild(&f1a) == 0);
+        TEST(pl.FindChild(&f1b) == 0);
+        TEST(pl.FindChild(&f2a) == 0);
+        TEST(pl.FindChild(&f2b) == 0);
 
-          TEST(f1al.GetParent() == &p);
-          TEST(f1al.FindChild(&p) == 0);
-          TEST(f1al.FindChild(&f1a) == 0);
-          TEST(f1al.FindChild(&f1b) == 0);
-          TEST(f1al.FindChild(&f2a) == &f2a);
-          TEST(f1al.FindChild(&f2b) == &f2b);
+        TEST(f1al.GetParent() == &p);
+        TEST(f1al.FindChild(&p) == 0);
+        TEST(f1al.FindChild(&f1a) == 0);
+        TEST(f1al.FindChild(&f1b) == 0);
+        TEST(f1al.FindChild(&f2a) == &f2a);
+        TEST(f1al.FindChild(&f2b) == &f2b);
 
-          TEST(f1bl.GetParent() == &p);
-          TEST(f1bl.FindChild(&p) == 0);
-          TEST(f1bl.FindChild(&f1a) == 0);
-          TEST(f1bl.FindChild(&f1b) == 0);
-          TEST(f1bl.FindChild(&f2a) == 0);
-          TEST(f1bl.FindChild(&f2b) == 0);
+        TEST(f1bl.GetParent() == &p);
+        TEST(f1bl.FindChild(&p) == 0);
+        TEST(f1bl.FindChild(&f1a) == 0);
+        TEST(f1bl.FindChild(&f1b) == 0);
+        TEST(f1bl.FindChild(&f2a) == 0);
+        TEST(f1bl.FindChild(&f2b) == 0);
 
-          TEST(f2al.GetParent() == &f1a);
-          TEST(f2al.FindChild(&p) == 0);
-          TEST(f2al.FindChild(&f1a) == 0);
-          TEST(f2al.FindChild(&f1b) == 0);
-          TEST(f2al.FindChild(&f2a) == 0);
-          TEST(f2al.FindChild(&f2b) == 0);
+        TEST(f2al.GetParent() == &f1a);
+        TEST(f2al.FindChild(&p) == 0);
+        TEST(f2al.FindChild(&f1a) == 0);
+        TEST(f2al.FindChild(&f1b) == 0);
+        TEST(f2al.FindChild(&f2a) == 0);
+        TEST(f2al.FindChild(&f2b) == 0);
 
-          TEST(f2bl.GetParent() == &f1a);
-          TEST(f2bl.FindChild(&p) == 0);
-          TEST(f2bl.FindChild(&f1a) == 0);
-          TEST(f2bl.FindChild(&f1b) == 0);
-          TEST(f2bl.FindChild(&f2a) == 0);
-          TEST(f2bl.FindChild(&f2b) == 0);
-        }
+        TEST(f2bl.GetParent() == &f1a);
+        TEST(f2bl.FindChild(&p) == 0);
+        TEST(f2bl.FindChild(&f1a) == 0);
+        TEST(f2bl.FindChild(&f1b) == 0);
+        TEST(f2bl.FindChild(&f2a) == 0);
+        TEST(f2bl.FindChild(&f2b) == 0);
+      }
 
-        /*
-        pl doesn't have f1a as a child,
-        but f1al has f2a as a child.
-        */
-        TEST(0 == pl.RemoveChild(&f1a));
-        TEST(&f2a == f1al.RemoveChild(&f2a));
-        /* 
-        pl should have no parent
-        pl should have no children
-        f1al should still have parent p
-        f1al should still have child f2b
-        f1bl should still have parent p
-        f1bl should have no children
-        f2al should have parent f1a
-        f2al should have no children
-        f2bl should have parent f1a
-        f2bl should have no children
-        */
-        {
-          TEST(pl.GetParent() == 0);
-          TEST(pl.FindChild(&p) == 0);
-          TEST(pl.FindChild(&f1a) == 0);
-          TEST(pl.FindChild(&f1b) == 0);
-          TEST(pl.FindChild(&f2a) == 0);
-          TEST(pl.FindChild(&f2b) == 0);
+      /*
+      pl doesn't have f1a as a child,
+      but f1al has f2a as a child.
+      */
+      TEST(0 == pl.RemoveChild(&f1a));
+      TEST(&f2a == f1al.RemoveChild(&f2a));
+      /* 
+      pl should have no parent
+      pl should have no children
+      f1al should still have parent p
+      f1al should still have child f2b
+      f1bl should still have parent p
+      f1bl should have no children
+      f2al should have parent f1a
+      f2al should have no children
+      f2bl should have parent f1a
+      f2bl should have no children
+      */
+      {
+        TEST(pl.GetParent() == 0);
+        TEST(pl.FindChild(&p) == 0);
+        TEST(pl.FindChild(&f1a) == 0);
+        TEST(pl.FindChild(&f1b) == 0);
+        TEST(pl.FindChild(&f2a) == 0);
+        TEST(pl.FindChild(&f2b) == 0);
 
-          TEST(f1al.GetParent() == &p);
-          TEST(f1al.FindChild(&p) == 0);
-          TEST(f1al.FindChild(&f1a) == 0);
-          TEST(f1al.FindChild(&f1b) == 0);
-          TEST(f1al.FindChild(&f2a) == 0);
-          TEST(f1al.FindChild(&f2b) == &f2b);
+        TEST(f1al.GetParent() == &p);
+        TEST(f1al.FindChild(&p) == 0);
+        TEST(f1al.FindChild(&f1a) == 0);
+        TEST(f1al.FindChild(&f1b) == 0);
+        TEST(f1al.FindChild(&f2a) == 0);
+        TEST(f1al.FindChild(&f2b) == &f2b);
 
-          TEST(f1bl.GetParent() == &p);
-          TEST(f1bl.FindChild(&p) == 0);
-          TEST(f1bl.FindChild(&f1a) == 0);
-          TEST(f1bl.FindChild(&f1b) == 0);
-          TEST(f1bl.FindChild(&f2a) == 0);
-          TEST(f1bl.FindChild(&f2b) == 0);
+        TEST(f1bl.GetParent() == &p);
+        TEST(f1bl.FindChild(&p) == 0);
+        TEST(f1bl.FindChild(&f1a) == 0);
+        TEST(f1bl.FindChild(&f1b) == 0);
+        TEST(f1bl.FindChild(&f2a) == 0);
+        TEST(f1bl.FindChild(&f2b) == 0);
 
-          TEST(f2al.GetParent() == &f1a);
-          TEST(f2al.FindChild(&p) == 0);
-          TEST(f2al.FindChild(&f1a) == 0);
-          TEST(f2al.FindChild(&f1b) == 0);
-          TEST(f2al.FindChild(&f2a) == 0);
-          TEST(f2al.FindChild(&f2b) == 0);
+        TEST(f2al.GetParent() == &f1a);
+        TEST(f2al.FindChild(&p) == 0);
+        TEST(f2al.FindChild(&f1a) == 0);
+        TEST(f2al.FindChild(&f1b) == 0);
+        TEST(f2al.FindChild(&f2a) == 0);
+        TEST(f2al.FindChild(&f2b) == 0);
 
-          TEST(f2bl.GetParent() == &f1a);
-          TEST(f2bl.FindChild(&p) == 0);
-          TEST(f2bl.FindChild(&f1a) == 0);
-          TEST(f2bl.FindChild(&f1b) == 0);
-          TEST(f2bl.FindChild(&f2a) == 0);
-          TEST(f2bl.FindChild(&f2b) == 0);
-        }
+        TEST(f2bl.GetParent() == &f1a);
+        TEST(f2bl.FindChild(&p) == 0);
+        TEST(f2bl.FindChild(&f1a) == 0);
+        TEST(f2bl.FindChild(&f1b) == 0);
+        TEST(f2bl.FindChild(&f2a) == 0);
+        TEST(f2bl.FindChild(&f2b) == 0);
+      }
 
-        /* 
-        pl should have no parent
-        pl should have no children
-        f1al should still have parent p
-        f1al should still have child f2b
-        f1bl should still have parent p
-        f1bl should have no children
-        f2al should have parent f1a
-        f2al should have no children
-        f2bl should now have no parent
-        f2bl should have no children
-        */
-        f2bl.SetParent(0);
-        {
-          TEST(pl.GetParent() == 0);
-          TEST(pl.FindChild(&p) == 0);
-          TEST(pl.FindChild(&f1a) == 0);
-          TEST(pl.FindChild(&f1b) == 0);
-          TEST(pl.FindChild(&f2a) == 0);
-          TEST(pl.FindChild(&f2b) == 0);
+      /* 
+      pl should have no parent
+      pl should have no children
+      f1al should still have parent p
+      f1al should still have child f2b
+      f1bl should still have parent p
+      f1bl should have no children
+      f2al should have parent f1a
+      f2al should have no children
+      f2bl should now have no parent
+      f2bl should have no children
+      */
+      f2bl.SetParent(0);
+      {
+        TEST(pl.GetParent() == 0);
+        TEST(pl.FindChild(&p) == 0);
+        TEST(pl.FindChild(&f1a) == 0);
+        TEST(pl.FindChild(&f1b) == 0);
+        TEST(pl.FindChild(&f2a) == 0);
+        TEST(pl.FindChild(&f2b) == 0);
 
-          TEST(f1al.GetParent() == &p);
-          TEST(f1al.FindChild(&p) == 0);
-          TEST(f1al.FindChild(&f1a) == 0);
-          TEST(f1al.FindChild(&f1b) == 0);
-          TEST(f1al.FindChild(&f2a) == 0);
-          TEST(f1al.FindChild(&f2b) == &f2b);
+        TEST(f1al.GetParent() == &p);
+        TEST(f1al.FindChild(&p) == 0);
+        TEST(f1al.FindChild(&f1a) == 0);
+        TEST(f1al.FindChild(&f1b) == 0);
+        TEST(f1al.FindChild(&f2a) == 0);
+        TEST(f1al.FindChild(&f2b) == &f2b);
 
-          TEST(f1bl.GetParent() == &p);
-          TEST(f1bl.FindChild(&p) == 0);
-          TEST(f1bl.FindChild(&f1a) == 0);
-          TEST(f1bl.FindChild(&f1b) == 0);
-          TEST(f1bl.FindChild(&f2a) == 0);
-          TEST(f1bl.FindChild(&f2b) == 0);
+        TEST(f1bl.GetParent() == &p);
+        TEST(f1bl.FindChild(&p) == 0);
+        TEST(f1bl.FindChild(&f1a) == 0);
+        TEST(f1bl.FindChild(&f1b) == 0);
+        TEST(f1bl.FindChild(&f2a) == 0);
+        TEST(f1bl.FindChild(&f2b) == 0);
 
-          TEST(f2al.GetParent() == &f1a);
-          TEST(f2al.FindChild(&p) == 0);
-          TEST(f2al.FindChild(&f1a) == 0);
-          TEST(f2al.FindChild(&f1b) == 0);
-          TEST(f2al.FindChild(&f2a) == 0);
-          TEST(f2al.FindChild(&f2b) == 0);
+        TEST(f2al.GetParent() == &f1a);
+        TEST(f2al.FindChild(&p) == 0);
+        TEST(f2al.FindChild(&f1a) == 0);
+        TEST(f2al.FindChild(&f1b) == 0);
+        TEST(f2al.FindChild(&f2a) == 0);
+        TEST(f2al.FindChild(&f2b) == 0);
 
-          TEST(f2bl.GetParent() == 0);
-          TEST(f2bl.FindChild(&p) == 0);
-          TEST(f2bl.FindChild(&f1a) == 0);
-          TEST(f2bl.FindChild(&f1b) == 0);
-          TEST(f2bl.FindChild(&f2a) == 0);
-          TEST(f2bl.FindChild(&f2b) == 0);
-        }
-
+        TEST(f2bl.GetParent() == 0);
+        TEST(f2bl.FindChild(&p) == 0);
+        TEST(f2bl.FindChild(&f1a) == 0);
+        TEST(f2bl.FindChild(&f1b) == 0);
+        TEST(f2bl.FindChild(&f2a) == 0);
+        TEST(f2bl.FindChild(&f2b) == 0);
       }
 
-      /* Test cAnalyzeGenotypeLink function AddChild(). {{{3 */
-      if(true){
-        cAnalyzeGenotype
-          p(AGFactory(*world, "ccc")),
-          f1a(AGFactory(*world, "ccc")),
-          f1b(AGFactory(*world, "ccc")),
-          f2a(AGFactory(*world, "ccc")),
-          f2b(AGFactory(*world, "ccc"));
-        cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
+    }
 
-        pl.SetParent(0);
+    /* Test cAnalyzeGenotypeLink function AddChild(). {{{3 */
+    if(true){
+      cAnalyzeGenotype
+        p(AGFactory(*world, "ccc")),
+        f1a(AGFactory(*world, "ccc")),
+        f1b(AGFactory(*world, "ccc")),
+        f2a(AGFactory(*world, "ccc")),
+        f2b(AGFactory(*world, "ccc"));
+      cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
 
-        pl.AddChild(&f1a);
-        f1al.SetParent(&p);
+      pl.SetParent(0);
 
-        pl.AddChild(&f1b);
-        f1bl.SetParent(&p);
+      pl.AddChild(&f1a);
+      f1al.SetParent(&p);
 
-        f1al.AddChild(&f2a);
-        f2al.SetParent(&f1a);
+      pl.AddChild(&f1b);
+      f1bl.SetParent(&p);
 
-        f1al.AddChild(&f2b);
-        f2bl.SetParent(&f1a);
+      f1al.AddChild(&f2a);
+      f2al.SetParent(&f1a);
 
-        /* 
-        pl should have no parent
-        pl should have children f1a and f1b
-        f1al should have parent p
-        f1al should have children f2a and f2b
-        f1bl should have parent p
-        f1bl should have no children
-        f2al should have parent f1a
-        f2al should have no children
-        f2bl should have parent f1a
-        f2bl should have no children
-        */
-        {
-          TEST(pl.GetParent() == 0);
-          TEST(pl.FindChild(&p) == 0);
-          TEST(pl.FindChild(&f1a) == &f1a);
-          TEST(pl.FindChild(&f1b) == &f1b);
-          TEST(pl.FindChild(&f2a) == 0);
-          TEST(pl.FindChild(&f2b) == 0);
+      f1al.AddChild(&f2b);
+      f2bl.SetParent(&f1a);
 
-          TEST(f1al.GetParent() == &p);
-          TEST(f1al.FindChild(&p) == 0);
-          TEST(f1al.FindChild(&f1a) == 0);
-          TEST(f1al.FindChild(&f1b) == 0);
-          TEST(f1al.FindChild(&f2a) == &f2a);
-          TEST(f1al.FindChild(&f2b) == &f2b);
+      /* 
+      pl should have no parent
+      pl should have children f1a and f1b
+      f1al should have parent p
+      f1al should have children f2a and f2b
+      f1bl should have parent p
+      f1bl should have no children
+      f2al should have parent f1a
+      f2al should have no children
+      f2bl should have parent f1a
+      f2bl should have no children
+      */
+      {
+        TEST(pl.GetParent() == 0);
+        TEST(pl.FindChild(&p) == 0);
+        TEST(pl.FindChild(&f1a) == &f1a);
+        TEST(pl.FindChild(&f1b) == &f1b);
+        TEST(pl.FindChild(&f2a) == 0);
+        TEST(pl.FindChild(&f2b) == 0);
 
-          TEST(f1bl.GetParent() == &p);
-          TEST(f1bl.FindChild(&p) == 0);
-          TEST(f1bl.FindChild(&f1a) == 0);
-          TEST(f1bl.FindChild(&f1b) == 0);
-          TEST(f1bl.FindChild(&f2a) == 0);
-          TEST(f1bl.FindChild(&f2b) == 0);
+        TEST(f1al.GetParent() == &p);
+        TEST(f1al.FindChild(&p) == 0);
+        TEST(f1al.FindChild(&f1a) == 0);
+        TEST(f1al.FindChild(&f1b) == 0);
+        TEST(f1al.FindChild(&f2a) == &f2a);
+        TEST(f1al.FindChild(&f2b) == &f2b);
 
-          TEST(f2al.GetParent() == &f1a);
-          TEST(f2al.FindChild(&p) == 0);
-          TEST(f2al.FindChild(&f1a) == 0);
-          TEST(f2al.FindChild(&f1b) == 0);
-          TEST(f2al.FindChild(&f2a) == 0);
-          TEST(f2al.FindChild(&f2b) == 0);
+        TEST(f1bl.GetParent() == &p);
+        TEST(f1bl.FindChild(&p) == 0);
+        TEST(f1bl.FindChild(&f1a) == 0);
+        TEST(f1bl.FindChild(&f1b) == 0);
+        TEST(f1bl.FindChild(&f2a) == 0);
+        TEST(f1bl.FindChild(&f2b) == 0);
 
-          TEST(f2bl.GetParent() == &f1a);
-          TEST(f2bl.FindChild(&p) == 0);
-          TEST(f2bl.FindChild(&f1a) == 0);
-          TEST(f2bl.FindChild(&f1b) == 0);
-          TEST(f2bl.FindChild(&f2a) == 0);
-          TEST(f2bl.FindChild(&f2b) == 0);
-        }
+        TEST(f2al.GetParent() == &f1a);
+        TEST(f2al.FindChild(&p) == 0);
+        TEST(f2al.FindChild(&f1a) == 0);
+        TEST(f2al.FindChild(&f1b) == 0);
+        TEST(f2al.FindChild(&f2a) == 0);
+        TEST(f2al.FindChild(&f2b) == 0);
+
+        TEST(f2bl.GetParent() == &f1a);
+        TEST(f2bl.FindChild(&p) == 0);
+        TEST(f2bl.FindChild(&f1a) == 0);
+        TEST(f2bl.FindChild(&f1b) == 0);
+        TEST(f2bl.FindChild(&f2a) == 0);
+        TEST(f2bl.FindChild(&f2b) == 0);
       }
+    }
 
-      /* Test cAnalyzeGenotype functions UnlinkParent(), LinkChild(), GetLink(). {{{3 */
-      {
-        cAnalyzeGenotype
-          p(AGFactory(*world, "ccc")),
-          f1a(AGFactory(*world, "ccc")),
-          f1b(AGFactory(*world, "ccc")),
-          f2a(AGFactory(*world, "ccc")),
-          f2b(AGFactory(*world, "ccc"));
+    /* Test cAnalyzeGenotype functions UnlinkParent(), LinkChild(), GetLink(). {{{3 */
+    {
+      cAnalyzeGenotype
+        p(AGFactory(*world, "ccc")),
+        f1a(AGFactory(*world, "ccc")),
+        f1b(AGFactory(*world, "ccc")),
+        f2a(AGFactory(*world, "ccc")),
+        f2b(AGFactory(*world, "ccc"));
 
-        p.UnlinkParent();
-        // or p.LinkParent(0)...
-        p.LinkChild(f1a);
-        p.LinkChild(f1b);
-        f1a.LinkChild(f2a);
-        f1a.LinkChild(f2b);
+      p.UnlinkParent();
+      // or p.LinkParent(0)...
+      p.LinkChild(f1a);
+      p.LinkChild(f1b);
+      f1a.LinkChild(f2a);
+      f1a.LinkChild(f2b);
 
-        /* 
-        p should have no parent
-        p should have children f1a and f1b
-        f1a should have parent p
-        f1a should have children f2a and f2b
-        f1b should have parent p
-        f1b should have no children
-        f2a should have parent f1a
-        f2a should have no children
-        f2b should have parent f1a
-        f2b should have no children
-        */
-        {
-          TEST(p.GetLink().GetParent() == 0);
-          TEST(p.GetLink().FindChild(&p) == 0);
-          TEST(p.GetLink().FindChild(&f1a) == &f1a);
-          TEST(p.GetLink().FindChild(&f1b) == &f1b);
-          TEST(p.GetLink().FindChild(&f2a) == 0);
-          TEST(p.GetLink().FindChild(&f2b) == 0);
+      /* 
+      p should have no parent
+      p should have children f1a and f1b
+      f1a should have parent p
+      f1a should have children f2a and f2b
+      f1b should have parent p
+      f1b should have no children
+      f2a should have parent f1a
+      f2a should have no children
+      f2b should have parent f1a
+      f2b should have no children
+      */
+      {
+        TEST(p.GetLink().GetParent() == 0);
+        TEST(p.GetLink().FindChild(&p) == 0);
+        TEST(p.GetLink().FindChild(&f1a) == &f1a);
+        TEST(p.GetLink().FindChild(&f1b) == &f1b);
+        TEST(p.GetLink().FindChild(&f2a) == 0);
+        TEST(p.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f1a.GetLink().GetParent() == &p);
-          TEST(f1a.GetLink().FindChild(&p) == 0);
-          TEST(f1a.GetLink().FindChild(&f1a) == 0);
-          TEST(f1a.GetLink().FindChild(&f1b) == 0);
-          TEST(f1a.GetLink().FindChild(&f2a) == &f2a);
-          TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
+        TEST(f1a.GetLink().GetParent() == &p);
+        TEST(f1a.GetLink().FindChild(&p) == 0);
+        TEST(f1a.GetLink().FindChild(&f1a) == 0);
+        TEST(f1a.GetLink().FindChild(&f1b) == 0);
+        TEST(f1a.GetLink().FindChild(&f2a) == &f2a);
+        TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
 
-          TEST(f1b.GetLink().GetParent() == &p);
-          TEST(f1b.GetLink().FindChild(&p) == 0);
-          TEST(f1b.GetLink().FindChild(&f1a) == 0);
-          TEST(f1b.GetLink().FindChild(&f1b) == 0);
-          TEST(f1b.GetLink().FindChild(&f2a) == 0);
-          TEST(f1b.GetLink().FindChild(&f2b) == 0);
+        TEST(f1b.GetLink().GetParent() == &p);
+        TEST(f1b.GetLink().FindChild(&p) == 0);
+        TEST(f1b.GetLink().FindChild(&f1a) == 0);
+        TEST(f1b.GetLink().FindChild(&f1b) == 0);
+        TEST(f1b.GetLink().FindChild(&f2a) == 0);
+        TEST(f1b.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f2a.GetLink().GetParent() == &f1a);
-          TEST(f2a.GetLink().FindChild(&p) == 0);
-          TEST(f2a.GetLink().FindChild(&f1a) == 0);
-          TEST(f2a.GetLink().FindChild(&f1b) == 0);
-          TEST(f2a.GetLink().FindChild(&f2a) == 0);
-          TEST(f2a.GetLink().FindChild(&f2b) == 0);
+        TEST(f2a.GetLink().GetParent() == &f1a);
+        TEST(f2a.GetLink().FindChild(&p) == 0);
+        TEST(f2a.GetLink().FindChild(&f1a) == 0);
+        TEST(f2a.GetLink().FindChild(&f1b) == 0);
+        TEST(f2a.GetLink().FindChild(&f2a) == 0);
+        TEST(f2a.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f2b.GetLink().GetParent() == &f1a);
-          TEST(f2b.GetLink().FindChild(&p) == 0);
-          TEST(f2b.GetLink().FindChild(&f1a) == 0);
-          TEST(f2b.GetLink().FindChild(&f1b) == 0);
-          TEST(f2b.GetLink().FindChild(&f2a) == 0);
-          TEST(f2b.GetLink().FindChild(&f2b) == 0);
-        }
+        TEST(f2b.GetLink().GetParent() == &f1a);
+        TEST(f2b.GetLink().FindChild(&p) == 0);
+        TEST(f2b.GetLink().FindChild(&f1a) == 0);
+        TEST(f2b.GetLink().FindChild(&f1b) == 0);
+        TEST(f2b.GetLink().FindChild(&f2a) == 0);
+        TEST(f2b.GetLink().FindChild(&f2b) == 0);
       }
+    }
 
-      /* Test cAnalyzeGenotype function LinkParent(). {{{3 */
-      {
-        cAnalyzeGenotype
-          p(AGFactory(*world, "ccc")),
-          f1a(AGFactory(*world, "ccc")),
-          f1b(AGFactory(*world, "ccc")),
-          f2a(AGFactory(*world, "ccc")),
-          f2b(AGFactory(*world, "ccc"));
+    /* Test cAnalyzeGenotype function LinkParent(). {{{3 */
+    {
+      cAnalyzeGenotype
+        p(AGFactory(*world, "ccc")),
+        f1a(AGFactory(*world, "ccc")),
+        f1b(AGFactory(*world, "ccc")),
+        f2a(AGFactory(*world, "ccc")),
+        f2b(AGFactory(*world, "ccc"));
 
 
-        p.UnlinkParent();
-        // or p.LinkParent(0)... ?
-        f1a.LinkParent(&p);
-        f1b.LinkParent(&p);
-        f2a.LinkParent(&f1a);
-        f2b.LinkParent(&f1a);
+      p.UnlinkParent();
+      // or p.LinkParent(0)... ?
+      f1a.LinkParent(&p);
+      f1b.LinkParent(&p);
+      f2a.LinkParent(&f1a);
+      f2b.LinkParent(&f1a);
 
-        /* 
-        p should have no parent
-        p should have children f1a and f1b
-        f1a should have parent p
-        f1a should have children f2a and f2b
-        f1b should have parent p
-        f1b should have no children
-        f2a should have parent f1a
-        f2a should have no children
-        f2b should have parent f1a
-        f2b should have no children
-        */
-        {
-          TEST(p.GetLink().GetParent() == 0);
-          TEST(p.GetLink().FindChild(&p) == 0);
-          TEST(p.GetLink().FindChild(&f1a) == &f1a);
-          TEST(p.GetLink().FindChild(&f1b) == &f1b);
-          TEST(p.GetLink().FindChild(&f2a) == 0);
-          TEST(p.GetLink().FindChild(&f2b) == 0);
+      /* 
+      p should have no parent
+      p should have children f1a and f1b
+      f1a should have parent p
+      f1a should have children f2a and f2b
+      f1b should have parent p
+      f1b should have no children
+      f2a should have parent f1a
+      f2a should have no children
+      f2b should have parent f1a
+      f2b should have no children
+      */
+      {
+        TEST(p.GetLink().GetParent() == 0);
+        TEST(p.GetLink().FindChild(&p) == 0);
+        TEST(p.GetLink().FindChild(&f1a) == &f1a);
+        TEST(p.GetLink().FindChild(&f1b) == &f1b);
+        TEST(p.GetLink().FindChild(&f2a) == 0);
+        TEST(p.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f1a.GetLink().GetParent() == &p);
-          TEST(f1a.GetLink().FindChild(&p) == 0);
-          TEST(f1a.GetLink().FindChild(&f1a) == 0);
-          TEST(f1a.GetLink().FindChild(&f1b) == 0);
-          TEST(f1a.GetLink().FindChild(&f2a) == &f2a);
-          TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
+        TEST(f1a.GetLink().GetParent() == &p);
+        TEST(f1a.GetLink().FindChild(&p) == 0);
+        TEST(f1a.GetLink().FindChild(&f1a) == 0);
+        TEST(f1a.GetLink().FindChild(&f1b) == 0);
+        TEST(f1a.GetLink().FindChild(&f2a) == &f2a);
+        TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
 
-          TEST(f1b.GetLink().GetParent() == &p);
-          TEST(f1b.GetLink().FindChild(&p) == 0);
-          TEST(f1b.GetLink().FindChild(&f1a) == 0);
-          TEST(f1b.GetLink().FindChild(&f1b) == 0);
-          TEST(f1b.GetLink().FindChild(&f2a) == 0);
-          TEST(f1b.GetLink().FindChild(&f2b) == 0);
+        TEST(f1b.GetLink().GetParent() == &p);
+        TEST(f1b.GetLink().FindChild(&p) == 0);
+        TEST(f1b.GetLink().FindChild(&f1a) == 0);
+        TEST(f1b.GetLink().FindChild(&f1b) == 0);
+        TEST(f1b.GetLink().FindChild(&f2a) == 0);
+        TEST(f1b.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f2a.GetLink().GetParent() == &f1a);
-          TEST(f2a.GetLink().FindChild(&p) == 0);
-          TEST(f2a.GetLink().FindChild(&f1a) == 0);
-          TEST(f2a.GetLink().FindChild(&f1b) == 0);
-          TEST(f2a.GetLink().FindChild(&f2a) == 0);
-          TEST(f2a.GetLink().FindChild(&f2b) == 0);
+        TEST(f2a.GetLink().GetParent() == &f1a);
+        TEST(f2a.GetLink().FindChild(&p) == 0);
+        TEST(f2a.GetLink().FindChild(&f1a) == 0);
+        TEST(f2a.GetLink().FindChild(&f1b) == 0);
+        TEST(f2a.GetLink().FindChild(&f2a) == 0);
+        TEST(f2a.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f2b.GetLink().GetParent() == &f1a);
-          TEST(f2b.GetLink().FindChild(&p) == 0);
-          TEST(f2b.GetLink().FindChild(&f1a) == 0);
-          TEST(f2b.GetLink().FindChild(&f1b) == 0);
-          TEST(f2b.GetLink().FindChild(&f2a) == 0);
-          TEST(f2b.GetLink().FindChild(&f2b) == 0);
-        }
+        TEST(f2b.GetLink().GetParent() == &f1a);
+        TEST(f2b.GetLink().FindChild(&p) == 0);
+        TEST(f2b.GetLink().FindChild(&f1a) == 0);
+        TEST(f2b.GetLink().FindChild(&f1b) == 0);
+        TEST(f2b.GetLink().FindChild(&f2a) == 0);
+        TEST(f2b.GetLink().FindChild(&f2b) == 0);
       }
+    }
 
-      /* Test cAnalyzeGenotype function UnlinkChildren(), LinkParent(0). {{{3 */
-      {
-        cAnalyzeGenotype
-          p(AGFactory(*world, "ccc")),
-          f1a(AGFactory(*world, "ccc")),
-          f1b(AGFactory(*world, "ccc")),
-          f2a(AGFactory(*world, "ccc")),
-          f2b(AGFactory(*world, "ccc"));
+    /* Test cAnalyzeGenotype function UnlinkChildren(), LinkParent(0). {{{3 */
+    {
+      cAnalyzeGenotype
+        p(AGFactory(*world, "ccc")),
+        f1a(AGFactory(*world, "ccc")),
+        f1b(AGFactory(*world, "ccc")),
+        f2a(AGFactory(*world, "ccc")),
+        f2b(AGFactory(*world, "ccc"));
 
 
-        p.UnlinkParent();
-        // or p.LinkParent(0)... ?
-        f1a.LinkParent(&p);
-        f1b.LinkParent(&p);
-        f2a.LinkParent(&f1a);
-        f2b.LinkParent(&f1a);
+      p.UnlinkParent();
+      // or p.LinkParent(0)... ?
+      f1a.LinkParent(&p);
+      f1b.LinkParent(&p);
+      f2a.LinkParent(&f1a);
+      f2b.LinkParent(&f1a);
 
-        p.UnlinkChildren();
-        f2a.LinkParent(0);
+      p.UnlinkChildren();
+      f2a.LinkParent(0);
 
-        /* 
-        p should have no parent
-        p should have no children
-        f1a should have no parent
-        f1a should have child f2b
-        f1b should have no parent
-        f1b should have no children
-        f2a should have no parent
-        f2a should have no children
-        f2b should have parent f1a
-        f2b should have no children
-        */
-        {
-          TEST(p.GetLink().GetParent() == 0);
-          TEST(p.GetLink().FindChild(&p) == 0);
-          TEST(p.GetLink().FindChild(&f1a) == 0);
-          TEST(p.GetLink().FindChild(&f1b) == 0);
-          TEST(p.GetLink().FindChild(&f2a) == 0);
-          TEST(p.GetLink().FindChild(&f2b) == 0);
+      /* 
+      p should have no parent
+      p should have no children
+      f1a should have no parent
+      f1a should have child f2b
+      f1b should have no parent
+      f1b should have no children
+      f2a should have no parent
+      f2a should have no children
+      f2b should have parent f1a
+      f2b should have no children
+      */
+      {
+        TEST(p.GetLink().GetParent() == 0);
+        TEST(p.GetLink().FindChild(&p) == 0);
+        TEST(p.GetLink().FindChild(&f1a) == 0);
+        TEST(p.GetLink().FindChild(&f1b) == 0);
+        TEST(p.GetLink().FindChild(&f2a) == 0);
+        TEST(p.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f1a.GetLink().GetParent() == 0);
-          TEST(f1a.GetLink().FindChild(&p) == 0);
-          TEST(f1a.GetLink().FindChild(&f1a) == 0);
-          TEST(f1a.GetLink().FindChild(&f1b) == 0);
-          TEST(f1a.GetLink().FindChild(&f2a) == 0);
-          TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
+        TEST(f1a.GetLink().GetParent() == 0);
+        TEST(f1a.GetLink().FindChild(&p) == 0);
+        TEST(f1a.GetLink().FindChild(&f1a) == 0);
+        TEST(f1a.GetLink().FindChild(&f1b) == 0);
+        TEST(f1a.GetLink().FindChild(&f2a) == 0);
+        TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
 
-          TEST(f1b.GetLink().GetParent() == 0);
-          TEST(f1b.GetLink().FindChild(&p) == 0);
-          TEST(f1b.GetLink().FindChild(&f1a) == 0);
-          TEST(f1b.GetLink().FindChild(&f1b) == 0);
-          TEST(f1b.GetLink().FindChild(&f2a) == 0);
-          TEST(f1b.GetLink().FindChild(&f2b) == 0);
+        TEST(f1b.GetLink().GetParent() == 0);
+        TEST(f1b.GetLink().FindChild(&p) == 0);
+        TEST(f1b.GetLink().FindChild(&f1a) == 0);
+        TEST(f1b.GetLink().FindChild(&f1b) == 0);
+        TEST(f1b.GetLink().FindChild(&f2a) == 0);
+        TEST(f1b.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f2a.GetLink().GetParent() == 0);
-          TEST(f2a.GetLink().FindChild(&p) == 0);
-          TEST(f2a.GetLink().FindChild(&f1a) == 0);
-          TEST(f2a.GetLink().FindChild(&f1b) == 0);
-          TEST(f2a.GetLink().FindChild(&f2a) == 0);
-          TEST(f2a.GetLink().FindChild(&f2b) == 0);
+        TEST(f2a.GetLink().GetParent() == 0);
+        TEST(f2a.GetLink().FindChild(&p) == 0);
+        TEST(f2a.GetLink().FindChild(&f1a) == 0);
+        TEST(f2a.GetLink().FindChild(&f1b) == 0);
+        TEST(f2a.GetLink().FindChild(&f2a) == 0);
+        TEST(f2a.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f2b.GetLink().GetParent() == &f1a);
-          TEST(f2b.GetLink().FindChild(&p) == 0);
-          TEST(f2b.GetLink().FindChild(&f1a) == 0);
-          TEST(f2b.GetLink().FindChild(&f1b) == 0);
-          TEST(f2b.GetLink().FindChild(&f2a) == 0);
-          TEST(f2b.GetLink().FindChild(&f2b) == 0);
-        }
+        TEST(f2b.GetLink().GetParent() == &f1a);
+        TEST(f2b.GetLink().FindChild(&p) == 0);
+        TEST(f2b.GetLink().FindChild(&f1a) == 0);
+        TEST(f2b.GetLink().FindChild(&f1b) == 0);
+        TEST(f2b.GetLink().FindChild(&f2a) == 0);
+        TEST(f2b.GetLink().FindChild(&f2b) == 0);
       }
+    }
 
-      /* Test cAnalyzeGenotype function Unlink(). {{{3 */
-      {
-        cAnalyzeGenotype
-          p(AGFactory(*world, "ccc")),
-          f1a(AGFactory(*world, "ccc")),
-          f1b(AGFactory(*world, "ccc")),
-          f2a(AGFactory(*world, "ccc")),
-          f2b(AGFactory(*world, "ccc"));
+    /* Test cAnalyzeGenotype function Unlink(). {{{3 */
+    {
+      cAnalyzeGenotype
+        p(AGFactory(*world, "ccc")),
+        f1a(AGFactory(*world, "ccc")),
+        f1b(AGFactory(*world, "ccc")),
+        f2a(AGFactory(*world, "ccc")),
+        f2b(AGFactory(*world, "ccc"));
 
 
-        p.UnlinkParent();
-        // or p.LinkParent(0)... ?
-        f1a.LinkParent(&p);
-        f1b.LinkParent(&p);
-        f2a.LinkParent(&f1a);
-        f2b.LinkParent(&f1a);
+      p.UnlinkParent();
+      // or p.LinkParent(0)... ?
+      f1a.LinkParent(&p);
+      f1b.LinkParent(&p);
+      f2a.LinkParent(&f1a);
+      f2b.LinkParent(&f1a);
 
-        f1a.Unlink();
-        /* 
-        p should have no parent
-        p should have child f1b
-        f1a should have no parent
-        f1a should have no children
-        f1b should have parent p
-        f1b should have no children
-        f2a should have no parent
-        f2a should have no children
-        f2b should have no parent
-        f2b should have no children
-        */
-        {
-          TEST(p.GetLink().GetParent() == 0);
-          TEST(p.GetLink().FindChild(&p) == 0);
-          TEST(p.GetLink().FindChild(&f1a) == 0);
-          TEST(p.GetLink().FindChild(&f1b) == &f1b);
-          TEST(p.GetLink().FindChild(&f2a) == 0);
-          TEST(p.GetLink().FindChild(&f2b) == 0);
+      f1a.Unlink();
+      /* 
+      p should have no parent
+      p should have child f1b
+      f1a should have no parent
+      f1a should have no children
+      f1b should have parent p
+      f1b should have no children
+      f2a should have no parent
+      f2a should have no children
+      f2b should have no parent
+      f2b should have no children
+      */
+      {
+        TEST(p.GetLink().GetParent() == 0);
+        TEST(p.GetLink().FindChild(&p) == 0);
+        TEST(p.GetLink().FindChild(&f1a) == 0);
+        TEST(p.GetLink().FindChild(&f1b) == &f1b);
+        TEST(p.GetLink().FindChild(&f2a) == 0);
+        TEST(p.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f1a.GetLink().GetParent() == 0);
-          TEST(f1a.GetLink().FindChild(&p) == 0);
-          TEST(f1a.GetLink().FindChild(&f1a) == 0);
-          TEST(f1a.GetLink().FindChild(&f1b) == 0);
-          TEST(f1a.GetLink().FindChild(&f2a) == 0);
-          TEST(f1a.GetLink().FindChild(&f2b) == 0);
+        TEST(f1a.GetLink().GetParent() == 0);
+        TEST(f1a.GetLink().FindChild(&p) == 0);
+        TEST(f1a.GetLink().FindChild(&f1a) == 0);
+        TEST(f1a.GetLink().FindChild(&f1b) == 0);
+        TEST(f1a.GetLink().FindChild(&f2a) == 0);
+        TEST(f1a.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f1b.GetLink().GetParent() == &p);
-          TEST(f1b.GetLink().FindChild(&p) == 0);
-          TEST(f1b.GetLink().FindChild(&f1a) == 0);
-          TEST(f1b.GetLink().FindChild(&f1b) == 0);
-          TEST(f1b.GetLink().FindChild(&f2a) == 0);
-          TEST(f1b.GetLink().FindChild(&f2b) == 0);
+        TEST(f1b.GetLink().GetParent() == &p);
+        TEST(f1b.GetLink().FindChild(&p) == 0);
+        TEST(f1b.GetLink().FindChild(&f1a) == 0);
+        TEST(f1b.GetLink().FindChild(&f1b) == 0);
+        TEST(f1b.GetLink().FindChild(&f2a) == 0);
+        TEST(f1b.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f2a.GetLink().GetParent() == 0);
-          TEST(f2a.GetLink().FindChild(&p) == 0);
-          TEST(f2a.GetLink().FindChild(&f1a) == 0);
-          TEST(f2a.GetLink().FindChild(&f1b) == 0);
-          TEST(f2a.GetLink().FindChild(&f2a) == 0);
-          TEST(f2a.GetLink().FindChild(&f2b) == 0);
+        TEST(f2a.GetLink().GetParent() == 0);
+        TEST(f2a.GetLink().FindChild(&p) == 0);
+        TEST(f2a.GetLink().FindChild(&f1a) == 0);
+        TEST(f2a.GetLink().FindChild(&f1b) == 0);
+        TEST(f2a.GetLink().FindChild(&f2a) == 0);
+        TEST(f2a.GetLink().FindChild(&f2b) == 0);
 
-          TEST(f2b.GetLink().GetParent() == 0);
-          TEST(f2b.GetLink().FindChild(&p) == 0);
-          TEST(f2b.GetLink().FindChild(&f1a) == 0);
-          TEST(f2b.GetLink().FindChild(&f1b) == 0);
-          TEST(f2b.GetLink().FindChild(&f2a) == 0);
-          TEST(f2b.GetLink().FindChild(&f2b) == 0);
-        }
+        TEST(f2b.GetLink().GetParent() == 0);
+        TEST(f2b.GetLink().FindChild(&p) == 0);
+        TEST(f2b.GetLink().FindChild(&f1a) == 0);
+        TEST(f2b.GetLink().FindChild(&f1b) == 0);
+        TEST(f2b.GetLink().FindChild(&f2a) == 0);
+        TEST(f2b.GetLink().FindChild(&f2b) == 0);
       }
+    }
 
-      /* Verify cAnalyzeGenotypeLink constructor. It shouldn't do much beyond initialize its child_list to empty and its parent to null. {{{3 */
-      {
-        cAnalyzeGenotypeLink pl;
+    /* Verify cAnalyzeGenotypeLink constructor. It shouldn't do much beyond initialize its child_list to empty and its parent to null. {{{3 */
+    {
+      cAnalyzeGenotypeLink pl;
 
-        TEST(0 == pl.GetParent());
-        TEST(0 == pl.GetChildList().GetSize());
-      }
+      TEST(0 == pl.GetParent());
+      TEST(0 == pl.GetChildList().GetSize());
+    }
 
-      /* Verify that adding same child twice does not create two entries in child list. {{{3 */
-      {
-        cAnalyzeGenotype
-          f1a(AGFactory(*world, "ccc")),
-          f1b(AGFactory(*world, "ccc"));
-        cAnalyzeGenotypeLink pl;
+    /* Verify that adding same child twice does not create two entries in child list. {{{3 */
+    {
+      cAnalyzeGenotype
+        f1a(AGFactory(*world, "ccc")),
+        f1b(AGFactory(*world, "ccc"));
+      cAnalyzeGenotypeLink pl;
 
-        TEST(0 == pl.GetParent());
-        TEST(0 == pl.GetChildList().GetSize());
+      TEST(0 == pl.GetParent());
+      TEST(0 == pl.GetChildList().GetSize());
 
-        /* First add of f1a. */
-        pl.AddChild(&f1a);
-        TEST(1 == pl.GetChildList().GetSize());
-        /* Second add of f1a. */
-        pl.AddChild(&f1a);
-        TEST(1 == pl.GetChildList().GetSize());
+      /* First add of f1a. */
+      pl.AddChild(&f1a);
+      TEST(1 == pl.GetChildList().GetSize());
+      /* Second add of f1a. */
+      pl.AddChild(&f1a);
+      TEST(1 == pl.GetChildList().GetSize());
 
-        /* First add of f1b. */
-        pl.AddChild(&f1b);
-        TEST(2 == pl.GetChildList().GetSize());
-      }
+      /* First add of f1b. */
+      pl.AddChild(&f1b);
+      TEST(2 == pl.GetChildList().GetSize());
+    }
 
-      /* Verify cAnalyzeGenotype constructor handling of cAnalyzeGenotypeLink. {{{3 */
-      {
-        cAnalyzeGenotype p(AGFactory(*world, "ccc"));
+    /* Verify cAnalyzeGenotype constructor handling of cAnalyzeGenotypeLink. {{{3 */
+    {
+      cAnalyzeGenotype p(AGFactory(*world, "ccc"));
 
-        TEST(0 == p.GetLink().GetParent());
-        TEST(0 == p.GetLink().GetChildList().GetSize());
-      }
+      TEST(0 == p.GetLink().GetParent());
+      TEST(0 == p.GetLink().GetChildList().GetSize());
+    }
 
-      /* XXX To-Do: Verify cAnalyzeGenotype destructor properly destroys cAnalyzeGenotypeLink. {{{3 */
-      {
-        cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-        cAnalyzeGenotype *p, *f1a, *f1b, *f2a, *f2b, *orphan;
+    /* XXX To-Do: Verify cAnalyzeGenotype destructor properly destroys cAnalyzeGenotypeLink. {{{3 */
+    {
+      cout << "XXX This is a testsuite demo. It needs filling-in. @kgn" << endl;
+      cAnalyzeGenotype *p, *f1a, *f1b, *f2a, *f2b, *orphan;
 
-        p = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
-        f1a = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
-        f1b = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
-        f2a = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
-        f2b = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+      p = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+      f1a = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+      f1b = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+      f2a = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+      f2b = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
 
-        orphan = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+      orphan = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
 
-        p->LinkChild(*f1a);
-        p->LinkChild(*f1b);
-        f1a->LinkChild(*f2a);
-        f1a->LinkChild(*f2b);
+      p->LinkChild(*f1a);
+      p->LinkChild(*f1b);
+      f1a->LinkChild(*f2a);
+      f1a->LinkChild(*f2b);
 
-        /* 
-        p should have no parent
-        p should have children f1a and f1b
-        f1a should have parent p
-        f1a should have children f2a and f2b
-        f1b should have parent p
-        f1b should have no children
-        f2a should have parent f1a
-        f2a should have no children
-        f2b should have parent f1a
-        f2b should have no children
-        orphan should have no parent
-        orphan should have no children
-        */
-        {
-          TEST(p->GetLink().GetParent() == 0);
-          TEST(2 == p->GetLink().GetChildList().GetSize());
-          TEST(f1a->GetLink().GetParent() == p);
-          TEST(2 == f1a->GetLink().GetChildList().GetSize());
-          TEST(f1b->GetLink().GetParent() == p);
-          TEST(0 == f1b->GetLink().GetChildList().GetSize());
-          TEST(f2a->GetLink().GetParent() == f1a);
-          TEST(0 == f2a->GetLink().GetChildList().GetSize());
-          TEST(f2b->GetLink().GetParent() == f1a);
-          TEST(0 == f2b->GetLink().GetChildList().GetSize());
-          TEST(orphan->GetLink().GetParent() == 0);
-          TEST(0 == orphan->GetLink().GetChildList().GetSize());
-        }
+      /* 
+      p should have no parent
+      p should have children f1a and f1b
+      f1a should have parent p
+      f1a should have children f2a and f2b
+      f1b should have parent p
+      f1b should have no children
+      f2a should have parent f1a
+      f2a should have no children
+      f2b should have parent f1a
+      f2b should have no children
+      orphan should have no parent
+      orphan should have no children
+      */
+      {
+        TEST(p->GetLink().GetParent() == 0);
+        TEST(2 == p->GetLink().GetChildList().GetSize());
+        TEST(f1a->GetLink().GetParent() == p);
+        TEST(2 == f1a->GetLink().GetChildList().GetSize());
+        TEST(f1b->GetLink().GetParent() == p);
+        TEST(0 == f1b->GetLink().GetChildList().GetSize());
+        TEST(f2a->GetLink().GetParent() == f1a);
+        TEST(0 == f2a->GetLink().GetChildList().GetSize());
+        TEST(f2b->GetLink().GetParent() == f1a);
+        TEST(0 == f2b->GetLink().GetChildList().GetSize());
+        TEST(orphan->GetLink().GetParent() == 0);
+        TEST(0 == orphan->GetLink().GetChildList().GetSize());
+      }
 
-        assert(f2b); delete f2b; f2b=0;
-        /*
-        XXX:
-        When f2b is not set zero after delete, a second delete causes
-        cString.h:124: failed assertion `refs > 0'! I've been looking
-        for things that trigger this symptom. Yay.
-        @kgn
-        */
-        /* 
-        p should have no parent
-        p should have children f1a and f1b
-        f1a should have parent p
-        f1a should have child f2a
-        f1b should have parent p
-        f1b should have no children
-        f2a should have parent f1a
-        f2a should have no children
-        orphan should have no parent
-        orphan should have no children
-        */
-        {
-          TEST(p->GetLink().GetParent() == 0);
-          TEST(2 == p->GetLink().GetChildList().GetSize());
-          TEST(f1a->GetLink().GetParent() == p);
-          TEST(1 == f1a->GetLink().GetChildList().GetSize());
-          TEST(f1b->GetLink().GetParent() == p);
-          TEST(0 == f1b->GetLink().GetChildList().GetSize());
-          TEST(f2a->GetLink().GetParent() == f1a);
-          TEST(0 == f2a->GetLink().GetChildList().GetSize());
-          TEST(orphan->GetLink().GetParent() == 0);
-          TEST(0 == orphan->GetLink().GetChildList().GetSize());
-        }
+      assert(f2b); delete f2b; f2b=0;
+      /*
+      XXX:
+      When f2b is not set zero after delete, a second delete causes
+      cString.h:124: failed assertion `refs > 0'! I've been looking
+      for things that trigger this symptom. Yay.
+      @kgn
+      */
+      /* 
+      p should have no parent
+      p should have children f1a and f1b
+      f1a should have parent p
+      f1a should have child f2a
+      f1b should have parent p
+      f1b should have no children
+      f2a should have parent f1a
+      f2a should have no children
+      orphan should have no parent
+      orphan should have no children
+      */
+      {
+        TEST(p->GetLink().GetParent() == 0);
+        TEST(2 == p->GetLink().GetChildList().GetSize());
+        TEST(f1a->GetLink().GetParent() == p);
+        TEST(1 == f1a->GetLink().GetChildList().GetSize());
+        TEST(f1b->GetLink().GetParent() == p);
+        TEST(0 == f1b->GetLink().GetChildList().GetSize());
+        TEST(f2a->GetLink().GetParent() == f1a);
+        TEST(0 == f2a->GetLink().GetChildList().GetSize());
+        TEST(orphan->GetLink().GetParent() == 0);
+        TEST(0 == orphan->GetLink().GetChildList().GetSize());
+      }
 
-        assert(f1a); delete f1a; f1a=0;
-        /*
-        XXX:
-        When f2b is not set zero after delete, a second delete causes
-        cString.h:124: failed assertion `refs > 0'! I've been looking
-        for things that trigger this symptom. Yay.
-        @kgn
-        */
-        /* 
-        p should have no parent
-        p should have child f1b
-        f1b should have parent p
-        f1b should have no children
-        f2a should have no parent
-        f2a should have no children
-        orphan should have no parent
-        orphan should have no children
-        */
-        {
-          TEST(p->GetLink().GetParent() == 0);
-          TEST(1 == p->GetLink().GetChildList().GetSize());
-          TEST(f1b->GetLink().GetParent() == p);
-          TEST(0 == f1b->GetLink().GetChildList().GetSize());
-          TEST(f2a->GetLink().GetParent() == 0);
-          TEST(0 == f2a->GetLink().GetChildList().GetSize());
-          TEST(orphan->GetLink().GetParent() == 0);
-          TEST(0 == orphan->GetLink().GetChildList().GetSize());
-        }
-
-        delete orphan;
-        delete f2a;
-        delete f1b;
-        delete p;
+      assert(f1a); delete f1a; f1a=0;
+      /*
+      XXX:
+      When f2b is not set zero after delete, a second delete causes
+      cString.h:124: failed assertion `refs > 0'! I've been looking
+      for things that trigger this symptom. Yay.
+      @kgn
+      */
+      /* 
+      p should have no parent
+      p should have child f1b
+      f1b should have parent p
+      f1b should have no children
+      f2a should have no parent
+      f2a should have no children
+      orphan should have no parent
+      orphan should have no children
+      */
+      {
+        TEST(p->GetLink().GetParent() == 0);
+        TEST(1 == p->GetLink().GetChildList().GetSize());
+        TEST(f1b->GetLink().GetParent() == p);
+        TEST(0 == f1b->GetLink().GetChildList().GetSize());
+        TEST(f2a->GetLink().GetParent() == 0);
+        TEST(0 == f2a->GetLink().GetChildList().GetSize());
+        TEST(orphan->GetLink().GetParent() == 0);
+        TEST(0 == orphan->GetLink().GetChildList().GetSize());
       }
 
-      /* Test cAnalyzeGenotype functions GetParent, HasChild(), UnlinkChild(), GetChildList(). {{{3 */
-      if(true){
-        cAnalyzeGenotype
-          p(AGFactory(*world, "ccc")),
-          f1a(AGFactory(*world, "ccc")),
-          f1b(AGFactory(*world, "ccc")),
-          f2a(AGFactory(*world, "ccc")),
-          f2b(AGFactory(*world, "ccc"));
+      delete orphan;
+      delete f2a;
+      delete f1b;
+      delete p;
+    }
 
-        cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
+    /* Test cAnalyzeGenotype functions GetParent, HasChild(), UnlinkChild(), GetChildList(). {{{3 */
+    if(true){
+      cAnalyzeGenotype
+        p(AGFactory(*world, "ccc")),
+        f1a(AGFactory(*world, "ccc")),
+        f1b(AGFactory(*world, "ccc")),
+        f2a(AGFactory(*world, "ccc")),
+        f2b(AGFactory(*world, "ccc"));
 
-        f1a.LinkParent(&p);
-        f1b.LinkParent(&p);
-        f2a.LinkParent(&f1a);
-        f2b.LinkParent(&f1a);
+      cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
 
-        /* Test GetParent(). */
-        {
-          TEST(p.GetParent() == 0);
-          TEST(f1a.GetParent() == &p);
-          TEST(f1b.GetParent() == &p);
-          TEST(f2a.GetParent() == &f1a);
-          TEST(f2b.GetParent() == &f1a);
-        }
+      f1a.LinkParent(&p);
+      f1b.LinkParent(&p);
+      f2a.LinkParent(&f1a);
+      f2b.LinkParent(&f1a);
 
-        /* Test HasChild(). */
-        {
-          TEST(!p.HasChild(p));
-          TEST(p.HasChild(f1a));
-          TEST(p.HasChild(f1b));
-          TEST(!p.HasChild(f2a));
-          TEST(!p.HasChild(f2b));
+      /* Test GetParent(). */
+      {
+        TEST(p.GetParent() == 0);
+        TEST(f1a.GetParent() == &p);
+        TEST(f1b.GetParent() == &p);
+        TEST(f2a.GetParent() == &f1a);
+        TEST(f2b.GetParent() == &f1a);
+      }
 
-          TEST(!f1a.HasChild(p));
-          TEST(!f1a.HasChild(f1a));
-          TEST(!f1a.HasChild(f1b));
-          TEST(f1a.HasChild(f2a));
-          TEST(f1a.HasChild(f2b));
+      /* Test HasChild(). */
+      {
+        TEST(!p.HasChild(p));
+        TEST(p.HasChild(f1a));
+        TEST(p.HasChild(f1b));
+        TEST(!p.HasChild(f2a));
+        TEST(!p.HasChild(f2b));
 
-          TEST(!f1b.HasChild(p));
-          TEST(!f1b.HasChild(f1a));
-          TEST(!f1b.HasChild(f1b));
-          TEST(!f1b.HasChild(f2a));
-          TEST(!f1b.HasChild(f2b));
+        TEST(!f1a.HasChild(p));
+        TEST(!f1a.HasChild(f1a));
+        TEST(!f1a.HasChild(f1b));
+        TEST(f1a.HasChild(f2a));
+        TEST(f1a.HasChild(f2b));
 
-          TEST(!f2a.HasChild(p));
-          TEST(!f2a.HasChild(f1a));
-          TEST(!f2a.HasChild(f1b));
-          TEST(!f2a.HasChild(f2a));
-          TEST(!f2a.HasChild(f2b));
+        TEST(!f1b.HasChild(p));
+        TEST(!f1b.HasChild(f1a));
+        TEST(!f1b.HasChild(f1b));
+        TEST(!f1b.HasChild(f2a));
+        TEST(!f1b.HasChild(f2b));
 
-          TEST(!f2b.HasChild(p));
-          TEST(!f2b.HasChild(f1a));
-          TEST(!f2b.HasChild(f1b));
-          TEST(!f2b.HasChild(f2a));
-          TEST(!f2b.HasChild(f2b));
-        }
+        TEST(!f2a.HasChild(p));
+        TEST(!f2a.HasChild(f1a));
+        TEST(!f2a.HasChild(f1b));
+        TEST(!f2a.HasChild(f2a));
+        TEST(!f2a.HasChild(f2b));
 
-        /* Test UnlinkChild() and GetChildList(). */
-        {
-          TEST(2 == p.GetChildList().GetSize());
-          TEST(!p.UnlinkChild(p));
-          TEST(2 == p.GetChildList().GetSize());
-          TEST(p.UnlinkChild(f1a));
-          TEST(1 == p.GetChildList().GetSize());
-          TEST(p.UnlinkChild(f1b));
-          TEST(0 == p.GetChildList().GetSize());
-          TEST(!p.UnlinkChild(f2a));
-          TEST(!p.UnlinkChild(f2b));
-          TEST(0 == p.GetChildList().GetSize());
+        TEST(!f2b.HasChild(p));
+        TEST(!f2b.HasChild(f1a));
+        TEST(!f2b.HasChild(f1b));
+        TEST(!f2b.HasChild(f2a));
+        TEST(!f2b.HasChild(f2b));
+      }
 
-          TEST(2 == f1a.GetChildList().GetSize());
-          TEST(!f1a.UnlinkChild(p));
-          TEST(!f1a.UnlinkChild(f1a));
-          TEST(!f1a.UnlinkChild(f1b));
-          TEST(2 == f1a.GetChildList().GetSize());
-          TEST(f1a.UnlinkChild(f2a));
-          TEST(1 == f1a.GetChildList().GetSize());
-          TEST(f1a.UnlinkChild(f2b));
-          TEST(0 == f1a.GetChildList().GetSize());
+      /* Test UnlinkChild() and GetChildList(). */
+      {
+        TEST(2 == p.GetChildList().GetSize());
+        TEST(!p.UnlinkChild(p));
+        TEST(2 == p.GetChildList().GetSize());
+        TEST(p.UnlinkChild(f1a));
+        TEST(1 == p.GetChildList().GetSize());
+        TEST(p.UnlinkChild(f1b));
+        TEST(0 == p.GetChildList().GetSize());
+        TEST(!p.UnlinkChild(f2a));
+        TEST(!p.UnlinkChild(f2b));
+        TEST(0 == p.GetChildList().GetSize());
 
-          TEST(0 == f1b.GetChildList().GetSize());
-          TEST(!f1b.UnlinkChild(p));
-          TEST(!f1b.UnlinkChild(f1a));
-          TEST(!f1b.UnlinkChild(f1b));
-          TEST(!f1b.UnlinkChild(f2a));
-          TEST(!f1b.UnlinkChild(f2b));
-          TEST(0 == f1b.GetChildList().GetSize());
+        TEST(2 == f1a.GetChildList().GetSize());
+        TEST(!f1a.UnlinkChild(p));
+        TEST(!f1a.UnlinkChild(f1a));
+        TEST(!f1a.UnlinkChild(f1b));
+        TEST(2 == f1a.GetChildList().GetSize());
+        TEST(f1a.UnlinkChild(f2a));
+        TEST(1 == f1a.GetChildList().GetSize());
+        TEST(f1a.UnlinkChild(f2b));
+        TEST(0 == f1a.GetChildList().GetSize());
 
-          TEST(0 == f2a.GetChildList().GetSize());
-          TEST(!f2a.UnlinkChild(p));
-          TEST(!f2a.UnlinkChild(f1a));
-          TEST(!f2a.UnlinkChild(f1b));
-          TEST(!f2a.UnlinkChild(f2a));
-          TEST(!f2a.UnlinkChild(f2b));
-          TEST(0 == f2a.GetChildList().GetSize());
+        TEST(0 == f1b.GetChildList().GetSize());
+        TEST(!f1b.UnlinkChild(p));
+        TEST(!f1b.UnlinkChild(f1a));
+        TEST(!f1b.UnlinkChild(f1b));
+        TEST(!f1b.UnlinkChild(f2a));
+        TEST(!f1b.UnlinkChild(f2b));
+        TEST(0 == f1b.GetChildList().GetSize());
 
-          TEST(0 == f2b.GetChildList().GetSize());
-          TEST(!f2b.UnlinkChild(p));
-          TEST(!f2b.UnlinkChild(f1a));
-          TEST(!f2b.UnlinkChild(f1b));
-          TEST(!f2b.UnlinkChild(f2a));
-          TEST(!f2b.UnlinkChild(f2b));
-          TEST(0 == f2b.GetChildList().GetSize());
-        }
-      }
+        TEST(0 == f2a.GetChildList().GetSize());
+        TEST(!f2a.UnlinkChild(p));
+        TEST(!f2a.UnlinkChild(f1a));
+        TEST(!f2a.UnlinkChild(f1b));
+        TEST(!f2a.UnlinkChild(f2a));
+        TEST(!f2a.UnlinkChild(f2b));
+        TEST(0 == f2a.GetChildList().GetSize());
 
-      /* Common test teardown. {{{3 */
-      delete world;
-      /* }}}3 */
-    }
-    cAddTestSuite t("cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink", test);
-  }
-
-
-/* Unit tests. {{{1 */
-  /* cAnalyzeGenotype_UnitTest_HelloWorld {{{2 */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
+        TEST(0 == f2b.GetChildList().GetSize());
+        TEST(!f2b.UnlinkChild(p));
+        TEST(!f2b.UnlinkChild(f1a));
+        TEST(!f2b.UnlinkChild(f1b));
+        TEST(!f2b.UnlinkChild(f2a));
+        TEST(!f2b.UnlinkChild(f2b));
+        TEST(0 == f2b.GetChildList().GetSize());
       }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
     }
-    cAddTestSuite t("cAnalyzeGenotype_UnitTest_HelloWorld", test);
+
+    /* Common test teardown. {{{3 */
+    delete world;
+    /* }}}3 */
   }
+  cAddTestSuite t("cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink", testsuite);
+}
 
-  // }}}1
+namespace nAnalyzeGenotype {
   /*
   This function does nothing;
   but if the compiler sees that this function is called, then the
-  compiler will also connect the above tests to the testing library.
+  compiler will also connect the above testsuites to the testing library.
   */
   void PhysicalLink(){}
 }

Modified: extras/source/testsuites/nChangeList.cpp
===================================================================
--- extras/source/testsuites/nChangeList.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nChangeList.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -2,7 +2,9 @@
 
 #include "cFile.h"
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <iostream>
 #include <fstream>
 
@@ -11,6 +13,7 @@
 /* Tests. */
 namespace nChangeList {
   /* Test-helpers.  */
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -24,74 +27,61 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cChangeList_Archive", s);
   }
+#endif // ENABLE_SERIALIZATION
 
-  /* Unit tests. */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cChangeList_UnitTest_HelloWorld", test);
-  }
+  /*
+  This function does nothing;
+  but if the compiler sees that this function is called, then the
+  compiler will also connect the above testsuites to the testing library.
+  */
+  void PhysicalLink(){}
+}
 
-  namespace UnitTest_Archiving {
-    void test(){
+/* Unit testsuites. */
+namespace cChangeList_UnitTest_Archiving {
+  void testsuite(){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      std::string filename("./cChangeList_basic_serialization.xml");
-      int changelist_size = 10;
-      int change_count = 5;
-      tArray<int> recorded_changes(change_count);
+    std::string filename("./cChangeList_basic_serialization.xml");
+    int changelist_size = 10;
+    int change_count = 5;
+    tArray<int> recorded_changes(change_count);
 
-      {
-        cChangeList cl(changelist_size);
-        TEST(cl.GetSize() == changelist_size);
+    {
+      cChangeList cl(changelist_size);
+      TEST(cl.GetSize() == changelist_size);
 
-        TEST(cl.GetChangeCount() == 0);
-        cl.PushChange(1);
-        cl.PushChange(7);
-        cl.PushChange(3);
-        cl.PushChange(5);
-        cl.PushChange(2);
-        TEST(cl.GetChangeCount() == change_count);
+      TEST(cl.GetChangeCount() == 0);
+      cl.PushChange(1);
+      cl.PushChange(7);
+      cl.PushChange(3);
+      cl.PushChange(5);
+      cl.PushChange(2);
+      TEST(cl.GetChangeCount() == change_count);
 
-        for(int i = 0; i < change_count; i++) {
-          recorded_changes[i] = cl.CheckChangeAt(i);
-        }
-        save_stuff<>(cl, filename.c_str());
+      for(int i = 0; i < change_count; i++) {
+        recorded_changes[i] = cl.CheckChangeAt(i);
       }
+      nChangeList::save_stuff<>(cl, filename.c_str());
+    }
 
-      {
-        cChangeList cl;
-        TEST(cl.GetSize() == 0);
-        TEST(cl.GetChangeCount() == 0);
+    {
+      cChangeList cl;
+      TEST(cl.GetSize() == 0);
+      TEST(cl.GetChangeCount() == 0);
 
-        restore_stuff<>(cl, filename.c_str());
-        TEST(cl.GetChangeCount() == change_count);
-        for(int i = 0; i < change_count; i++) {
-          TEST(recorded_changes[i] == cl.CheckChangeAt(i));
-        }
+      nChangeList::restore_stuff<>(cl, filename.c_str());
+      TEST(cl.GetChangeCount() == change_count);
+      for(int i = 0; i < change_count; i++) {
+        TEST(recorded_changes[i] == cl.CheckChangeAt(i));
       }
+    }
 
-      std::remove(filename.c_str());
+    std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
-    }
-    cAddTestSuite t("cChangeList_UnitTest_Archiving", test);
   }
-
-  /*
-  This function does nothing;
-  but if the compiler sees that this function is called, then the
-  compiler will also connect the above tests to the testing library.
-  */
-  void PhysicalLink(){}
+  cAddTestSuite t("cChangeList_UnitTest_Archiving", testsuite);
 }
 
 

Modified: extras/source/testsuites/nClassName.cpp
===================================================================
--- extras/source/testsuites/nClassName.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nClassName.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -8,15 +8,13 @@
 namespace nClassName {
   /* Unit tests. */
   namespace nUnitTest_HelloWorld {
-    void test(const cStringList &attrs){
-      if(!attrs.HasString("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
+    void test(cTestSettings &settings){
+      if(!settings.HasSetting("HelloWorld")){
+        SKIP("Skipping HelloWorld test");
         return;
       }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
+      cout << "XXX This is a test demo. It needs filling-in. @kgn" << endl;
       TEST(true);
-      TEST(false);
     }
     cAddTestSuite t("cClassName_UnitTest_HelloWorld", test);
   }

Modified: extras/source/testsuites/nConsoleCatcher.cpp
===================================================================
--- extras/source/testsuites/nConsoleCatcher.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nConsoleCatcher.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -4,174 +4,144 @@
 
 using namespace std;
 
-namespace nConsoleCatcher {
 /* Brainstorms. {{{1 */
-  /* cConsoleCatcher_Brainstorm_HelloWorld {{{2 */
-  namespace Brainstorm_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cConsoleCatcher_Brainstorm_HelloWorld", test);
-  }
-  /* cConsoleCatcher_Brainstorm_Design {{{2 */
-  namespace Brainstorm_Design {
-    /*
-    XXX Questions:
-    - What if lots of output is being captured?
-      - Possible answers:
-        - ignore it
-        - discard previous by overwriting
-        - something complicated like storage to temporary file
-          - In which case it might be better to return a cStringList,
-            but still, a single line could grow huge.
-      - How much can be stored in a cString?
-        - A: 4096 characters.
-    */
-    /*
-    XXX Answered:
-    - Better to return cString or cStringList?
-      - A: Decided to return a cString, it's less complex.
-    */
-    /*
-    XXX Done:
-    - cString myConsoleCatcher::Capture(ostream &out);
-    - cString myConsoleCatcher::Release(void);
-    - Verify myConsoleCatcher::Release releases previous stream, if any;
-    - Verify myConsoleCatcher::Release release of null stream doesn't
-      crash;
-    - Verify myConsoleCatcher::Release release of null stream returns
-      empty string;
-    - Verify myConsoleCatcher::myConsoleCatcher() zeros stored onput
-      stream and streambuf;
-    */
+/* cConsoleCatcher_Brainstorm_Design {{{2 */
+namespace cConsoleCatcher_Brainstorm_Design {
+  /*
+  XXX Questions:
+  - What if lots of output is being captured?
+    - Possible answers:
+      - ignore it
+      - discard previous by overwriting
+      - something complicated like storage to temporary file
+        - In which case it might be better to return a cStringList,
+          but still, a single line could grow huge.
+    - How much can be stored in a cString?
+      - A: 4096 characters.
+  */
+  /*
+  XXX Answered:
+  - Better to return cString or cStringList?
+    - A: Decided to return a cString, it's less complex.
+  */
+  /*
+  XXX Done:
+  - cString myConsoleCatcher::Capture(ostream &out);
+  - cString myConsoleCatcher::Release(void);
+  - Verify myConsoleCatcher::Release releases previous stream, if any;
+  - Verify myConsoleCatcher::Release release of null stream doesn't
+    crash;
+  - Verify myConsoleCatcher::Release release of null stream returns
+    empty string;
+  - Verify myConsoleCatcher::myConsoleCatcher() zeros stored onput
+    stream and streambuf;
+  */
 
-    void test(){
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      // Second iteration : cConsoleCatcher
+  void testsuite(){
+    cout << "XXX This is a testsuite demo. It needs filling-in. @kgn" << endl;
+    // Second iteration : cConsoleCatcher
+    {
+      cConsoleCatcher cc;
+
+      /*
+      myConsoleCatcher constructor should zero temporary storage for
+      caught stream.
+      */
       {
-        cConsoleCatcher cc;
+        TEST(0 == cc.m_stream);
+        TEST(0 == cc.m_streambuf);
+      }
 
-        /*
-        myConsoleCatcher constructor should zero temporary storage for
-        caught stream.
-        */
+      /* Basics : Capture and Release a stream. */
+      {
+        cc.Capture(cout);
         {
+          TEST(&cout == cc.m_stream);
+          TEST(0 != cc.m_streambuf);
+        }
+        cout << "hello, world.";
+        cString captured(cc.Release());
+        {
           TEST(0 == cc.m_stream);
           TEST(0 == cc.m_streambuf);
         }
+        //cout << "captured : \"" << captured << "\"." << endl;
 
-        /* Basics : Capture and Release a stream. */
-        {
-          cc.Capture(cout);
-          {
-            TEST(&cout == cc.m_stream);
-            TEST(0 != cc.m_streambuf);
-          }
-          cout << "hello, world.";
-          cString captured(cc.Release());
-          {
-            TEST(0 == cc.m_stream);
-            TEST(0 == cc.m_streambuf);
-          }
-          //cout << "captured : \"" << captured << "\"." << endl;
+        TEST(0 <= captured.Find("hello, world"));
+        TEST(0 > captured.Find("blah"));
+      }
 
-          TEST(0 <= captured.Find("hello, world"));
-          TEST(0 > captured.Find("blah"));
+      /* Basics : Construct-Capture and Release a stream. */
+      {
+        cConsoleCatcher cc2(cout);
+        {
+          TEST(&cout == cc2.m_stream);
+          TEST(0 != cc2.m_streambuf);
         }
-
-        /* Basics : Construct-Capture and Release a stream. */
+        cout << "hello, world.";
+        cString captured(cc2.Release());
         {
-          cConsoleCatcher cc2(cout);
-          {
-            TEST(&cout == cc2.m_stream);
-            TEST(0 != cc2.m_streambuf);
-          }
-          cout << "hello, world.";
-          cString captured(cc2.Release());
-          {
-            TEST(0 == cc2.m_stream);
-            TEST(0 == cc2.m_streambuf);
-          }
-          //cout << "captured : \"" << captured << "\"." << endl;
-
-          TEST(0 <= captured.Find("hello, world"));
-          TEST(0 > captured.Find("blah"));
+          TEST(0 == cc2.m_stream);
+          TEST(0 == cc2.m_streambuf);
         }
+        //cout << "captured : \"" << captured << "\"." << endl;
 
-        /* What happens upon Capture-Capture-Release? */
-        {
-          cc.Capture(cout);
-          cout << "to cout";
-          cString captured_cout(cc.Capture(clog));
-          clog << "to clog";
-          cString captured_clog(cc.Release());
+        TEST(0 <= captured.Find("hello, world"));
+        TEST(0 > captured.Find("blah"));
+      }
 
-          //cout << "captured_cout : \"" << captured_cout << "\"." << endl;
-          //cout << "captured_clog : \"" << captured_clog << "\"." << endl;
+      /* What happens upon Capture-Capture-Release? */
+      {
+        cc.Capture(cout);
+        cout << "to cout";
+        cString captured_cout(cc.Capture(clog));
+        clog << "to clog";
+        cString captured_clog(cc.Release());
 
-          TEST(0 <= captured_cout.Find("to cout"));
-          TEST(0 <= captured_clog.Find("to clog"));
+        //cout << "captured_cout : \"" << captured_cout << "\"." << endl;
+        //cout << "captured_clog : \"" << captured_clog << "\"." << endl;
 
-          TEST(0 > captured_cout.Find("to nowhere"));
-          TEST(0 > captured_clog.Find("to nowhere"));
-        }
+        TEST(0 <= captured_cout.Find("to cout"));
+        TEST(0 <= captured_clog.Find("to clog"));
 
-        /* What happens upon Capture-Release-Release? */
-        {
-          cc.Capture(cout);
-          cout << "to cout";
-          cString captured_cout(cc.Release());
-          /* This should not be captured. */
-          clog << "(this text should go direct to console)" << endl;
-          cString captured_clog(cc.Release());
-
-          //cout << "captured_cout : \"" << captured_cout << "\"." << endl;
-          //cout << "captured_clog : \"" << captured_clog << "\"." << endl;
-
-          TEST(0 <= captured_cout.Find("to cout"));
-          TEST(0 >  captured_clog.Find("to clog"));
-        }
+        TEST(0 > captured_cout.Find("to nowhere"));
+        TEST(0 > captured_clog.Find("to nowhere"));
       }
 
+      /* What happens upon Capture-Release-Release? */
       {
-        cConsoleCatcher cc;
-        /* What happens upon Release without prior capture? */
-        {
-          cString null_captured(cc.Release());
+        cc.Capture(cout);
+        cout << "to cout";
+        cString captured_cout(cc.Release());
+        /* This should not be captured. */
+        clog << "(this text should go direct to console)" << endl;
+        cString captured_clog(cc.Release());
 
-          //cout << "null_captured : \"" << null_captured << "\"." << endl;
+        //cout << "captured_cout : \"" << captured_cout << "\"." << endl;
+        //cout << "captured_clog : \"" << captured_clog << "\"." << endl;
 
-          TEST(null_captured == "");
-          TEST(null_captured != "blah");
-        }
+        TEST(0 <= captured_cout.Find("to cout"));
+        TEST(0 >  captured_clog.Find("to clog"));
       }
     }
-    cAddTestSuite t("cConsoleCatcher_Brainstorm_Design", test);
-  }
 
-/* Unit Tests. {{{1 */
-  /* cConsoleCatcher_UnitTest_HelloWorld {{{2 */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
+    {
+      cConsoleCatcher cc;
+      /* What happens upon Release without prior capture? */
+      {
+        cString null_captured(cc.Release());
+
+        //cout << "null_captured : \"" << null_captured << "\"." << endl;
+
+        TEST(null_captured == "");
+        TEST(null_captured != "blah");
       }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
     }
-    cAddTestSuite t("cConsoleCatcher_UnitTest_HelloWorld", test);
   }
+  cAddTestSuite t("cConsoleCatcher_Brainstorm_Design", testsuite);
+}
 
+namespace nConsoleCatcher {
   // }}}1
   /*
   This function does nothing;

Modified: extras/source/testsuites/nDataEntry.cpp
===================================================================
--- extras/source/testsuites/nDataEntry.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nDataEntry.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -1,7 +1,9 @@
 #include "cDataEntry.h"
 
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <iostream>
 #include <fstream>
 using namespace std;
@@ -11,6 +13,7 @@
   /*
   Test-helpers.
   */
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -24,62 +27,46 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cDataEntry_Archive", s);
   }
+#endif // ENABLE_SERIALIZATION
+  void PhysicalLink(){}
+}
 
-  /* Unit tests. */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cDataEntry_UnitTest_HelloWorld", test);
-  }
-
-  namespace UnitTest_Archiving {
-    void test(){
+/* Unit testsuites. */
+namespace cDataEntry_UnitTest_Archiving {
+  void testsuite(){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      std::string filename("./cDataEntry_basic_serialization.xml");
+    std::string filename("./cDataEntry_basic_serialization.xml");
 
-      // Open cDataEntry_data.txt for reading.
-      cDataEntry d("name", "desc", "null_value", "html_table_flags");
-      cDataEntry d1("n", "d", "nv", "htf");
+    // Open cDataEntry_data.txt for reading.
+    cDataEntry d("name", "desc", "null_value", "html_table_flags");
+    cDataEntry d1("n", "d", "nv", "htf");
 
-      // Sanity checks...
-      TEST(cString("name") == d.GetName());
-      TEST(cString("desc") == d.GetDesc());
-      TEST(cString("null_value") == d.GetNull());
-      TEST(cString("html_table_flags") == d.GetHtmlCellFlags());
+    // Sanity checks...
+    TEST(cString("name") == d.GetName());
+    TEST(cString("desc") == d.GetDesc());
+    TEST(cString("null_value") == d.GetNull());
+    TEST(cString("html_table_flags") == d.GetHtmlCellFlags());
 
-      TEST(cString("n") == d1.GetName());
-      TEST(cString("d") == d1.GetDesc());
-      TEST(cString("nv") == d1.GetNull());
-      TEST(cString("htf") == d1.GetHtmlCellFlags());
+    TEST(cString("n") == d1.GetName());
+    TEST(cString("d") == d1.GetDesc());
+    TEST(cString("nv") == d1.GetNull());
+    TEST(cString("htf") == d1.GetHtmlCellFlags());
 
-      // Save cDataEntry state.
-      save_stuff<>(d, filename.c_str());
-      // Reload state into new cDataEntry.
-      restore_stuff<>(d1, filename.c_str());
+    // Save cDataEntry state.
+    nDataEntry::save_stuff<>(d, filename.c_str());
+    // Reload state into new cDataEntry.
+    nDataEntry::restore_stuff<>(d1, filename.c_str());
 
-      // Check reloaded state.
-      TEST(cString("name") == d1.GetName());
-      TEST(cString("desc") == d1.GetDesc());
-      TEST(cString("null_value") == d1.GetNull());
-      TEST(cString("html_table_flags") == d1.GetHtmlCellFlags());
+    // Check reloaded state.
+    TEST(cString("name") == d1.GetName());
+    TEST(cString("desc") == d1.GetDesc());
+    TEST(cString("null_value") == d1.GetNull());
+    TEST(cString("html_table_flags") == d1.GetHtmlCellFlags());
 
-      std::remove(filename.c_str());
+    std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
-    } 
-    cAddTestSuite t("cDataEntry_UnitTest_Archiving", test);
-  }
-
-  void PhysicalLink(){}
+  } 
+  cAddTestSuite t("cDataEntry_UnitTest_Archiving", testsuite);
 }
-
-

Modified: extras/source/testsuites/nDataFile.cpp
===================================================================
--- extras/source/testsuites/nDataFile.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nDataFile.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -2,7 +2,9 @@
 
 #include "cFile.h"
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <iostream>
 #include <fstream>
 using namespace std;
@@ -10,6 +12,7 @@
 /* Tests. */
 namespace nDataFile {
   /* Test-helpers. {{{1 */
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -23,146 +26,122 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cDataFile_Archive", s);
   }
+#endif // ENABLE_SERIALIZATION
 
-  /* Regrssions. {{{1 */
-  namespace Regression_Ticket1_ {
-    void test(cTestSettings &settings){
-      ERROR("kgn at FIXME - incomplete test -");
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cDataFile_Regression_Ticket1_", test);
-  }
+  void PhysicalLink(){}
+}
 
-  /* Unit tests. {{{1 */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cDataFile_UnitTest_HelloWorld", test);
-  }
-
-  namespace UnitTest_Archiving {
-    void test(){
+/* Unit testsuites. {{{1 */
+namespace cDataFile_UnitTest_Archiving {
+  void testsuite(){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      std::string filename("./cDataFile_basic_serialization.xml");
-      int linecount = 3;
-      std::string data_file_name("./cDataFile_data.txt");
-      cString dfn(data_file_name.c_str());
+    std::string filename("./cDataFile_basic_serialization.xml");
+    int linecount = 3;
+    std::string data_file_name("./cDataFile_data.txt");
+    cString dfn(data_file_name.c_str());
 
-      /*
-      Create a data file object, write two lines of data, archive the
-      data file object ... 
-      */
-      {
-        cDataFile df(dfn);
-        df.WriteComment("Comment!");
-        df.Write(1, "descr1");
-        df.Write(1.0, "descr2");
-        df.Write("blah", "descr3");
-        df.Endl();
-        df.Write(2, "descr1");
-        df.Write(2.0, "descr2");
-        df.Write("blahblah", "descr3");
-        df.Endl();
-        save_stuff<>(df, filename.c_str());
-      }
-      /*
-      Sanity-check contents of file on disk.
-      */
-      {
-        cFile f(dfn);
-        TEST(f.Good());
+    /*
+    Create a data file object, write two lines of data, archive the
+    data file object ... 
+    */
+    {
+      cDataFile df(dfn);
+      df.WriteComment("Comment!");
+      df.Write(1, "descr1");
+      df.Write(1.0, "descr2");
+      df.Write("blah", "descr3");
+      df.Endl();
+      df.Write(2, "descr1");
+      df.Write(2.0, "descr2");
+      df.Write("blahblah", "descr3");
+      df.Endl();
+      nDataFile::save_stuff<>(df, filename.c_str());
+    }
+    /*
+    Sanity-check contents of file on disk.
+    */
+    {
+      cFile f(dfn);
+      TEST(f.Good());
 
-        cString l[7];
-        for(int i = 0; i<7; i++){
-          f.ReadLine(l[i]);
-          //std::cout << "\"" << l[i] << "\"" << std::endl;
-        }
-        TEST(cString("# Comment!") == l[0]);
-        TEST(cString("#  1: descr1") == l[1]);
-        TEST(cString("#  2: descr2") == l[2]);
-        TEST(cString("#  3: descr3") == l[3]);
-        TEST(cString("") == l[4]);
-        TEST(cString("1 1.000000 blah ") == l[5]);
-        TEST(cString("2 2 blahblah ") == l[6]);
+      cString l[7];
+      for(int i = 0; i<7; i++){
+        f.ReadLine(l[i]);
+        //std::cout << "\"" << l[i] << "\"" << std::endl;
       }
-      /*
-      Reload the data file object, write another line of data ...
-      */
-      {
-        cDataFile df;
-        restore_stuff<>(df, filename.c_str());
-        df.Write(3, "descr1");
-        df.Write(3.0, "descr2");
-        df.Write("blahblahblah", "descr3");
-      }
-      /*
-      Verify that a new line was appended to the file on disk.
-      */
-      {
-        cFile f(dfn);
-        TEST(f.Good());
+      TEST(cString("# Comment!") == l[0]);
+      TEST(cString("#  1: descr1") == l[1]);
+      TEST(cString("#  2: descr2") == l[2]);
+      TEST(cString("#  3: descr3") == l[3]);
+      TEST(cString("") == l[4]);
+      TEST(cString("1 1.000000 blah ") == l[5]);
+      TEST(cString("2 2 blahblah ") == l[6]);
+    }
+    /*
+    Reload the data file object, write another line of data ...
+    */
+    {
+      cDataFile df;
+      nDataFilerestore_stuff<>(df, filename.c_str());
+      df.Write(3, "descr1");
+      df.Write(3.0, "descr2");
+      df.Write("blahblahblah", "descr3");
+    }
+    /*
+    Verify that a new line was appended to the file on disk.
+    */
+    {
+      cFile f(dfn);
+      TEST(f.Good());
 
-        cString l[8];
-        for(int i = 0; i<8; i++){
-          f.ReadLine(l[i]);
-          //std::cout << "\"" << l[i] << "\"" << std::endl;
-        }
-        TEST(cString("# Comment!") == l[0]);
-        TEST(cString("#  1: descr1") == l[1]);
-        TEST(cString("#  2: descr2") == l[2]);
-        TEST(cString("#  3: descr3") == l[3]);
-        TEST(cString("") == l[4]);
-        TEST(cString("1 1.000000 blah ") == l[5]);
-        TEST(cString("2 2 blahblah ") == l[6]);
-        TEST(cString("3 3 blahblahblah ") == l[7]);
+      cString l[8];
+      for(int i = 0; i<8; i++){
+        f.ReadLine(l[i]);
+        //std::cout << "\"" << l[i] << "\"" << std::endl;
       }
+      TEST(cString("# Comment!") == l[0]);
+      TEST(cString("#  1: descr1") == l[1]);
+      TEST(cString("#  2: descr2") == l[2]);
+      TEST(cString("#  3: descr3") == l[3]);
+      TEST(cString("") == l[4]);
+      TEST(cString("1 1.000000 blah ") == l[5]);
+      TEST(cString("2 2 blahblah ") == l[6]);
+      TEST(cString("3 3 blahblahblah ") == l[7]);
+    }
 
-      /*
-      Create a new data file object with the same name. This should
-      overwrite the original file on disk.
-      */
-      {
-        cDataFile df(dfn);
-        df.WriteComment("This should be a new file.");
-        df.Write(1, "newdescr");
-        df.Endl();
-      }
-      /*
-      Verify that original file on disk has been overwritten.
-      */
-      {
-        cFile f(dfn);
-        TEST(f.Good());
+    /*
+    Create a new data file object with the same name. This should
+    overwrite the original file on disk.
+    */
+    {
+      cDataFile df(dfn);
+      df.WriteComment("This should be a new file.");
+      df.Write(1, "newdescr");
+      df.Endl();
+    }
+    /*
+    Verify that original file on disk has been overwritten.
+    */
+    {
+      cFile f(dfn);
+      TEST(f.Good());
 
-        cString l[4];
-        for(int i = 0; i<4; i++){
-          f.ReadLine(l[i]);
-          //std::cout << "\"" << l[i] << "\"" << std::endl;
-        }
-        TEST(cString("# This should be a new file.") == l[0]);
-        TEST(cString("#  1: newdescr") == l[1]);
-        TEST(cString("") == l[2]);
-        TEST(cString("1 ") == l[3]);
+      cString l[4];
+      for(int i = 0; i<4; i++){
+        f.ReadLine(l[i]);
+        //std::cout << "\"" << l[i] << "\"" << std::endl;
       }
+      TEST(cString("# This should be a new file.") == l[0]);
+      TEST(cString("#  1: newdescr") == l[1]);
+      TEST(cString("") == l[2]);
+      TEST(cString("1 ") == l[3]);
+    }
 
-      std::remove(filename.c_str());
-      std::remove(data_file_name.c_str());
+    std::remove(filename.c_str());
+    std::remove(data_file_name.c_str());
 #   endif // ENABLE_SERIALIZATION
-    } 
-    cAddTestSuite t("cDataFile_UnitTest_Archiving", test);
-  }
-
-  void PhysicalLink(){}
+  } 
+  cAddTestSuite t("cDataFile_UnitTest_Archiving", testsuite);
 }

Modified: extras/source/testsuites/nFile.cpp
===================================================================
--- extras/source/testsuites/nFile.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nFile.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -2,7 +2,9 @@
 
 #include "cFile.h"
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <iostream>
 #include <fstream>
 using namespace std;
@@ -12,6 +14,7 @@
   /*
   Test-helpers.
   */
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -25,124 +28,109 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cFile_Archive", s);
   }
+#endif // ENABLE_SERIALIZATION
 
-  /* Unit tests. */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cFile_UnitTest_HelloWorld", test);
-  }
+  void PhysicalLink(){}
+}
 
-  namespace UnitTest_Archiving {
-    void test(){
+
+/* Unit testsuites. */
+namespace cFile_UnitTest_Archiving {
+  void testsuite(){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      std::string filename("./cFile_basic_serialization.xml");
-      int linecount = 3;
-      std::string data_file_name("./cFile_data.txt");
-      {
-        std::ofstream data_file(data_file_name.c_str());
-        for(int i = 0; i < linecount; i++){
-          data_file << 2 * i << std::endl;
-        }
+    std::string filename("./cFile_basic_serialization.xml");
+    int linecount = 3;
+    std::string data_file_name("./cFile_data.txt");
+    {
+      std::ofstream data_file(data_file_name.c_str());
+      for(int i = 0; i < linecount; i++){
+        data_file << 2 * i << std::endl;
       }
-      
-      // Open cFile_data.txt for reading.
-      cFile f(data_file_name.c_str());
-      
-      cFile f1, f2, f3;
-      cString s1, s2, s3;
-      cString l1, l2, l3;
-      
-      // Save initial cFile state.
-      save_stuff<>(f, filename.c_str());
-      // Reload initial state into new cFile.
-      restore_stuff<>(f1, filename.c_str());
-  
-      // Save cFile state after reading first line.
-      f.ReadLine(s1);
-      save_stuff<>(f, filename.c_str());
-      // Reload second state into new cFile.
-      restore_stuff<>(f2, filename.c_str());
+    }
     
-      // Save cFile state after reading second line.
-      f.ReadLine(s2);
-      save_stuff<>(f, filename.c_str());
-      // Reload third state into new cFile.
-      restore_stuff<>(f3, filename.c_str());
+    // Open cFile_data.txt for reading.
+    cFile f(data_file_name.c_str());
+    
+    cFile f1, f2, f3;
+    cString s1, s2, s3;
+    cString l1, l2, l3;
+    
+    // Save initial cFile state.
+    nFile::save_stuff<>(f, filename.c_str());
+    // Reload initial state into new cFile.
+    nFile::restore_stuff<>(f1, filename.c_str());
+
+    // Save cFile state after reading first line.
+    f.ReadLine(s1);
+    nFile::save_stuff<>(f, filename.c_str());
+    // Reload second state into new cFile.
+    nFile::restore_stuff<>(f2, filename.c_str());
   
-      f.ReadLine(s3);
-  
-      // Sanity checks...
-      //TEST(false);
-      TEST(cString("0") == s1);
-      TEST(cString("2") == s2);
-      TEST(cString("4") == s3);
-  
-      // Verify reading expected lines from various reloaded states.
-      f3.ReadLine(l3);
-      f2.ReadLine(l2);
-      f1.ReadLine(l1);
-      TEST(l1 == s1);
-      TEST(l2 == s2);
-      TEST(l3 == s3);
-  
-      std::remove(filename.c_str());
-      std::remove(data_file_name.c_str());
+    // Save cFile state after reading second line.
+    f.ReadLine(s2);
+    nFile::save_stuff<>(f, filename.c_str());
+    // Reload third state into new cFile.
+    nFile::restore_stuff<>(f3, filename.c_str());
+
+    f.ReadLine(s3);
+
+    // Sanity checks...
+    TEST(cString("0") == s1);
+    TEST(cString("2") == s2);
+    TEST(cString("4") == s3);
+
+    // Verify reading expected lines from various reloaded states.
+    f3.ReadLine(l3);
+    f2.ReadLine(l2);
+    f1.ReadLine(l1);
+    TEST(l1 == s1);
+    TEST(l2 == s2);
+    TEST(l3 == s3);
+
+    std::remove(filename.c_str());
+    std::remove(data_file_name.c_str());
 #   endif // ENABLE_SERIALIZATION
-    } 
-    cAddTestSuite t("cFile_UnitTest_Archiving", test);
-  }
+  } 
+  cAddTestSuite t("cFile_UnitTest_Archiving", testsuite);
+}
 
-  namespace UnitTest_ArchivingClosedFile {
-    void test(){
+namespace cFile_UnitTest_ArchivingClosedFile {
+  void testsuite(){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      std::string data_file_name("./cFile_data.txt");
-      {
-        std::ofstream data_file(data_file_name.c_str());
-        for(int i = 0; i < 3; i++){
-          data_file << 2 * i << std::endl;
-        }
+    std::string data_file_name("./cFile_data.txt");
+    {
+      std::ofstream data_file(data_file_name.c_str());
+      for(int i = 0; i < 3; i++){
+        data_file << 2 * i << std::endl;
       }
+    }
 
-      std::string filename("./cFile_serialize_closed_file.xml");
+    std::string filename("./cFile_serialize_closed_file.xml");
 
-      // Open cFile_data.txt for reading.
-      cFile f(data_file_name.c_str());
-      // Close file.
-      f.Close();
-      TEST(!f.IsOpen());
+    // Open cFile_data.txt for reading.
+    cFile f(data_file_name.c_str());
+    // Close file.
+    f.Close();
+    TEST(!f.IsOpen());
 
-      cFile f1;
+    cFile f1;
 
-      // Save cFile state.
-      save_stuff<>(f, filename.c_str());
-      // Reload state into new cFile.
-      restore_stuff<>(f1, filename.c_str());
-      // Verify new cFile has matching filename.
-      TEST(f.GetFilename() == f1.GetFilename());
-      // Verify new cFile is closed.
-      TEST(!f1.IsOpen());
+    // Save cFile state.
+    nFile::save_stuff<>(f, filename.c_str());
+    // Reload state into new cFile.
+    nFile::restore_stuff<>(f1, filename.c_str());
+    // Verify new cFile has matching filename.
+    TEST(f.GetFilename() == f1.GetFilename());
+    // Verify new cFile is closed.
+    TEST(!f1.IsOpen());
 
-      std::remove(filename.c_str());
-      std::remove(data_file_name.c_str());
+    std::remove(filename.c_str());
+    std::remove(data_file_name.c_str());
 #   endif // ENABLE_SERIALIZATION
-    } 
-    cAddTestSuite t("cFile_UnitTest_ArchivingClosedFile", test);
-  }
-
-  void PhysicalLink(){}
+  } 
+  cAddTestSuite t("cFile_UnitTest_ArchivingClosedFile", testsuite);
 }
-
-

Modified: extras/source/testsuites/nFixedCoords.cpp
===================================================================
--- extras/source/testsuites/nFixedCoords.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nFixedCoords.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -1,7 +1,9 @@
 #include "cFixedCoords.h"
 
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <fstream>
 #include <iostream>
 using namespace std;
@@ -9,6 +11,7 @@
 /* Tests. */
 namespace nFixedCoords {
   /* Test-helpers.  */
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -22,60 +25,45 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cFixedCoords_Archive", s);
   }
+#endif // ENABLE_SERIALIZATION
 
-  /* Unit tests. */
-  namespace nUnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      /* Make sure testing is working with successes and failures. @kgn */
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cFixedCoords_UnitTest_HelloWorld", test);
-  }
+  void PhysicalLink(){}
+}
 
-  namespace UnitTest_Archiving {
-    void test(){
+/* Unit testsuites. */
+namespace cFixedCoords_UnitTest_Archiving {
+  void testsuite(){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      string filename("./cFixedCoords_basic_serialization.xml");
+    string filename("./cFixedCoords_basic_serialization.xml");
 
-      /*
-      Create and archive a cFixedCoords object.
-      */
-      {
-        cFixedCoords fc;
-        TEST(0 == fc.GetBlockNum());
-        TEST(0 == fc.GetOffset());
-        fc(2,3);
-        TEST(2 == fc.GetBlockNum());
-        TEST(3 == fc.GetOffset());
-        save_stuff<>(fc, filename.c_str());
-      }
-      /*
-      Reload archived cFixedCoords object.
-      */
-      {
-        cFixedCoords fc;
-        TEST(0 == fc.GetBlockNum());
-        TEST(0 == fc.GetOffset());
-        restore_stuff<>(fc, filename.c_str());
-        TEST(2 == fc.GetBlockNum());
-        TEST(3 == fc.GetOffset());
-      }
-
-      remove(filename.c_str());
-#   endif // ENABLE_SERIALIZATION
+    /*
+    Create and archive a cFixedCoords object.
+    */
+    {
+      cFixedCoords fc;
+      TEST(0 == fc.GetBlockNum());
+      TEST(0 == fc.GetOffset());
+      fc(2,3);
+      TEST(2 == fc.GetBlockNum());
+      TEST(3 == fc.GetOffset());
+      nFixedCoords::save_stuff<>(fc, filename.c_str());
     }
-    cAddTestSuite t("cFixedCoords_UnitTest_Archiving", test);
-  } // UnitTest_Archiving
+    /*
+    Reload archived cFixedCoords object.
+    */
+    {
+      cFixedCoords fc;
+      TEST(0 == fc.GetBlockNum());
+      TEST(0 == fc.GetOffset());
+      nFixedCoords::restore_stuff<>(fc, filename.c_str());
+      TEST(2 == fc.GetBlockNum());
+      TEST(3 == fc.GetOffset());
+    }
 
-  void PhysicalLink(){}
-}
-
-
+    remove(filename.c_str());
+#   endif // ENABLE_SERIALIZATION
+  }
+  cAddTestSuite t("cFixedCoords_UnitTest_Archiving", testsuite);
+} // cFixedCoords_UnitTest_Archiving

Added: extras/source/testsuites/nHelloWorld.cpp
===================================================================
--- extras/source/testsuites/nHelloWorld.cpp	                        (rev 0)
+++ extras/source/testsuites/nHelloWorld.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -0,0 +1,15 @@
+#include "cTestLib.h"
+
+/* Tests. */
+/* Unit testsuites. */
+namespace cHelloWorld_DemoTest {
+  void testsuite(cTestSettings &settings){
+    if(!settings.HasSetting("HelloWorld")){
+      SKIP("Skipping because 'HelloWorld' is not enabled;");
+      return;
+    }
+    ERROR("FIXME: This is a demo testsuite. It needs filling-in;");
+    TEST(true);
+  }
+  cAddTestSuite t("cHelloWorld_DemoTest", testsuite);
+}

Modified: extras/source/testsuites/nInitFile.cpp
===================================================================
--- extras/source/testsuites/nInitFile.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nInitFile.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -2,7 +2,9 @@
 
 #include "cFile.h"
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <iostream>
 #include <fstream>
 using namespace std;
@@ -12,6 +14,7 @@
   /*
   Test-helpers.
   */
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -25,74 +28,61 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cInitFile_Archive", s);
   }
+#endif // ENABLE_SERIALIZATION
 
-  /* Unit tests. */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cInitFile_UnitTest_HelloWorld", test);
-  }
+  void PhysicalLink(){}
+}
 
-  namespace UnitTest_Archiving {
-    void test(cTestSettings &settings){
+/* Unit testsuites. */
+namespace cInitFile_UnitTest_Archiving {
+  void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
 #   endif // ENABLE_SERIALIZATION
-    } 
-    cAddTestSuite t("cInitFile_UnitTest_Archiving", test);
-  }
+  } 
+  cAddTestSuite t("cInitFile_UnitTest_Archiving", testsuite);
+}
 
-  namespace UnitTest_ArchivingClosedFile {
-    void test(cTestSettings &settings){
+namespace cInitFile_UnitTest_ArchivingClosedFile {
+  void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
 #   endif // ENABLE_SERIALIZATION
-    } 
-    cAddTestSuite t("cInitFile_UnitTest_ArchivingClosedFile", test);
-  }
+  } 
+  cAddTestSuite t("cInitFile_UnitTest_ArchivingClosedFile", testsuite);
+}
 
-  namespace UnitTest_ReadStringAfterOpenAndClose {
-    void test(cTestSettings &settings){
+namespace cInitFile_UnitTest_ReadStringAfterOpenAndClose {
+  void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      std::string data_file_name("./utInitFile_ReadString_after_open_and_close.cfg");
-      {
-        std::ofstream data_file(data_file_name.c_str());
-        data_file << "TEST_VALUE BLAH" << std::endl;
-        data_file << std::endl;
-      }
+    std::string data_file_name("./utInitFile_ReadString_after_open_and_close.cfg");
+    {
+      std::ofstream data_file(data_file_name.c_str());
+      data_file << "TEST_VALUE BLAH" << std::endl;
+      data_file << std::endl;
+    }
 
-      std::string filename("./cInitFile_serialize_closed_file.xml");
+    std::string filename("./cInitFile_serialize_closed_file.xml");
 
-      // Open cInitFile_data.txt for reading.
-      cInitFile f(data_file_name.c_str());
-      f.Load();
-      f.Compress();
-      f.Close();
+    // Open cInitFile_data.txt for reading.
+    cInitFile f(data_file_name.c_str());
+    f.Load();
+    f.Compress();
+    f.Close();
 
-      const cString keyword("TEST_VALUE");
-      const cString default_val("ICK");
-      const cString loaded_val(f.ReadString(keyword, default_val));
-      const cString expected_val("BLAH");
-      TEST(!f.IsOpen());
-      TEST(loaded_val == expected_val);
+    const cString keyword("TEST_VALUE");
+    const cString default_val("ICK");
+    const cString loaded_val(f.ReadString(keyword, default_val));
+    const cString expected_val("BLAH");
+    TEST(!f.IsOpen());
+    TEST(loaded_val == expected_val);
 
-      std::remove(data_file_name.c_str());
+    std::remove(data_file_name.c_str());
 #   endif // ENABLE_SERIALIZATION
-    } 
-    cAddTestSuite t("cInitFile_UnitTest_ReadStringAfterOpenAndClose", test);
-  }
-
-  void PhysicalLink(){}
+  } 
+  cAddTestSuite t("cInitFile_UnitTest_ReadStringAfterOpenAndClose", testsuite);
 }

Modified: extras/source/testsuites/nRandom.cpp
===================================================================
--- extras/source/testsuites/nRandom.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nRandom.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -1,7 +1,9 @@
 #include "cRandom.h"
 
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <iostream>
 #include <fstream>
 using namespace std;
@@ -11,6 +13,7 @@
   /*
   Test-helpers.
   */
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -24,141 +27,165 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cRandom_Archive", s);
   }
-  
-  /* Unit tests. */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cRandom_UnitTest_HelloWorld", test);
-  }
+#endif // ENABLE_SERIALIZATION
 
-  namespace UnitTest_Archiving {
-    void test(cTestSettings &settings){
+  void PhysicalLink(){}
+}
+
+
+/* Unit testsuites. */
+namespace cRandom_UnitTest_Archiving {
+  void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      { 
-        std::string filename("./cRandom_basic_serialization.xml");
-  
-        // Using seed drawn from date and time.
-        // No, using a problematic seed found.
-        cRandom r(13396544);
-  
-        /*
-        Exercise the random number generator a little bit before saving
-        and restoring.
-        */
-        int seed = r.GetSeed();
-        int original_seed = r.GetOriginalSeed();
-        double d = r.GetDouble();
-        double dm = r.GetDouble(1.0);
-        double dr = r.GetDouble(1.0, 2.0);
-        int i = r.GetInt(100);
-        int ir = r.GetInt(100, 200);
-        bool p = r.P(0.5);
-        bool up = r.uP(0.0000005);
-        double rn = r.GetRandNormal();
-        double rnr = r.GetRandNormal(10.0, 2.0);
-        unsigned int rpnp = r.GetRandPoisson(10.0, 0.5);
-        unsigned int rpm = r.GetRandPoisson(0.5);
-        unsigned int frb = r.GetFullRandBinomial(10.0, 3.0);
-        unsigned int rb = r.GetRandBinomial(10.0, 3.0);
-  
-        /* Save random number generator state.  */
-        save_stuff<>(r, filename.c_str());
-  
-        /* Get some random numbers...  */
-        seed = r.GetSeed();
-        original_seed = r.GetOriginalSeed();
-        d = r.GetDouble();
-        dm = r.GetDouble(1.0);
-        dr = r.GetDouble(1.0, 2.0);
-        i = r.GetInt(100);
-        ir = r.GetInt(100, 200);
-        p = r.P(0.5);
-        up = r.uP(0.0000005);
-        tArray<int> choose(10);
-        r.Choose(100, choose);
-        rn = r.GetRandNormal();
-        rnr = r.GetRandNormal(10.0, 2.0);
-        rpnp = r.GetRandPoisson(10.0, 0.5);
-        rpm = r.GetRandPoisson(0.5);
-        frb = r.GetFullRandBinomial(10.0, 3.0);
-        rb = r.GetRandBinomial(10.0, 3.0);
-  
-        /* Reload saved random number generator state.  */
-        cRandom r2(0);
-        restore_stuff<>(r2, filename.c_str());
-  
-        /*
-        Get some random numbers... Should be the same as those read above.
-        */
-        int seed2 = r2.GetSeed();
-        int original_seed2 = r2.GetOriginalSeed();
-        double d2 = r2.GetDouble();
-        double dm2 = r2.GetDouble(1.0);
-        double dr2 = r2.GetDouble(1.0, 2.0);
-        int i2 = r2.GetInt(100);
-        int ir2 = r2.GetInt(100, 200);
-        bool p2 = r2.P(0.5);
-        bool up2 = r2.uP(0.0000005);
-        tArray<int> choose2(10);
-        r2.Choose(100, choose2);
-        double rn2 = r2.GetRandNormal();
-        double rnr2 = r2.GetRandNormal(10.0, 2.0);
-        unsigned int rpnp2 = r2.GetRandPoisson(10.0, 0.5);
-        unsigned int rpm2 = r2.GetRandPoisson(0.5);
-        unsigned int frb2 = r2.GetFullRandBinomial(10.0, 3.0);
-        unsigned int rb2 = r2.GetRandBinomial(10.0, 3.0);
-  
-        /* Compare results.  */
-        TEST(seed2 == seed);
-        TEST(original_seed2 == original_seed);
-        TEST(d2 == d);
-        TEST(dm2 == dm);
-        TEST(dr2 == dr);
-        TEST(i2 == i);
-        TEST(ir2 == ir);
-        TEST(p2 == p);
-        TEST(up2 == up);
-        for(int i = 0; i < choose.GetSize(); i++){
-          TEST(choose2[i] == choose[i]);
-        }
-        TEST(rn2 == rn);
-        TEST(rnr2 == rnr);
-        TEST(rpnp2 == rpnp);
-        TEST(rpm2 == rpm);
-        //std::cout<<"rnr2: "<<rnr2<<", rnr: "<<rnr<<std::endl;
-        //std::cout<<"rpnp2: "<<rpnp2<<", rpnp: "<<rpnp<<std::endl;
-        //std::cout<<"rpm2: "<<rpm2<<", rpm: "<<rpm<<std::endl;
-        TEST(frb2 == frb);
-        TEST(rb2 == rb);
-  
-        /*
-        Print random number seeds to stdout, in case we run across a seed
-        that breaks things in weird ways.
-        */
-        std::cout << "XXX seed " << seed << ", seed2 " << seed2
-        << ", original_seed " << original_seed << ", original_seed2 "
-        << original_seed2 << std::endl;
-  
-        std::remove(filename.c_str());
+    { 
+      std::string filename("./cRandom_basic_serialization.xml");
+
+      // Using seed drawn from date and time.
+      // No, using a problematic seed found.
+      cRandom r(13396544);
+
+      /*
+      Exercise the random number generator a little bit before saving
+      and restoring.
+      */
+      int seed = r.GetSeed();
+      int original_seed = r.GetOriginalSeed();
+      double d = r.GetDouble();
+      double dm = r.GetDouble(1.0);
+      double dr = r.GetDouble(1.0, 2.0);
+      int i = r.GetInt(100);
+      int ir = r.GetInt(100, 200);
+      bool p = r.P(0.5);
+      bool up = r.uP(0.0000005);
+      double rn = r.GetRandNormal();
+      double rnr = r.GetRandNormal(10.0, 2.0);
+      unsigned int rpnp = r.GetRandPoisson(10.0, 0.5);
+      unsigned int rpm = r.GetRandPoisson(0.5);
+      unsigned int frb = r.GetFullRandBinomial(10.0, 3.0);
+      unsigned int rb = r.GetRandBinomial(10.0, 3.0);
+
+      /* Save random number generator state.  */
+      nRandom::save_stuff<>(r, filename.c_str());
+
+      /* Get some random numbers...  */
+      seed = r.GetSeed();
+      original_seed = r.GetOriginalSeed();
+      d = r.GetDouble();
+      dm = r.GetDouble(1.0);
+      dr = r.GetDouble(1.0, 2.0);
+      i = r.GetInt(100);
+      ir = r.GetInt(100, 200);
+      p = r.P(0.5);
+      up = r.uP(0.0000005);
+      tArray<int> choose(10);
+      r.Choose(100, choose);
+      rn = r.GetRandNormal();
+      rnr = r.GetRandNormal(10.0, 2.0);
+      rpnp = r.GetRandPoisson(10.0, 0.5);
+      rpm = r.GetRandPoisson(0.5);
+      frb = r.GetFullRandBinomial(10.0, 3.0);
+      rb = r.GetRandBinomial(10.0, 3.0);
+
+      /* Reload saved random number generator state.  */
+      cRandom r2(0);
+      nRandom::restore_stuff<>(r2, filename.c_str());
+
+      /*
+      Get some random numbers... Should be the same as those read above.
+      */
+      int seed2 = r2.GetSeed();
+      int original_seed2 = r2.GetOriginalSeed();
+      double d2 = r2.GetDouble();
+      double dm2 = r2.GetDouble(1.0);
+      double dr2 = r2.GetDouble(1.0, 2.0);
+      int i2 = r2.GetInt(100);
+      int ir2 = r2.GetInt(100, 200);
+      bool p2 = r2.P(0.5);
+      bool up2 = r2.uP(0.0000005);
+      tArray<int> choose2(10);
+      r2.Choose(100, choose2);
+      double rn2 = r2.GetRandNormal();
+      double rnr2 = r2.GetRandNormal(10.0, 2.0);
+      unsigned int rpnp2 = r2.GetRandPoisson(10.0, 0.5);
+      unsigned int rpm2 = r2.GetRandPoisson(0.5);
+      unsigned int frb2 = r2.GetFullRandBinomial(10.0, 3.0);
+      unsigned int rb2 = r2.GetRandBinomial(10.0, 3.0);
+
+      /* Compare results.  */
+      TEST(seed2 == seed);
+      TEST(original_seed2 == original_seed);
+      TEST(d2 == d);
+      TEST(dm2 == dm);
+      TEST(dr2 == dr);
+      TEST(i2 == i);
+      TEST(ir2 == ir);
+      TEST(p2 == p);
+      TEST(up2 == up);
+      for(int i = 0; i < choose.GetSize(); i++){
+        TEST(choose2[i] == choose[i]);
       }
+      TEST(rn2 == rn);
+      TEST(rnr2 == rnr);
+      TEST(rpnp2 == rpnp);
+      TEST(rpm2 == rpm);
+      //std::cout<<"rnr2: "<<rnr2<<", rnr: "<<rnr<<std::endl;
+      //std::cout<<"rpnp2: "<<rpnp2<<", rpnp: "<<rpnp<<std::endl;
+      //std::cout<<"rpm2: "<<rpm2<<", rpm: "<<rpm<<std::endl;
+      TEST(frb2 == frb);
+      TEST(rb2 == rb);
+
+      /*
+      Print random number seeds to stdout, in case we run across a seed
+      that breaks things in weird ways.
+      */
+      std::cout << "XXX seed " << seed << ", seed2 " << seed2
+      << ", original_seed " << original_seed << ", original_seed2 "
+      << original_seed2 << std::endl;
+
+      std::remove(filename.c_str());
+    }
 #   endif // ENABLE_SERIALIZATION
+  }
+  cAddTestSuite t("cRandom_UnitTest_Archiving", testsuite);
+}
+
+/* Consistency testsuites. */
+namespace cRandom_ConsistencyTest_RandomIntSequence {
+  void printInternalState(cRandom &r){
+    cout << r.seed << endl;
+    cout << r.original_seed << endl;
+    cout << r.inext << endl;
+    cout << r.inextp << endl;
+    for(int i = 0; i < 56; i++){
+      cout << r.ma[i] << "\t";
     }
-    cAddTestSuite t("cRandom_UnitTest_Archiving", test);
+    cout << endl;
   }
-
-
-  void PhysicalLink(){}
+  void testsuite(cTestSettings &settings){
+    {
+      cRandom r(1);
+      printInternalState(r);
+      r.Get();
+      printInternalState(r);
+    }
+    {
+      cRandom r(1);
+      TEST(715119168 == r.Get());
+      TEST(950102458 == r.Get());
+      TEST(874393600 == r.Get());
+      TEST(534194424 == r.Get());
+      TEST(631586247 == r.Get());
+    }
+    {
+      cRandom r(1);
+      TEST(71 == r.GetInt(100));
+      TEST(95 == r.GetInt(100));
+      TEST(87 == r.GetInt(100));
+      TEST(53 == r.GetInt(100));
+      TEST(63 == r.GetInt(100));
+    }
+  }
+  cAddTestSuite t("cRandom_ConsistencyTest_RandomIntSequence", testsuite);
 }
-
-

Modified: extras/source/testsuites/nString.cpp
===================================================================
--- extras/source/testsuites/nString.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nString.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -1,7 +1,9 @@
 #include "cString.h"
 
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <iostream>
 #include <fstream>
 using namespace std;
@@ -11,6 +13,7 @@
   /*
   Test-helpers.
   */
+#if ENABLE_SERIALIZATION
   class Helper {
   public:
     cString m_s1, m_s2;
@@ -43,192 +46,176 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("s", s);
   }
+#endif // ENABLE_SERIALIZATION
 
-  /* Unit tests. */
-  namespace nUnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cString_UnitTest_HelloWorld", test);
-  }
+  void PhysicalLink(){}
+}
 
-  namespace FunctionalTest_StringManip {
-    void test(cTestSettings &settings){
-      cString test_str("string is string 321");
-      TEST(test_str.Replace("ring", "rung", 9) != -1);
-      TEST(test_str[3] == 'i');
-      TEST(test_str[13] == 'u');
-      TEST(test_str.PopWord() == "string");
-      TEST(test_str.Pop('s') == "i");
-      TEST(test_str.LeftJustify() == 1);
-      test_str.Reverse();
-      TEST(test_str == "123 gnurts");
-      TEST(test_str.GetWord(1) == "gnurts");
-      TEST(test_str.GetWordAt(6) == "urts");
-      TEST(test_str.ToUpper() == "123 GNURTS");
-      TEST(test_str.IsWhitespace(2) == false);
-      TEST(test_str.IsWhitespace(3) == true);
-      TEST(test_str.IsWhitespace(4) == false);
-      TEST(test_str.CountNumWords() == 2);
-      TEST(test_str.PopWord().AsInt() == 123);
-      TEST(test_str.Find('T') == 4);
-      TEST((test_str += " 4fun") == "GNURTS 4fun");
-      TEST(test_str.ToLower() == "gnurts 4fun");
-      TEST(test_str.Insert("  should r", 3, 6) == "gnu  should run");
-      TEST(test_str.ClipEnd(3) == "gnu  should ");
-      test_str.CompressWhitespace();
-      TEST(test_str == "gnu should");
-      test_str.RemoveChar('u');
-      TEST(test_str == "gn shold");
-    }
-    cAddTestSuite t("cString_FunctionalTest_StringManip", test);
+/* Unit tests. */
+namespace cString_FunctionalTest_StringManip {
+  void testsuite(cTestSettings &settings){
+    cString test_str("string is string 321");
+    TEST(test_str.Replace("ring", "rung", 9) != -1);
+    TEST(test_str[3] == 'i');
+    TEST(test_str[13] == 'u');
+    TEST(test_str.PopWord() == "string");
+    TEST(test_str.Pop('s') == "i");
+    TEST(test_str.LeftJustify() == 1);
+    test_str.Reverse();
+    TEST(test_str == "123 gnurts");
+    TEST(test_str.GetWord(1) == "gnurts");
+    TEST(test_str.GetWordAt(6) == "urts");
+    TEST(test_str.ToUpper() == "123 GNURTS");
+    TEST(test_str.IsWhitespace(2) == false);
+    TEST(test_str.IsWhitespace(3) == true);
+    TEST(test_str.IsWhitespace(4) == false);
+    TEST(test_str.CountNumWords() == 2);
+    TEST(test_str.PopWord().AsInt() == 123);
+    TEST(test_str.Find('T') == 4);
+    TEST((test_str += " 4fun") == "GNURTS 4fun");
+    TEST(test_str.ToLower() == "gnurts 4fun");
+    TEST(test_str.Insert("  should r", 3, 6) == "gnu  should run");
+    TEST(test_str.ClipEnd(3) == "gnu  should ");
+    test_str.CompressWhitespace();
+    TEST(test_str == "gnu should");
+    test_str.RemoveChar('u');
+    TEST(test_str == "gn shold");
   }
-  
-  namespace UnitTest_Archiving {
-    void test(cTestSettings &settings){
+  cAddTestSuite t("cString_FunctionalTest_StringManip", testsuite);
+}
+
+namespace cString_UnitTest_Archiving {
+  void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      { 
-        TEST(true);
-        std::string filename("./cString_basic_serialization.xml");
-  
-        TEST(0 == Helper::s_instance_ct);
-        Helper *a(new Helper);
-        TEST(1 == Helper::s_instance_ct);
-  
-        /*
-        Both instances of cString should share a single cStringData instance.
-        */
-        TEST(cString("blah.") == a->m_s1);
-        TEST(cString("blah.") == a->m_s2);
-        const char *s1(a->m_s1);
-        const char *s2(a->m_s2);
-        TEST(s1 == s2);
-  
-        /*
-        Both pointers should point to one cString instance.
-        */
-        TEST(cString("ick.") == *a->m_ps1);
-        TEST(cString("ick.") == *a->m_ps2);
-        const char *s3(*a->m_ps1);
-        const char *s4(*a->m_ps2);
-        TEST(s3 == s4);
-  
-        save_stuff<>(a, filename.c_str());
-        delete a;
-        TEST(0 == Helper::s_instance_ct);
-  
-        restore_stuff<>(a, filename.c_str());
-        TEST(1 == Helper::s_instance_ct);
-  
-        /*
-        Both instances of cString should share a single cStringData instance.
-        */
-        TEST(cString("blah.") == a->m_s1);
-        TEST(cString("blah.") == a->m_s2);
-        /*
-        We have decided to not track cStringData instance sharing;
-        consequently we now expect that if two strings sharing data are
-        both saved and then reloaded, the reloaded versions no longer
-        share data.
-        This prevents a certain kind of memory leak.
-        @kgn
-        */
-        const char *s5(a->m_s1);
-        const char *s6(a->m_s2);
-        TEST(s5 != s6);
-  
-        /*
-        Both pointers should point to one cString instance.
-        */
-        TEST(cString("ick.") == *a->m_ps1);
-        TEST(cString("ick.") == *a->m_ps2);
-        const char *s7(*a->m_ps1);
-        const char *s8(*a->m_ps2);
-        TEST(s7 == s8);
-  
-        delete a;
-        TEST(0 == Helper::s_instance_ct);
-  
-        std::remove(filename.c_str());
-      }
-      {
-        TEST(true);
-        std::string filename("./cString_basic_serialization_2.xml");
-  
-        TEST(0 == Helper::s_instance_ct);
-        Helper *a(new Helper);
-        TEST(1 == Helper::s_instance_ct);
-  
-        /*
-        Both instances of cString were sharing a single cStringData
-        instance, but assigning a new string to the first should create a
-        new, unshared cStringData instance; so now each cString should
-        have its own cStringData.
-        */
-        a->m_s1 = "bleah.";
-        TEST(cString("bleah.") == a->m_s1);
-        TEST(cString("blah.") == a->m_s2);
-        const char *s1(a->m_s1);
-        const char *s2(a->m_s2);
-        TEST(s1 != s2);
-  
-        /*
-        Both pointers should point to one cString instance.
-        */
-        *a->m_ps1 = "ack.";
-        TEST(cString("ack.") == *a->m_ps1);
-        TEST(cString("ack.") == *a->m_ps2);
-        const char *s3(*a->m_ps1);
-        const char *s4(*a->m_ps2);
-        TEST(s3 == s4);
-  
-        save_stuff<>(a, filename.c_str());
-        delete a;
-        TEST(0 == Helper::s_instance_ct);
-  
-        restore_stuff<>(a, filename.c_str());
-        TEST(1 == Helper::s_instance_ct);
-  
-        /*
-        Each cString should have its own cStringData.
-        */
-        TEST(cString("bleah.") == a->m_s1);
-        TEST(cString("blah.") == a->m_s2);
-        const char *s5(a->m_s1);
-        const char *s6(a->m_s2);
-        TEST(s5 != s6);
-  
-        /*
-        Both pointers should point to one cString instance.
-        */
-        TEST(cString("ack.") == *a->m_ps1);
-        TEST(cString("ack.") == *a->m_ps2);
-        const char *s7(*a->m_ps1);
-        const char *s8(*a->m_ps2);
-        TEST(s7 == s8);
-  
-  
-        delete a;
-        TEST(0 == Helper::s_instance_ct);
-  
-        std::remove(filename.c_str());
-      }
-#   endif // ENABLE_SERIALIZATION
+    { 
+      TEST(true);
+      std::string filename("./cString_basic_serialization.xml");
+
+      TEST(0 == nString::Helper::s_instance_ct);
+      nString::Helper *a(new nString::Helper);
+      TEST(1 == nString::Helper::s_instance_ct);
+
+      /*
+      Both instances of cString should share a single cStringData instance.
+      */
+      TEST(cString("blah.") == a->m_s1);
+      TEST(cString("blah.") == a->m_s2);
+      const char *s1(a->m_s1);
+      const char *s2(a->m_s2);
+      TEST(s1 == s2);
+
+      /*
+      Both pointers should point to one cString instance.
+      */
+      TEST(cString("ick.") == *a->m_ps1);
+      TEST(cString("ick.") == *a->m_ps2);
+      const char *s3(*a->m_ps1);
+      const char *s4(*a->m_ps2);
+      TEST(s3 == s4);
+
+      nString::save_stuff<>(a, filename.c_str());
+      delete a;
+      TEST(0 == nString::Helper::s_instance_ct);
+
+      nString::restore_stuff<>(a, filename.c_str());
+      TEST(1 == nString::Helper::s_instance_ct);
+
+      /*
+      Both instances of cString should share a single cStringData instance.
+      */
+      TEST(cString("blah.") == a->m_s1);
+      TEST(cString("blah.") == a->m_s2);
+      /*
+      We have decided to not track cStringData instance sharing;
+      consequently we now expect that if two strings sharing data are
+      both saved and then reloaded, the reloaded versions no longer
+      share data.
+      This prevents a certain kind of memory leak.
+      @kgn
+      */
+      const char *s5(a->m_s1);
+      const char *s6(a->m_s2);
+      TEST(s5 != s6);
+
+      /*
+      Both pointers should point to one cString instance.
+      */
+      TEST(cString("ick.") == *a->m_ps1);
+      TEST(cString("ick.") == *a->m_ps2);
+      const char *s7(*a->m_ps1);
+      const char *s8(*a->m_ps2);
+      TEST(s7 == s8);
+
+      delete a;
+      TEST(0 == nString::Helper::s_instance_ct);
+
+      std::remove(filename.c_str());
     }
-    cAddTestSuite t("cString_UnitTest_Archiving", test);
-  } // utString_archiving
+    {
+      TEST(true);
+      std::string filename("./cString_basic_serialization_2.xml");
 
+      TEST(0 == nString::Helper::s_instance_ct);
+      nString::Helper *a(new nString::Helper);
+      TEST(1 == nString::Helper::s_instance_ct);
 
-  void PhysicalLink(){}
-}
+      /*
+      Both instances of cString were sharing a single cStringData
+      instance, but assigning a new string to the first should create a
+      new, unshared cStringData instance; so now each cString should
+      have its own cStringData.
+      */
+      a->m_s1 = "bleah.";
+      TEST(cString("bleah.") == a->m_s1);
+      TEST(cString("blah.") == a->m_s2);
+      const char *s1(a->m_s1);
+      const char *s2(a->m_s2);
+      TEST(s1 != s2);
 
+      /*
+      Both pointers should point to one cString instance.
+      */
+      *a->m_ps1 = "ack.";
+      TEST(cString("ack.") == *a->m_ps1);
+      TEST(cString("ack.") == *a->m_ps2);
+      const char *s3(*a->m_ps1);
+      const char *s4(*a->m_ps2);
+      TEST(s3 == s4);
 
+      nString::save_stuff<>(a, filename.c_str());
+      delete a;
+      TEST(0 == nString::Helper::s_instance_ct);
+
+      nString::restore_stuff<>(a, filename.c_str());
+      TEST(1 == nString::Helper::s_instance_ct);
+
+      /*
+      Each cString should have its own cStringData.
+      */
+      TEST(cString("bleah.") == a->m_s1);
+      TEST(cString("blah.") == a->m_s2);
+      const char *s5(a->m_s1);
+      const char *s6(a->m_s2);
+      TEST(s5 != s6);
+
+      /*
+      Both pointers should point to one cString instance.
+      */
+      TEST(cString("ack.") == *a->m_ps1);
+      TEST(cString("ack.") == *a->m_ps2);
+      const char *s7(*a->m_ps1);
+      const char *s8(*a->m_ps2);
+      TEST(s7 == s8);
+
+
+      delete a;
+      TEST(0 == nString::Helper::s_instance_ct);
+
+      std::remove(filename.c_str());
+    }
+#   endif // ENABLE_SERIALIZATION
+  }
+  cAddTestSuite t("cString_UnitTest_Archiving", testsuite);
+} // utString_archiving

Modified: extras/source/testsuites/nStringList.cpp
===================================================================
--- extras/source/testsuites/nStringList.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nStringList.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -2,7 +2,9 @@
 #include "cStringIterator.h"
 
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include <iostream>
 #include <fstream>
 using namespace std;
@@ -12,6 +14,7 @@
   /*
   Test-helpers.
   */
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -25,90 +28,75 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("cStringList_Archive", s);
   }
-  
-  /* Unit tests. */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cStringList_UnitTest_HelloWorld", test);
-  }
+#endif // ENABLE_SERIALIZATION
 
-  namespace UnitTest_Archiving {
-    void test() {
+  void PhysicalLink(){}
+}
+
+/* Unit tests. */
+namespace cStringList_UnitTest_Archiving {
+  void testsuite() {
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+    SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
-      char numstr[] = "number 0";
-      cString s;
-      cStringList sl;
-      cStringIterator it(sl);
-      std::string filename("./cStringList_basic_serialization.xml");
-      int i, listsize = 10;
-      
-      /*
-      Construct basic list.
-      */
-      TEST(0 == sl.GetSize());
-      for(i=0; i<listsize; i++){
-        numstr[7] = '0' + i; 
-        s = cString(numstr);
-        sl.PushRear(s);
-      }
-      TEST(listsize == sl.GetSize());
+    char numstr[] = "number 0";
+    cString s;
+    cStringList sl;
+    cStringIterator it(sl);
+    std::string filename("./cStringList_basic_serialization.xml");
+    int i, listsize = 10;
     
-      /*
-      Verify basic list contents.
-      */
-      it.Reset();
-      for(i=0; !it.AtEnd(); i++){
-        s = it.Next();
-        numstr[7] = '0' + i;
-        TEST(cString(numstr) == s);
-      }
-      TEST(i == listsize);
+    /*
+    Construct basic list.
+    */
+    TEST(0 == sl.GetSize());
+    for(i=0; i<listsize; i++){
+      numstr[7] = '0' + i; 
+      s = cString(numstr);
+      sl.PushRear(s);
+    }
+    TEST(listsize == sl.GetSize());
+  
+    /*
+    Verify basic list contents.
+    */
+    it.Reset();
+    for(i=0; !it.AtEnd(); i++){
+      s = it.Next();
+      numstr[7] = '0' + i;
+      TEST(cString(numstr) == s);
+    }
+    TEST(i == listsize);
 
-      /*
-      Save basic list.
-      */
-      save_stuff<>(sl, filename.c_str());
-      sl.Clear();
-      TEST(0 == sl.GetSize());
+    /*
+    Save basic list.
+    */
+    nStringList::save_stuff<>(sl, filename.c_str());
+    sl.Clear();
+    TEST(0 == sl.GetSize());
 
-      /*
-      Reload basic list.
-      */
-      restore_stuff<>(sl, filename.c_str());
-      TEST(listsize == sl.GetSize());
+    /*
+    Reload basic list.
+    */
+    nStringList::restore_stuff<>(sl, filename.c_str());
+    TEST(listsize == sl.GetSize());
 
-      /*
-      Verify contents of reloaded basic list.
-      */
-      it.Reset();
-      for(i=0; !it.AtEnd(); i++){
-        s = it.Next();
-        numstr[7] = '0' + i;
-        TEST(cString(numstr) == s);
-      }
-      TEST(i == listsize);
-
-      sl.Clear();
-      TEST(0 == sl.GetSize());
-
-      std::remove(filename.c_str());
-#   endif // ENABLE_SERIALIZATION
+    /*
+    Verify contents of reloaded basic list.
+    */
+    it.Reset();
+    for(i=0; !it.AtEnd(); i++){
+      s = it.Next();
+      numstr[7] = '0' + i;
+      TEST(cString(numstr) == s);
     }
-    cAddTestSuite t("cStringList_UnitTest_Archiving", test);
-  } // utStringList_archiving
+    TEST(i == listsize);
 
-  void PhysicalLink(){}
-}
+    sl.Clear();
+    TEST(0 == sl.GetSize());
 
-
+    std::remove(filename.c_str());
+#   endif // ENABLE_SERIALIZATION
+  }
+  cAddTestSuite t("cStringList_UnitTest_Archiving", testsuite);
+} // cStringList_UnitTest_Archiving

Modified: extras/source/testsuites/nTemplate.cpp
===================================================================
--- extras/source/testsuites/nTemplate.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nTemplate.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -1,5 +1,7 @@
 #include "cTestLib.h"
-#include "cXMLArchive.h"
+#if ENABLE_SERIALIZATION
+#  include "cXMLArchive.h"
+#endif // ENABLE_SERIALIZATION
 #include "tArray.h"
 #include "tBuffer.h"
 #include "tDictionary.h"
@@ -31,11 +33,13 @@
       m_j = in.m_j;
       return *this;
     }
+#if ENABLE_SERIALIZATION
     template<class Archive>
     void serialize(Archive & a, const unsigned int version){
       a.ArkvObj("m_i", m_i);
       a.ArkvObj("m_j", m_j);
     } 
+#endif // ENABLE_SERIALIZATION
   };  
   // ostream output, needed for tHashTable::OK()
   std::ostream& operator << (std::ostream& out, const A & a){
@@ -43,6 +47,7 @@
     return out;
   }
       
+#if ENABLE_SERIALIZATION
   template <class T>
   void save_stuff(const T &s, const char * filename){
     std::ofstream ofs(filename);
@@ -56,24 +61,11 @@
     cXMLIArchive ia(ifs);
     ia.ArkvObj("TemplateTest", s);
   }   
+#endif // ENABLE_SERIALIZATION
     
   /* Unit tests. */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("nTemplate_UnitTest_HelloWorld", test);
-  }
-
   namespace UnitTest_tMemTrack {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
         return;
@@ -92,13 +84,13 @@
       TEST(0 == tMemTrack<A>::Instances());
       
     }
-    cAddTestSuite t("nTemplate_UnitTest_tMemTrack", test);
+    cAddTestSuite t("nTemplate_UnitTest_tMemTrack", testsuite);
   }
   
   namespace UnitTest_tListBasicSerialization {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -172,13 +164,13 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tListBasicSerialization", test);
+    cAddTestSuite t("nTemplate_UnitTest_tListBasicSerialization", testsuite);
   }
   
   namespace UnitTest_tListArchiveStructure {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -285,13 +277,13 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tListArchiveStructure", test);
+    cAddTestSuite t("nTemplate_UnitTest_tListArchiveStructure", testsuite);
   }
 
   namespace UnitTest_tArraysOfPointers {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -310,13 +302,13 @@
       TEST(0 == tMemTrack<A>::Instances());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tArraysOfPointers", test);
+    cAddTestSuite t("nTemplate_UnitTest_tArraysOfPointers", testsuite);
   }
 
   namespace UnitTest_tArrayBasicSerialization {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -369,13 +361,13 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tArrayBasicSerialization", test);
+    cAddTestSuite t("nTemplate_UnitTest_tArrayBasicSerialization", testsuite);
   }
   
   namespace UnitTest_tHashTableBasicSerialization {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -452,13 +444,13 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tHashTableBasicSerialization", test);
+    cAddTestSuite t("nTemplate_UnitTest_tHashTableBasicSerialization", testsuite);
   }
 
   namespace UnitTest_tDictionaryBasicSerialization {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -536,13 +528,13 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tDictionaryBasicSerialization", test);
+    cAddTestSuite t("nTemplate_UnitTest_tDictionaryBasicSerialization", testsuite);
   }
 
   namespace UnitTest_tBufferBasicSerialization {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       std::string filename("./tBuffer_basic_serialization.xml");
       A a;
@@ -609,13 +601,13 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tBufferBasicSerialization", test);
+    cAddTestSuite t("nTemplate_UnitTest_tBufferBasicSerialization", testsuite);
   }
 
   namespace UnitTest_tManagedPointerArrayBasicSerialization {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -668,13 +660,13 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tManagedPointerArrayBasicSerialization", test);
+    cAddTestSuite t("nTemplate_UnitTest_tManagedPointerArrayBasicSerialization", testsuite);
   }
 
   namespace UnitTest_tSmartArrayBasicSerialization {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -727,13 +719,13 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tSmartArrayBasicSerialization", test);
+    cAddTestSuite t("nTemplate_UnitTest_tSmartArrayBasicSerialization", testsuite);
   }
 
   namespace UnitTest_tMatrixBasicSerialization {
-    void test(cTestSettings &settings){
+    void testsuite(cTestSettings &settings){
 #   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
+      SKIP("Test skipped because serialization is disabled");
 #   else // ENABLE_SERIALIZATION
       if(!settings.HasSetting("tMemTrack")){
         cout << "FIXME Skipping test requiring tMemTrack." << endl;
@@ -795,7 +787,7 @@
       std::remove(filename.c_str());
 #   endif // ENABLE_SERIALIZATION
     }
-    cAddTestSuite t("nTemplate_UnitTest_tMatrixBasicSerialization", test);
+    cAddTestSuite t("nTemplate_UnitTest_tMatrixBasicSerialization", testsuite);
   }
 
   void PhysicalLink(){}

Modified: extras/source/testsuites/nTestDriver.cpp
===================================================================
--- extras/source/testsuites/nTestDriver.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nTestDriver.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -7,327 +7,241 @@
 
 using namespace std;
 
-namespace nTestDriver {
 /* To-Do. {{{1 */
-  namespace ToDo {
-    void test(){
-      ERROR("kgn at FIXME : bugfix needed : option 'Quiet' now causes crashes, I think because it collides with @cao's 'nonverbose' setting for Avida -");
-    }
-    cAddTestSuite t("cTestDriver_ToDo", test);
+namespace cTestDriver_ToDo {
+  void testsuite(){
   }
+  cAddTestSuite t("cTestDriver_ToDo", testsuite);
+}
 
-/* Brainstorms. {{{1 */
-  /* cTestDriver_Brainstorm_HelloWorld {{{2 */
-  namespace Brainstorm_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cTestDriver_Brainstorm_HelloWorld", test);
+/* Functional Tests. {{{1 */
+/* cTestDriver_FunctionalTest_Settings {{{2 */
+namespace cTestDriver_FunctionalTest_Settings {
+  bool has_setting;
+  cString setting_value;
+  void testrunner(cTestSettings &settings){
+    has_setting = settings.HasSetting("TestSettings");
+    setting_value = settings.Setting("TestSettings");
   }
+  void testsuite(){
+    cStringList args;
+    cTestDriver td;
 
-/* Functional Tests. {{{1 */
-  /* cTestDriver_FunctionalTest_Settings {{{2 */
-  namespace FunctionalTest_Settings {
-    bool has_setting;
-    cString setting_value;
-    void testrunner(cTestSettings &settings){
-      has_setting = settings.HasSetting("TestSettings");
-      setting_value = settings.Setting("TestSettings");
-    }
-    void test(){
-      cStringList args;
-      cTestDriver td;
+    cTestLib::getLib().reg(
+      "cTestDriver_FunctionalTest_Settings_subtest",
+      testrunner
+    );
 
-      cTestLib::getLib().reg(
-        "cTestDriver_FunctionalTest_Settings_subtest",
-        testrunner
-      );
+    args.Clear();
+    args.PushRear("--set-TestSettings-blah");
+    args.PushRear("cTestDriver_FunctionalTest_Settings_subtest");
+    td.Tests(args);
+    TEST(has_setting);
+    TEST(setting_value == "blah");
 
-      args.Clear();
-      args.PushRear("Set_TestSettings_blah");
-      args.PushRear("cTestDriver_FunctionalTest_Settings_subtest");
-      td.Tests(args);
-      TEST(has_setting);
-      TEST(setting_value == "blah");
+    args.Clear();
+    args.PushRear("--unset-TestSettings");
+    args.PushRear("cTestDriver_FunctionalTest_Settings_subtest");
+    td.Tests(args);
+    TEST(!has_setting);
+    TEST(setting_value == "");
 
-      args.Clear();
-      args.PushRear("Unset_TestSettings");
-      args.PushRear("cTestDriver_FunctionalTest_Settings_subtest");
-      td.Tests(args);
-      TEST(!has_setting);
-      TEST(setting_value == "");
-
-      cTestLib::getLib().unreg("cTestDriver_FunctionalTest_Settings_subtest");
-    }
-    cAddTestSuite t("cTestDriver_FunctionalTest_Settings", test);
+    cTestLib::getLib().unreg("cTestDriver_FunctionalTest_Settings_subtest");
   }
+  cAddTestSuite t("cTestDriver_FunctionalTest_Settings", testsuite);
+}
 
-  /* cTestDriver_FunctionalTest_AlteringErrorCount {{{2 */
-  namespace FunctionalTest_AlteringErrorCount {
-    void test(cTestSettings &settings){
-      int original_error_count, new_error_count;
+/* cTestDriver_FunctionalTest_AlteringErrorCount {{{2 */
+namespace cTestDriver_FunctionalTest_AlteringErrorCount {
+  void testsuite(cTestSettings &settings){
+    int original_error_count, new_error_count;
 
-      original_error_count = test_errors();
+    original_error_count = testing_errors();
 
-      cConsoleCatcher cc;
-      cc.Capture(cerr);
-      {
-        cerr << "... (the following test fails on purpose; saving error count of ";
-        cerr << original_error_count << ") ..." << endl;
-        bool fail_on_purpose = false;
-        TEST(fail_on_purpose);
-        new_error_count = test_errors();
-        TEST(original_error_count < new_error_count);
-        --test_errors();
-        new_error_count = test_errors();
-        test_errors() = original_error_count;
-        cerr << "... (error count restored to ";
-        cerr << original_error_count << ") ..." << endl;
-      }
-      cString captured(cc.Release());
-
-      TEST(0 <= captured.Find("test 'fail_on_purpose' failed"));
+    cConsoleCatcher cc;
+    cc.Capture(cerr);
+    {
+      cerr << "... (the following test fails on purpose; saving error count of ";
+      cerr << original_error_count << ") ..." << endl;
+      bool fail_on_purpose = false;
+      TEST(fail_on_purpose);
+      new_error_count = testing_errors();
+      TEST(original_error_count < new_error_count);
+//        --testing_errors();
+      new_error_count = testing_errors();
+      testing_errors() = original_error_count;
+      cerr << "... (error count restored to ";
+      cerr << original_error_count << ") ..." << endl;
     }
-    cAddTestSuite t("cTestDriver_FunctionalTest_AlteringErrorCount", test);
+    cString captured(cc.Release());
+
+    TEST(0 <= captured.Find("test 'fail_on_purpose' failed"));
   }
+  cAddTestSuite t("cTestDriver_FunctionalTest_AlteringErrorCount", testsuite);
+}
 
 /* Regressions. {{{1 */
-  /* cTestDriver_Regression_SomeTestSuitesNotProperlyMatched {{{2 */
-  namespace Regression_SomeTestSuitesNotProperlyMatched {
+/* cTestDriver_Regression_SomeTestSuitesNotProperlyMatched {{{2 */
+namespace cTestDriver_Regression_SomeTestSuitesNotProperlyMatched {
 
-    bool t1_called, t2_called, t3_called, t4_called;
+  bool t1_called, t2_called, t3_called, t4_called;
 
-    void t1WithAttrs(cTestSettings &settings){ t1_called = true; }
-    void t2WithAttrs(cTestSettings &settings){ t2_called = true; }
-    void t3WithoutAttrs(){ t3_called = true; }
-    void t4WithoutAttrs(){ t4_called = true; }
+  void t1WithAttrs(cTestSettings &settings){ t1_called = true; }
+  void t2WithAttrs(cTestSettings &settings){ t2_called = true; }
+  void t3WithoutAttrs(){ t3_called = true; }
+  void t4WithoutAttrs(){ t4_called = true; }
 
-    void test(cTestSettings &settings){
-      cStringList args;
-      cTestDriver td;
+  void testsuite(cTestSettings &settings){
+    cStringList args;
+    cTestDriver td;
 
-      int saved_error_count;
+    int saved_error_count;
 
-      /* Make sure detectors work. */
-      t1_called = t2_called = t3_called = t4_called = false;
-      TEST((!t1_called) && (!t2_called) && (!t3_called) && (!t4_called));
-      t1_called = t2_called = t3_called = t4_called = true;
-      TEST(t1_called && t2_called && t3_called && t4_called);
+    /* Make sure detectors work. */
+    t1_called = t2_called = t3_called = t4_called = false;
+    TEST((!t1_called) && (!t2_called) && (!t3_called) && (!t4_called));
+    t1_called = t2_called = t3_called = t4_called = true;
+    TEST(t1_called && t2_called && t3_called && t4_called);
 
-      /* Make sure subtests aren't installed. */
-      t1_called = t2_called = t3_called = t4_called = false;
-      args.Clear();
-      args.Push("cTestDriver_RegressionSubtest");
-      saved_error_count = td.testErrors();
+    /* Make sure subtests aren't installed. */
+    t1_called = t2_called = t3_called = t4_called = false;
+    args.Clear();
+    args.Push("cTestDriver_RegressionSubtest");
+    saved_error_count = td.testingErrors();
 
-      cConsoleCatcher cc;
-      cc.Capture(cerr);
-      {
-        cerr << "... ('key not supported' error expected; saving error count of ";
-        cerr << saved_error_count << ") ..." << endl;
-        td.Tests(args);
-        td.testErrors() = saved_error_count;
-        cerr << "... (error count restored to ";
-        cerr << saved_error_count << ") ..." << endl;
-      }
-      cString captured = cc.Release();
+    cConsoleCatcher cc;
+    cc.Capture(cerr);
+    {
+      cerr << "... ('key not supported' error expected; saving error count of ";
+      cerr << saved_error_count << ") ..." << endl;
+      td.Tests(args);
+      td.testingErrors() = saved_error_count;
+      cerr << "... (error count restored to ";
+      cerr << saved_error_count << ") ..." << endl;
+    }
+    cString captured = cc.Release();
+    
+    TEST(0 <= captured.Find("Test or option 'cTestDriver_RegressionSubtest' could not be found"));
+    TEST((!t1_called) && (!t2_called) && (!t3_called) && (!t4_called));
 
-      TEST(0 <= captured.Find("key 'cTestDriver_RegressionSubtest' not supported"));
-      TEST((!t1_called) && (!t2_called) && (!t3_called) && (!t4_called));
+    /* Install subtests. */
+    cTestLib::getLib().reg(
+      "cTestDriver_RegressionSubtest_t1WithAttrs",
+      t1WithAttrs
+    );
+    cTestLib::getLib().reg(
+      "cTestDriver_RegressionSubtest_t2WithAttrs",
+      t2WithAttrs
+    );
+    cTestLib::getLib().reg(
+      "cTestDriver_RegressionSubtest_t3WithoutAttrs",
+      t3WithoutAttrs
+    );
+    cTestLib::getLib().reg(
+      "cTestDriver_RegressionSubtest_t4WithoutAttrs",
+      t4WithoutAttrs
+    );
 
-      /* Install subtests. */
-      cTestLib::getLib().reg(
-        "cTestDriver_RegressionSubtest_t1WithAttrs",
-        t1WithAttrs
-      );
-      cTestLib::getLib().reg(
-        "cTestDriver_RegressionSubtest_t2WithAttrs",
-        t2WithAttrs
-      );
-      cTestLib::getLib().reg(
-        "cTestDriver_RegressionSubtest_t3WithoutAttrs",
-        t3WithoutAttrs
-      );
-      cTestLib::getLib().reg(
-        "cTestDriver_RegressionSubtest_t4WithoutAttrs",
-        t4WithoutAttrs
-      );
+    /* Make sure subtests are all called. */
+    t1_called = t2_called = t3_called = t4_called = false;
+    args.Clear();
+    args.Push("cTestDriver_RegressionSubtest");
+    saved_error_count = td.testingErrors();
 
-      /* Make sure subtests are all called. */
-      t1_called = t2_called = t3_called = t4_called = false;
-      args.Clear();
-      args.Push("cTestDriver_RegressionSubtest");
-      saved_error_count = td.testErrors();
+    cout << "... (saving error count of ";
+    cout << saved_error_count << ") ..." << endl;
+    td.Tests(args);
+    td.testingErrors() = saved_error_count;
+    cout << "... (error count restored to ";
+    cout << saved_error_count << ") ..." << endl;
+    TEST(t1_called);
+    TEST(t2_called);
+    TEST(t3_called);
+    TEST(t4_called);
 
-      cout << "... (saving error count of ";
+    /* Uninstall subtests. */
+    cTestLib::getLib().unreg("cTestDriver_RegressionSubtest_t1WithAttrs");
+    cTestLib::getLib().unreg("cTestDriver_RegressionSubtest_t2WithAttrs");
+    cTestLib::getLib().unreg("cTestDriver_RegressionSubtest_t3WithoutAttrs");
+    cTestLib::getLib().unreg("cTestDriver_RegressionSubtest_t4WithoutAttrs");
+
+    /* Make sure subtests aren't installed. */
+    t1_called = t2_called = t3_called = t4_called = false;
+    args.Clear();
+    args.Push("cTestDriver_RegressionSubtest");
+    saved_error_count = td.testingErrors();
+    cc.Capture(cerr);
+    {
+      cout << "... ('key not supported' error expected; saving error count of ";
       cout << saved_error_count << ") ..." << endl;
       td.Tests(args);
-      td.testErrors() = saved_error_count;
+      td.testingErrors() = saved_error_count;
       cout << "... (error count restored to ";
       cout << saved_error_count << ") ..." << endl;
-      TEST(t1_called);
-      TEST(t2_called);
-      TEST(t3_called);
-      TEST(t4_called);
-
-      /* Uninstall subtests. */
-      cTestLib::getLib().unreg("cTestDriver_RegressionSubtest_t1WithAttrs");
-      cTestLib::getLib().unreg("cTestDriver_RegressionSubtest_t2WithAttrs");
-      cTestLib::getLib().unreg("cTestDriver_RegressionSubtest_t3WithoutAttrs");
-      cTestLib::getLib().unreg("cTestDriver_RegressionSubtest_t4WithoutAttrs");
-
-      /* Make sure subtests aren't installed. */
-      t1_called = t2_called = t3_called = t4_called = false;
-      args.Clear();
-      args.Push("cTestDriver_RegressionSubtest");
-      saved_error_count = td.testErrors();
-      cc.Capture(cerr);
-      {
-        cout << "... ('key not supported' error expected; saving error count of ";
-        cout << saved_error_count << ") ..." << endl;
-        td.Tests(args);
-        td.testErrors() = saved_error_count;
-        cout << "... (error count restored to ";
-        cout << saved_error_count << ") ..." << endl;
-      }
-      captured = cc.Release();
-      TEST(0 <= captured.Find("key 'cTestDriver_RegressionSubtest' not supported"));
-
-      TEST(!t1_called);
-      TEST(!t2_called);
-      TEST(!t3_called);
-      TEST(!t4_called);
     }
-    cAddTestSuite t("cTestDriver_Regression_SomeTestSuitesNotProperlyMatched", test);
+    captured = cc.Release();
+    TEST(0 <= captured.Find("Test or option 'cTestDriver_RegressionSubtest' could not be found"));
+
+    TEST(!t1_called);
+    TEST(!t2_called);
+    TEST(!t3_called);
+    TEST(!t4_called);
   }
+  cAddTestSuite t("cTestDriver_Regression_SomeTestSuitesNotProperlyMatched", testsuite);
+}
 
 /* Unit Tests. {{{1 */
-  /* cTestDriver_UnitTest_HelloWorld {{{2 */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cTestDriver_UnitTest_HelloWorld", test);
-  }
+/* cTestDriver_UnitTest_TestErrors {{{2 */
+namespace cTestDriver_UnitTest_TestErrors {
+  void testsuite(cTestSettings &settings){
+    int original_error_count, new_error_count;
 
-  /* cTestDriver_RegisterAndUnregisterAndSupports {{{2 */
-  namespace UnitTest_RegisterAndUnregisterAndSupports {
-    void t1WithAttrs(cTestSettings &settings){ }
-    void t3WithoutAttrs(){ }
-    void testSettings(cTestSettings &settings){}
+    cTestDriver td;
 
-    void test(cTestSettings &settings){
-      ERROR("kgn at FIXME : redundancy with cTestLib_UnitTest_SupportsAndRegAndUnreg");
+    new_error_count = 0;
+    original_error_count = td.testingErrors();
+    td.testingErrors() = 1;
+    new_error_count = td.testingErrors();
+    td.testingErrors() = original_error_count;
+    TEST(new_error_count == 1);
 
-      TEST(!cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t1WithAttrs"));
-      TEST(!cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t3WithoutAttrs"));
-      TEST(!cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_testSettings"));
-
-      /* Install subtests. */
-      cTestLib::getLib().reg(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t1WithAttrs",
-        t1WithAttrs
-      );
-      cTestLib::getLib().reg(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t3WithoutAttrs",
-        t3WithoutAttrs
-      );
-      cTestLib::getLib().reg(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_testSettings",
-        testSettings
-      );
-
-      TEST(cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t1WithAttrs"));
-      TEST(cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t3WithoutAttrs"));
-      TEST(cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_testSettings"));
-
-      cTestLib::getLib().unreg(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t1WithAttrs");
-      cTestLib::getLib().unreg(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t3WithoutAttrs");
-      cTestLib::getLib().unreg(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_testSettings");
-
-      TEST(!cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t1WithAttrs"));
-      TEST(!cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_t3WithoutAttrs"));
-      TEST(!cTestLib::getLib().supports(
-        "cTestDriver_UnitTest_RegisterAndUnregisterAndSupports_testSettings"));
-    }
-    cAddTestSuite t("cTestDriver_RegisterAndUnregisterAndSupports", test);
+    new_error_count = 0;
+    original_error_count = td.testingErrors();
+    td.testingErrors() = 2;
+    new_error_count = td.testingErrors();
+    td.testingErrors() = original_error_count;
+    TEST(new_error_count == 2);
   }
+  cAddTestSuite t("cTestDriver_UnitTest_TestErrors", testsuite);
+}
 
-  /* cTestDriver_UnitTest_TestErrors {{{2 */
-  namespace UnitTest_TestErrors {
-    void test(cTestSettings &settings){
-      int original_error_count, new_error_count;
+/* cTestDriver_UnitTest_ResetTestErrors {{{2 */
+namespace cTestDriver_UnitTest_ResetTestErrors {
+  void testsuite(cTestSettings &settings){
+    int original_error_count, new_error_count;
 
-      cTestDriver td;
+    cTestDriver td;
 
-      new_error_count = 0;
-      original_error_count = td.testErrors();
-      td.testErrors() = 1;
-      new_error_count = td.testErrors();
-      td.testErrors() = original_error_count;
-      TEST(new_error_count == 1);
+    new_error_count = 0;
+    original_error_count = td.testingErrors();
+    td.testingErrors() = 1;
+    td.resetTestErrors();
+    new_error_count = td.testingErrors();
+    td.testingErrors() = original_error_count;
+    TEST(new_error_count == 0);
 
-      new_error_count = 0;
-      original_error_count = td.testErrors();
-      td.testErrors() = 2;
-      new_error_count = td.testErrors();
-      td.testErrors() = original_error_count;
-      TEST(new_error_count == 2);
-    }
-    cAddTestSuite t("cTestDriver_UnitTest_TestErrors", test);
+    new_error_count = 0;
+    original_error_count = td.testingErrors();
+    td.testingErrors() = 2;
+    td.resetTestErrors();
+    new_error_count = td.testingErrors();
+    td.testingErrors() = original_error_count;
+    TEST(new_error_count == 0);
   }
+  cAddTestSuite t("cTestDriver_UnitTest_ResetTestErrors", testsuite);
+}
 
-  /* cTestDriver_UnitTest_ResetTestErrors {{{2 */
-  namespace UnitTest_ResetTestErrors {
-    void test(cTestSettings &settings){
-      int original_error_count, new_error_count;
-
-      cTestDriver td;
-
-      new_error_count = 0;
-      original_error_count = td.testErrors();
-      td.testErrors() = 1;
-      td.resetTestErrors();
-      new_error_count = td.testErrors();
-      td.testErrors() = original_error_count;
-      TEST(new_error_count == 0);
-
-      new_error_count = 0;
-      original_error_count = td.testErrors();
-      td.testErrors() = 2;
-      td.resetTestErrors();
-      new_error_count = td.testErrors();
-      td.testErrors() = original_error_count;
-      TEST(new_error_count == 0);
-    }
-    cAddTestSuite t("cTestDriver_UnitTest_ResetTestErrors", test);
-  }
-
+namespace nTestDriver {
 /* Physical Link. {{{1 */
   /*
   This function does nothing;

Modified: extras/source/testsuites/nTestLib.cpp
===================================================================
--- extras/source/testsuites/nTestLib.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nTestLib.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -7,181 +7,139 @@
 XXX To-Do:
 - test void tryRun(cString key, const cTestSettings &settings);
 */
-
-namespace nTestLib {
-/* Brainstorms. {{{1 */
-  /* cTestLib_Brainstorm_HelloWorld {{{2 */
-  namespace Brainstorm_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      bool test_bool = false;
-      TEST(test_bool);
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cTestLib_Brainstorm_HelloWorld", test);
-  }
-
 /* Unit Tests. {{{1 */
-  /* cTestLib_UnitTest_HelloWorld {{{2 */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cTestLib_UnitTest_HelloWorld", test);
-  }
+/* cTestLib_UnitTest_SupportsAndRegAndUnreg {{{2 */
+namespace cTestLib_UnitTest_SupportsAndRegAndUnreg {
+  void testVoid(){}
+  void testSettings(cTestSettings &settings){}
 
-  /* cTestLib_UnitTest_SupportsAndRegAndUnreg {{{2 */
-  namespace UnitTest_SupportsAndRegAndUnreg {
-    void testVoid(){}
-    void testAttr(cTestSettings &settings){}
-    void testSettings(cTestSettings &settings){}
+  void testsuite(){
+    /* Test a testrunner taking no args. {{{3 */
+    TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testVoid"));
+    cTestLib::getLib().reg("cTestLib_SupportsAndRegAndUnreg_testVoid", testVoid);
+    TEST(cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testVoid"));
+    cTestLib::getLib().unreg("cTestLib_SupportsAndRegAndUnreg_testVoid");
+    TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testVoid"));
 
-    void test(){
-      /* Test a testrunner taking no args. {{{3 */
-      TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testVoid"));
-      cTestLib::getLib().reg("cTestLib_SupportsAndRegAndUnreg_testVoid", testVoid);
-      TEST(cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testVoid"));
-      cTestLib::getLib().unreg("cTestLib_SupportsAndRegAndUnreg_testVoid");
-      TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testVoid"));
+    /* Test a testrunner taking settings as arg. {{{3 */
+    TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testSettings"));
+    cTestLib::getLib().reg("cTestLib_SupportsAndRegAndUnreg_testSettings", testSettings);
+    TEST(cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testSettings"));
+    cTestLib::getLib().unreg("cTestLib_SupportsAndRegAndUnreg_testSettings");
+    TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testSettings"));
 
-      /* Test a testrunner taking attributes as arg. {{{3 */
-      TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testAttr"));
-      cTestLib::getLib().reg("cTestLib_SupportsAndRegAndUnreg_testAttr", testAttr);
-      TEST(cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testAttr"));
-      cTestLib::getLib().unreg("cTestLib_SupportsAndRegAndUnreg_testAttr");
-      TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testAttr"));
-
-      /* Test a testrunner taking settings as arg. {{{3 */
-      TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testSettings"));
-      cTestLib::getLib().reg("cTestLib_SupportsAndRegAndUnreg_testSettings", testSettings);
-      TEST(cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testSettings"));
-      cTestLib::getLib().unreg("cTestLib_SupportsAndRegAndUnreg_testSettings");
-      TEST(!cTestLib::getLib().supports("cTestLib_SupportsAndRegAndUnreg_testSettings"));
-
-      /* }}}3 */
-    }
-    cAddTestSuite t("cTestLib_UnitTest_SupportsAndRegAndUnreg", test);
+    /* }}}3 */
   }
+  cAddTestSuite t("cTestLib_UnitTest_SupportsAndRegAndUnreg", testsuite);
+}
 
 /* Regression. {{{1 */
-  /* cTestLib_Regression_ErrorLoadingTestrunnerByKey1 {{{2 */
-  namespace Regression_ErrorLoadingTestrunnerByKey {
-    void testVoid(){}
-    void test1(){
-      {
-        /* Sanity check. */
-        TEST(!cTestLib::getLib().supports(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"
-        ));
-        /* Register testVoid function. */
-        cTestLib::getLib().reg(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid",
-          testVoid
-        );
-        TEST(cTestLib::getLib().supports(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"
-        ));
+/* cTestLib_Regression_ErrorLoadingTestrunnerByKey1 {{{2 */
+namespace cTestLib_Regression_ErrorLoadingTestrunnerByKey {
+  void testVoid(){}
+  void testsuite1(){
+    {
+      /* Sanity check. */
+      TEST(!cTestLib::getLib().supports(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"
+      ));
+      /* Register testVoid function. */
+      cTestLib::getLib().reg(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid",
+        testVoid
+      );
+      TEST(cTestLib::getLib().supports(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"
+      ));
 
-        /* Test 'tryRun'. */
-        cTestSettings ts;
-        cTestLib::getLib().tryRun(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid",
-          ts
-        );
+      /* Test 'tryRun'. */
+      cTestSettings ts;
+      cTestLib::getLib().tryRun(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid",
+        ts
+      );
 
-        /* Unregister testVoid function. */
-        cTestLib::getLib().unreg(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"
-        );
-        TEST(!cTestLib::getLib().supports(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"
-        ));
-      }
+      /* Unregister testVoid function. */
+      cTestLib::getLib().unreg(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"
+      );
+      TEST(!cTestLib::getLib().supports(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"
+      ));
     }
-    cAddTestSuite t1("cTestLib_Regression_ErrorLoadingTestrunnerByKey1", test1);
+  }
+  cAddTestSuite t1("cTestLib_Regression_ErrorLoadingTestrunnerByKey1", testsuite1);
 
-  /* cTestLib_Regression_ErrorLoadingTestrunnerByKey2 {{{2 */
-    void testSettings(cTestSettings &settings){}
-    void test2(){
-      {
-        /* Sanity check. */
-        TEST(!cTestLib::getLib().supports(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr"
-        ));
-        /* Register testAttr function. */
-        cTestLib::getLib().reg(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr",
-          testSettings
-        );
-        TEST(cTestLib::getLib().supports(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr"
-        ));
+/* cTestLib_Regression_ErrorLoadingTestrunnerByKey2 {{{2 */
+  void testSettings(cTestSettings &settings){}
+  void testsuite2(){
+    {
+      /* Sanity check. */
+      TEST(!cTestLib::getLib().supports(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr"
+      ));
+      /* Register testAttr function. */
+      cTestLib::getLib().reg(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr",
+        testSettings
+      );
+      TEST(cTestLib::getLib().supports(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr"
+      ));
 
-        /* Test 'tryRun'. */
-        cTestSettings ts;
-        cTestLib::getLib().tryRun(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr",
-          ts
-        );
+      /* Test 'tryRun'. */
+      cTestSettings ts;
+      cTestLib::getLib().tryRun(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr",
+        ts
+      );
 
-        /* Unregister testAttr function. */
-        cTestLib::getLib().unreg(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr"
-        );
-        TEST(!cTestLib::getLib().supports(
-          "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr"
-        ));
-      }
+      /* Unregister testAttr function. */
+      cTestLib::getLib().unreg(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr"
+      );
+      TEST(!cTestLib::getLib().supports(
+        "cTestLib_Regression_ErrorLoadingTestrunnerByKey_testAttr"
+      ));
     }
-    cAddTestSuite t2("cTestLib_Regression_ErrorLoadingTestrunnerByKey2", test2);
+  }
+  cAddTestSuite t2("cTestLib_Regression_ErrorLoadingTestrunnerByKey2", testsuite2);
 
-  /* cTestLib_Regression_ErrorLoadingTestrunnerByKey3 {{{2 */
-    bool try_run_was_called;
-    class myTestLib : public cTestLib {
-    public:
-      virtual void tryRun(cString key, const cStringList &attributes){
-        try_run_was_called = true;
-      }
-    };
-    void test3(){
-      {
-        myTestLib tl;
+/* cTestLib_Regression_ErrorLoadingTestrunnerByKey3 {{{2 */
+  bool try_run_was_called;
+  class myTestLib : public cTestLib {
+  public:
+    virtual void tryRun(cString key, const cStringList &attributes){
+      try_run_was_called = true;
+    }
+  };
+  void testsuite3(){
+    {
+      myTestLib tl;
 
-        /* Sanity check. */
-        TEST(!tl.supports("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"));
-        /* Register testVoid function. */
-        tl.reg("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid", testVoid);
-        TEST(tl.supports("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"));
+      /* Sanity check. */
+      TEST(!tl.supports("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"));
+      /* Register testVoid function. */
+      tl.reg("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid", testVoid);
+      TEST(tl.supports("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"));
 
-        try_run_was_called = false;
-        tl.tryRun("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid", cStringList());
-        TEST(true == try_run_was_called);
+      try_run_was_called = false;
+      tl.tryRun("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid", cStringList());
+      TEST(true == try_run_was_called);
 
-        try_run_was_called = false;
-        tl.tryRun("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid", cStringList());
-        TEST(true == try_run_was_called);
+      try_run_was_called = false;
+      tl.tryRun("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid", cStringList());
+      TEST(true == try_run_was_called);
 
-        /* Unregister testVoid function. */
-        tl.unreg("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid");
-        TEST(!tl.supports("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"));
-      }
+      /* Unregister testVoid function. */
+      tl.unreg("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid");
+      TEST(!tl.supports("cTestLib_Regression_ErrorLoadingTestrunnerByKey_testVoid"));
     }
-    cAddTestSuite t3("cTestLib_Regression_ErrorLoadingTestrunnerByKey3", test3);
   }
+  cAddTestSuite t3("cTestLib_Regression_ErrorLoadingTestrunnerByKey3", testsuite3);
+}
 
+namespace nTestLib {
 /* Physical Link. {{{1 */
   /*
   This function does nothing;

Modified: extras/source/testsuites/nTestSettings.cpp
===================================================================
--- extras/source/testsuites/nTestSettings.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/testsuites/nTestSettings.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -9,215 +9,183 @@
 - test void Clear();
 */
 
-namespace nTestSettings {
-/* Brainstorms. {{{1 */
-  /* cTestSettings_Brainstorm_HelloWorld {{{2 */
-  namespace Brainstorm_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cTestSettings_Brainstorm_HelloWorld", test);
-  }
+/* UnitTests. {{{1 */
 
-  /* cTestSettings_Brainstorm_ClassDesign {{{2 */
-  namespace Brainstorm_ClassDesign {
-    void test(){
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Verify basic functionality : shadowing tDictionary. {{{3 */
-      {
-        cTestSettings ts;
-        cString value("ick");
-        /* Verify initial number of settings is zero. {{{4 */
-        TEST(0 == ts.Size());
-        /* Verify behavior on checking a setting that hasn't been set. {{{4 */
-        TEST(!ts.HasSetting("blah"));
-        TEST(ts.Setting("blah") == "");
-        /* Set "blah" to "hum". {{{4 */
-        ts.Set("blah", "hum");
-        TEST(1 == ts.Size());
-        /* Verify behavior on checking a valid setting. {{{4 */
-        TEST(ts.HasSetting("blah"));
-        TEST(ts.Setting("blah") == "hum");
-        /* Reset "blah" to "ho". {{{4 */
-        ts.Set("blah", "ho");
-        TEST(1 == ts.Size());
-        /* Verify behavior on reset of a valid setting. {{{4 */
-        TEST(ts.HasSetting("blah"));
-        TEST(ts.Setting("blah") != "hum");
-        TEST(ts.Setting("blah") == "ho");
-        /* Verify unsetting an invalid setting. {{{4 */
-        TEST(!ts.HasSetting("urk"));
-        TEST(ts.Setting("urk") == "");
-        /* Verify unsetting a valid setting. {{{4 */
-        TEST(ts.HasSetting("blah"));
-        value = ts.Unset("blah");
-        TEST(value == "ho");
-        TEST(0 == ts.Size());
-        TEST(ts.Setting("blah") == "");
-        /* Verify unsetting a formerly valid setting. {{{4 */
-        TEST(!ts.HasSetting("blah"));
-        value = ts.Unset("blah");
-        TEST(value == "");
-        TEST(0 == ts.Size());
-        TEST(ts.Setting("blah") == "");
-        /* Verify parsing various "setting" strings. {{{4 */
-        /* - This shouldn't parse. {{{5 */
-        TEST(!ts.ParseSettingString("nope"));
-        TEST(0 == ts.Size());
-        TEST(!ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(!ts.HasSetting(""));
-        TEST(ts.Setting("y") == "");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "");
-        /* - This should parse, but sets "" to "". {{{5 */
-        TEST(ts.ParseSettingString("Set"));
-        TEST(1 == ts.Size());
-        TEST(!ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        TEST(ts.Setting("y") == "");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "");
-        /* - This should parse, but sets "" to "". {{{5 */
-        TEST(ts.ParseSettingString("Set_"));
-        TEST(1 == ts.Size());
-        TEST(!ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        TEST(ts.Setting("y") == "");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "");
-        /* - This should parse, but sets "" to "". {{{5 */
-        TEST(ts.ParseSettingString("Set__"));
-        TEST(1 == ts.Size());
-        TEST(!ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        TEST(ts.Setting("y") == "");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "");
-        /* - This should parse, but sets "" to "hmf". {{{5 */
-        TEST(ts.ParseSettingString("Set__hmf"));
-        TEST(1 == ts.Size());
-        TEST(!ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        TEST(ts.Setting("y") == "");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "hmf");
-        /* - This should parse, but sets "" to "hmf". {{{5 */
-        TEST(ts.ParseSettingString("Set__good_grief"));
-        TEST(1 == ts.Size());
-        TEST(!ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        TEST(ts.Setting("y") == "");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "good_grief");
-        /* - This should parse, and should set "x" to "". {{{5 */
-        TEST(ts.ParseSettingString("Set_x"));
-        TEST(2 == ts.Size());
-        TEST(!ts.HasSetting("y"));
-        TEST(ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        TEST(ts.Setting("y") == "");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "good_grief");
-        /* - This should parse, and should set "y" to "fubar". {{{5 */
-        TEST(ts.ParseSettingString("Set_y_fubar"));
-        TEST(3 == ts.Size());
-        TEST(ts.HasSetting("y"));
-        TEST(ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        TEST(ts.Setting("y") == "fubar");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "good_grief");
-        /* - This should parse, and should set "y" to "z_z". {{{5 */
-        TEST(ts.ParseSettingString("Set_y_z_z"));
-        TEST(3 == ts.Size());
-        TEST(ts.HasSetting("y"));
-        TEST(ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        TEST(ts.Setting("y") == "z_z");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "good_grief");
-        /* - This should parse, but unset "" . {{{5 */
-        TEST(ts.ParseSettingString("Unset"));
-        TEST(2 == ts.Size());
-        TEST(ts.HasSetting("y"));
-        TEST(ts.HasSetting("x"));
-        TEST(!ts.HasSetting(""));
-        TEST(ts.Setting("y") == "z_z");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "");
-        /* - This should parse, but unset "". {{{5 */
-        TEST(ts.ParseSettingString("Unset_"));
-        TEST(2 == ts.Size());
-        TEST(ts.HasSetting("y"));
-        TEST(ts.HasSetting("x"));
-        TEST(!ts.HasSetting(""));
-        TEST(ts.Setting("y") == "z_z");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "");
-        /* - This should parse, and should unset "x". {{{5 */
-        TEST(ts.ParseSettingString("Unset_x"));
-        TEST(1 == ts.Size());
-        TEST(ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(!ts.HasSetting(""));
-        TEST(ts.Setting("y") == "z_z");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "");
-        /* - This should parse, and should unset "y". {{{5 */
-        TEST(ts.ParseSettingString("Unset_y_z_z"));
-        TEST(0 == ts.Size());
-        TEST(!ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(!ts.HasSetting(""));
-        TEST(ts.Setting("y") == "");
-        TEST(ts.Setting("x") == "");
-        TEST(ts.Setting("") == "");
-        /* - This should set "x", "y", and "", then unset all at once. {{{5 */
-        TEST(ts.ParseSettingString("Set_x"));
-        TEST(ts.ParseSettingString("Set_y_fubar"));
-        TEST(ts.ParseSettingString("Set"));
-        TEST(ts.HasSetting("y"));
-        TEST(ts.HasSetting("x"));
-        TEST(ts.HasSetting(""));
-        ts.Clear();
-        TEST(!ts.HasSetting("y"));
-        TEST(!ts.HasSetting("x"));
-        TEST(!ts.HasSetting(""));
-      }
+/* cTestSettings_UnitTest_ClassDesign {{{2 */
+namespace cTestSettings_UnitTest_ClassDesign {
+  void testsuite(){
+    /* Verify basic functionality : shadowing tDictionary. {{{3 */
+    {
+      cTestSettings ts;
+      cString value("ick");
+      /* Verify initial number of settings is zero. {{{4 */
+      TEST(0 == ts.Size());
+      /* Verify behavior on checking a setting that hasn't been set. {{{4 */
+      TEST(!ts.HasSetting("blah"));
+      TEST(ts.Setting("blah") == "");
+      /* Set "blah" to "hum". {{{4 */
+      ts.Set("blah", "hum");
+      TEST(1 == ts.Size());
+      /* Verify behavior on checking a valid setting. {{{4 */
+      TEST(ts.HasSetting("blah"));
+      TEST(ts.Setting("blah") == "hum");
+      /* Reset "blah" to "ho". {{{4 */
+      ts.Set("blah", "ho");
+      TEST(1 == ts.Size());
+      /* Verify behavior on reset of a valid setting. {{{4 */
+      TEST(ts.HasSetting("blah"));
+      TEST(ts.Setting("blah") != "hum");
+      TEST(ts.Setting("blah") == "ho");
+      /* Verify unsetting an invalid setting. {{{4 */
+      TEST(!ts.HasSetting("urk"));
+      TEST(ts.Setting("urk") == "");
+      /* Verify unsetting a valid setting. {{{4 */
+      TEST(ts.HasSetting("blah"));
+      value = ts.Unset("blah");
+      TEST(value == "ho");
+      TEST(0 == ts.Size());
+      TEST(ts.Setting("blah") == "");
+      /* Verify unsetting a formerly valid setting. {{{4 */
+      TEST(!ts.HasSetting("blah"));
+      value = ts.Unset("blah");
+      TEST(value == "");
+      TEST(0 == ts.Size());
+      TEST(ts.Setting("blah") == "");
+      /* Verify parsing various "setting" strings. {{{4 */
+      /* - This shouldn't parse. {{{5 */
+      TEST(!ts.ParseSettingString("nope"));
+      TEST(0 == ts.Size());
+      TEST(!ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(!ts.HasSetting(""));
+      TEST(ts.Setting("y") == "");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "");
+      /* - This should parse, but sets "" to "". {{{5 */
+      TEST(ts.ParseSettingString("--set"));
+      TEST(1 == ts.Size());
+      TEST(!ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      TEST(ts.Setting("y") == "");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "");
+      /* - This should parse, but sets "" to "". {{{5 */
+      TEST(ts.ParseSettingString("--set-"));
+      TEST(1 == ts.Size());
+      TEST(!ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      TEST(ts.Setting("y") == "");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "");
+      /* - This should parse, but sets "" to "". {{{5 */
+      TEST(ts.ParseSettingString("--set--"));
+      TEST(1 == ts.Size());
+      TEST(!ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      TEST(ts.Setting("y") == "");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "");
+      /* - This should parse, but sets "" to "hmf". {{{5 */
+      TEST(ts.ParseSettingString("--set--hmf"));
+      TEST(1 == ts.Size());
+      TEST(!ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      TEST(ts.Setting("y") == "");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "hmf");
+      /* - This should parse, but sets "" to "good-grief". {{{5 */
+      TEST(ts.ParseSettingString("--set--good-grief"));
+      TEST(1 == ts.Size());
+      TEST(!ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      TEST(ts.Setting("y") == "");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "good-grief");
+      /* - This should parse, and should set "x" to "". {{{5 */
+      TEST(ts.ParseSettingString("--set-x"));
+      TEST(2 == ts.Size());
+      TEST(!ts.HasSetting("y"));
+      TEST(ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      TEST(ts.Setting("y") == "");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "good-grief");
+      /* - This should parse, and should set "y" to "fubar". {{{5 */
+      TEST(ts.ParseSettingString("--set-y-fubar"));
+      TEST(3 == ts.Size());
+      TEST(ts.HasSetting("y"));
+      TEST(ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      TEST(ts.Setting("y") == "fubar");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "good-grief");
+      /* - This should parse, and should set "y" to "z_z". {{{5 */
+      TEST(ts.ParseSettingString("--set-y-z-z"));
+      TEST(3 == ts.Size());
+      TEST(ts.HasSetting("y"));
+      TEST(ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      TEST(ts.Setting("y") == "z-z");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "good-grief");
+      /* - This should parse, but unset "" . {{{5 */
+      TEST(ts.ParseSettingString("--unset"));
+      TEST(2 == ts.Size());
+      TEST(ts.HasSetting("y"));
+      TEST(ts.HasSetting("x"));
+      TEST(!ts.HasSetting(""));
+      TEST(ts.Setting("y") == "z-z");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "");
+      /* - This should parse, but unset "". {{{5 */
+      TEST(ts.ParseSettingString("--unset-"));
+      TEST(2 == ts.Size());
+      TEST(ts.HasSetting("y"));
+      TEST(ts.HasSetting("x"));
+      TEST(!ts.HasSetting(""));
+      TEST(ts.Setting("y") == "z-z");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "");
+      /* - This should parse, and should unset "x". {{{5 */
+      TEST(ts.ParseSettingString("--unset-x"));
+      TEST(1 == ts.Size());
+      TEST(ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(!ts.HasSetting(""));
+      TEST(ts.Setting("y") == "z-z");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "");
+      /* - This should parse, and should unset "y". {{{5 */
+      TEST(ts.ParseSettingString("--unset-y-z-z"));
+      TEST(0 == ts.Size());
+      TEST(!ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(!ts.HasSetting(""));
+      TEST(ts.Setting("y") == "");
+      TEST(ts.Setting("x") == "");
+      TEST(ts.Setting("") == "");
+      /* - This should set "x", "y", and "", then unset all at once. {{{5 */
+      TEST(ts.ParseSettingString("--set-x"));
+      TEST(ts.ParseSettingString("--set-y-fubar"));
+      TEST(ts.ParseSettingString("--set"));
+      TEST(ts.HasSetting("y"));
+      TEST(ts.HasSetting("x"));
+      TEST(ts.HasSetting(""));
+      ts.Clear();
+      TEST(!ts.HasSetting("y"));
+      TEST(!ts.HasSetting("x"));
+      TEST(!ts.HasSetting(""));
     }
-    cAddTestSuite t("cTestSettings_Brainstorm_ClassDesign", test);
   }
+  cAddTestSuite t("cTestSettings_UnitTest_ClassDesign", testsuite);
+}
 
-
-/* Unit Tests. {{{1 */
-  /* cTestSettings_UnitTest_HelloWorld {{{2 */
-  namespace UnitTest_HelloWorld {
-    void test(cTestSettings &settings){
-      if(!settings.HasSetting("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
-      }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cTestSettings_UnitTest_HelloWorld", test);
-  }
-
+namespace nTestSettings {
 /* Physical Link. {{{1 */
   /*
   This function does nothing;

Modified: extras/source/tools/cTestDriver.cpp
===================================================================
--- extras/source/tools/cTestDriver.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/tools/cTestDriver.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -7,20 +7,93 @@
 
 using namespace std;
 
-int & cTestDriver::testErrors(void){
-  return test_errors();
+int & cTestDriver::testingErrors(void){
+  return testing_errors();
 }
 
+int & cTestDriver::testAttempts(void){
+  return test_attempts();
+}
+
+int & cTestDriver::testSuccesses(void){
+  return test_successes();
+}
+
+int & cTestDriver::testSkips(void){
+  return test_skips();
+}
+
 void cTestDriver::resetTestErrors(void){
-  testErrors() = 0;
+  testingErrors() = 0;
+  testSuccesses() = 0;
+  testSkips() = 0;
 }
 
 int cTestDriver::reportErrors(void){
+  int tests = testAttempts();
+  int skips = testSkips();
+  if (0 < tests){
+    cerr << tests << " test" << (tests == 1? " was": "s were") << " run." << endl;
+  }
+  if (0 < skips){
+    cerr << skips << " testsuite" << (skips == 1? " was": "s were") << " skipped." << endl;
+  }
   return report_errors();
 }
 
+void cTestDriver::Usage(void){
+
+  cout << endl
+       << "Usage: " << endl
+       << "  " << m_application_name << " [option or testsuite-name or partial-testsuite-name] ..."
+       << endl
+       << endl;
+       
+  cout << "Options:" << endl
+       << "  -h, --help      Help on options (this listing)" << endl
+       << "  -l, --list      Print a list known testsuites" << endl
+       << "  -q, --quiet     Switch to quiet mode" << endl
+       << "  -v, --verbose   Switch to verbose mode" << endl
+       << endl
+       << "  --set-<Variable>-<Value>   Set <Variable> to <Value>" << endl
+       << "  --enable-<Variable>        Enable boolean <Variable>" << endl
+       << "  --unset-<Variable>         Unset <Variable>" << endl
+       << "  --disable-<Variable>       Unset <Variable>" << endl
+       << endl;
+}
+
+void cTestDriver::ListTests(void){
+  cout << "------ Listing known testsuites ..." << endl;
+  {
+    /* Get a list of names of known test suites. */
+    tList<cString> name_list;
+    tList<Testrunner> test_list;
+    cTestLib::getLib().asLists(name_list, test_list);
+    /* Iterate through list of test suite names. */
+    tListIterator<cString> list_it(name_list);
+    while(list_it.Next() != 0) {
+      /* List each test suite by name. */
+      cout << "--- '" << *list_it.Get() << endl;
+    }
+  }
+  /* Settings */
+  {
+    /* Get a list of names of known test suites. */
+    tList<cString> name_list;
+    tList<TestrunnerWithSettings> test_list;
+    cTestLib::getLib().asLists(name_list, test_list);
+    /* Iterate through list of test suite names. */
+    tListIterator<cString> list_it(name_list);
+    while(list_it.Next() != 0) {
+      /* List each test suite by name. */
+      cout << "--- '" << *list_it.Get() << endl;
+    }
+  }
+  cout << "****** Done listing known testsuites." << endl;
+}
+
 void cTestDriver::TestAll(cTestSettings &settings){
-  cout << "------ Running all known tests ..." << endl;
+  cout << "------ Running all known testsuites ..." << endl;
   {
     /* Get a list of names of known test suites. */
     tList<cString> name_list;
@@ -50,57 +123,60 @@
       cout << "*** '" << *list_it.Get() << "' : done." << endl;
     }
   }
-  cout << "****** Done running all known tests." << endl;
+  cout << "****** Done running all known testsuites." << endl;
 }
 
 int cTestDriver::Tests(cStringList &args){
   /* Whether to be verbose (enable cout) or quiet (disable cout). */
-  cout << "...... Being verbose by default." << endl;
+  // cout << "...... Being verbose by default." << endl;
   fstream null_file;
   streambuf *null_buf = null_file.rdbuf();
   streambuf *cout_buf = cout.rdbuf();
   streambuf *clog_buf = clog.rdbuf();
 
-  bool did_already_test_something = false;
+  bool should_test_all_by_default = true;
 
   while(args.GetSize() > 0){
     cString test_name(args.Pop());
     if(m_test_settings.ParseSettingString(test_name)){
       // Do nothing extra...
-    } else if (test_name == "Quiet"){
-      /*
-      Turn slow tests off; i.e., skip tests that we think take a long
-      time.
-      */
+    } else if ((test_name == "--help") || (test_name == "-h")){
+      streambuf *buf = cout.rdbuf();      cout.rdbuf(buf);
+      cout.rdbuf(cout_buf);
+      Usage();
+      cout.rdbuf(buf);
+      should_test_all_by_default = false;
+    } else if ((test_name == "--list") || (test_name == "-l")){
+      streambuf *buf = cout.rdbuf();
+      cout.rdbuf(cout_buf);
+      ListTests();
+      cout.rdbuf(buf);
+      should_test_all_by_default = false;
+    } else if ((test_name == "--quiet") || (test_name == "-q")){
       cout << "...... Being quiet ..." << endl;
       cout.rdbuf(null_buf);
       clog.rdbuf(null_buf);
-    } else if (test_name == "Verbose"){
-      /*
-      Turn slow tests off; i.e., skip tests that we think take a long
-      time.
-      */
+    } else if ((test_name == "--verbose") || (test_name == "-v")){
       cout.rdbuf(cout_buf);
       clog.rdbuf(clog_buf);
       cout << "...... Being verbose ..." << endl;
-    } else if (test_name == "All"){
+    } else if ((test_name == "--all") || (test_name == "-a")){
       /*
       Test everything.
       */
-      did_already_test_something = true;
       TestAll(m_test_settings);
+      should_test_all_by_default = false;
     } else {
       /*
       Look for and try to run a test suite by name.
       */
-      did_already_test_something = true;
       cout << "--- '" << test_name << "' : testing ..." << endl;
-      //cTestLib::getLib().tryRun(test_name, m_test_attributes);
       cTestLib::getLib().tryRun(test_name, m_test_settings);
       cout << "*** '" << test_name << "' : done." << endl;
+      should_test_all_by_default = false;
     }
   }
-  if(!did_already_test_something){
+  if(should_test_all_by_default){
     /*
     Test everything if nothing has been tested yet.
     */
@@ -110,25 +186,12 @@
   clog.flush();
   cout.rdbuf(cout_buf);
   clog.rdbuf(clog_buf);
-  return testErrors();
+  return testingErrors();
 }
 
-/*
-Command line args:
-a list of test suites to run, by name;
-three other keywords are understood:
-- Slow: turn on slow test suites, i.e., run the tests that we think take
-  a long time;
-- Fast: turn off slow test suites, i.e., skip the tests that we think
-  take a long time;
-- All: run all of test suites that we know about.
-
-By default, slow tests are turned off.
-*/
 int cTestDriver::Tests(int argc, char * argv[]){
   cStringList sl;
-
-  cStringList non_test_settings;
+  m_application_name = cString(argv[0]);
   for(int i=1; i<argc; i++){
     sl.PushRear(argv[i]);
   }

Modified: extras/source/tools/cTestDriver.h
===================================================================
--- extras/source/tools/cTestDriver.h	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/tools/cTestDriver.h	2007-12-19 20:19:54 UTC (rev 2225)
@@ -5,17 +5,27 @@
 #include "cStringList.h"
 #endif
 
+#ifndef cString_h
+#include "cString.h"
+#endif
+
 #ifndef cTestSettings_h
 #include "cTestSettings.h"
 #endif
 
 class cTestDriver {
 protected:
+  cString m_application_name;
   cTestSettings m_test_settings;
 public:
-  int & testErrors(void);
+  int & testingErrors(void);
+  int & testAttempts(void);
+  int & testSuccesses(void);
+  int & testSkips(void);
   void resetTestErrors(void);
   int reportErrors(void);
+  void Usage();
+  void ListTests();
   void TestAll(cTestSettings &settings);
   int Tests(cStringList &args);
   int Tests(int argc, char * argv[]);

Modified: extras/source/tools/cTestLib.cpp
===================================================================
--- extras/source/tools/cTestLib.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/tools/cTestLib.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -91,7 +91,7 @@
       }
     }
     if(!found_match){
-      ERROR(cString("key '") + key + "' not supported");
+      ERROR(cString("Test or option '") + key + "' could not be found");
     }
   }
 }

Modified: extras/source/tools/cTestSettings.cpp
===================================================================
--- extras/source/tools/cTestSettings.cpp	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/tools/cTestSettings.cpp	2007-12-19 20:19:54 UTC (rev 2225)
@@ -48,19 +48,31 @@
 
 bool cTestSettings::ParseSettingString(const cString& arg) {
   cString command(""), name(""), value("");
-  cStringList l(arg, '_');
+  cStringList l(arg, '-');
 
+  if(0 < l.GetSize()){ l.Pop(); }
+  if(0 < l.GetSize()){ l.Pop(); }
   if(0 < l.GetSize()){ command = l.Pop(); }
   if(0 < l.GetSize()){ name = l.Pop(); }
   if(0 < l.GetSize()){ value = l.Pop(); }
-  while(0 < l.GetSize()){ value = value + "_" + l.Pop(); }
+  while(0 < l.GetSize()){ value = value + "-" + l.Pop(); }
 
-  if((command == "Set")){
+  if(command == "set"){
+    cout << "...... Setting '" << name << "' to '" << value << "' ..." << endl;
     Set(name, value);
     return true;
-  } else if ((command == "Unset")){
+  } else if (command == "enable"){
+    cout << "...... Enabling '" << name << "' ..." << endl;
+    Set(name, "");
+    return true;
+  } else if (command == "unset"){
+    cout << "...... Unsetting '" << name << "' ..." << endl;
     Unset(name);
     return true;
+  } else if (command == "disable"){
+    cout << "...... Disabling '" << name << "' ..." << endl;
+    Unset(name);
+    return true;
   } else {
     return false;
   }

Modified: extras/source/tools/lightweight_test.h
===================================================================
--- extras/source/tools/lightweight_test.h	2007-02-22 01:21:24 UTC (rev 1361)
+++ extras/source/tools/lightweight_test.h	2007-12-19 20:19:54 UTC (rev 2225)
@@ -20,41 +20,82 @@
 #endif
 }
 
-inline int & test_errors()
+inline int & testing_errors()
 {
     static int x = 0;
     return x;
 }
 
+inline int & test_attempts()
+{
+    static int x = 0;
+    return x;
+}
+
+inline int & test_successes()
+{
+    static int x = 0;
+    return x;
+}
+
+inline int & test_skips()
+{
+    static int x = 0;
+    return x;
+}
+
+inline void test_passed_impl(char const * expr, char const * file, int line, char const * function)
+{
+    ++test_attempts();
+    ++test_successes();
+}
+
 inline void test_failed_impl(char const * expr, char const * file, int line, char const * function)
 {
-    std::cerr << file << "(" << line << "): test '" << expr << "' failed in function '" << function << "'" << std::endl;
-    ++test_errors();
+    std::cerr << file << "(" << line << "):" << std::endl
+              << "  test '" << expr << "' failed in function:" << std::endl
+              << "  '" << function << "'" << std::endl;
+    ++test_attempts();
+    ++testing_errors();
 }
 
 inline void error_impl(char const * msg, char const * file, int line, char const * function)
 {
-    std::cerr << file << "(" << line << "): " << msg << " in function '" << function << "'" << std::endl;
-    ++test_errors();
+    std::cerr << file << "(" << line << "):" << std::endl
+              << "  " << msg << " in function:" << std::endl
+              << "  '" << function << "'" << std::endl;
+    ++testing_errors();
 }
 
+inline void skip_impl(char const * msg, char const * file, int line, char const * function)
+{
+    std::cout << file << "(" << line << "):" << std::endl
+              << "  " << msg << " in function:" << std::endl
+              << "  '" << function << "'" << std::endl;
+    ++test_skips();
+}
+
 inline int report_errors()
 {
-    int errors = test_errors();
+    int errors = testing_errors();
 
     if(errors == 0)
     {
-        std::cerr << "No errors detected." << std::endl;
+        std::cerr << "No errors were detected." << std::endl;
         return 0;
     }
     else
     {
-        std::cerr << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl;
+        std::cerr << errors << " error" << (errors == 1? " was": "s were") << " detected." << std::endl;
         return 1;
     }
 }
 
-#define TEST(expr) ((expr)? (void)0: test_failed_impl(#expr, __FILE__, __LINE__, CURRENT_FUNCTION))
+#define TEST(expr) ((expr) \
+  ? test_passed_impl(#expr, __FILE__, __LINE__, CURRENT_FUNCTION) \
+  : test_failed_impl(#expr, __FILE__, __LINE__, CURRENT_FUNCTION) \
+  )
+#define SKIP(msg) skip_impl(msg, __FILE__, __LINE__, CURRENT_FUNCTION)
 #define ERROR(msg) error_impl(msg, __FILE__, __LINE__, CURRENT_FUNCTION)
 
 #endif




More information about the Avida-cvs mailing list