lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [4894] Merge two TUs, renaming 'ihs_dbdict.cpp' to 'dbdict


From: Greg Chicares
Subject: [lmi-commits] [4894] Merge two TUs, renaming 'ihs_dbdict.cpp' to 'dbdict.cpp'
Date: Sun, 02 May 2010 17:06:18 +0000

Revision: 4894
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=4894
Author:   chicares
Date:     2010-05-02 17:06:17 +0000 (Sun, 02 May 2010)
Log Message:
-----------
Merge two TUs, renaming 'ihs_dbdict.cpp' to 'dbdict.cpp'

Modified Paths:
--------------
    lmi/trunk/ChangeLog
    lmi/trunk/Makefile.am
    lmi/trunk/objects.make

Added Paths:
-----------
    lmi/trunk/dbdict.cpp

Removed Paths:
-------------
    lmi/trunk/dbdict.cpp
    lmi/trunk/ihs_dbdict.cpp

Modified: lmi/trunk/ChangeLog
===================================================================
--- lmi/trunk/ChangeLog 2010-05-02 15:23:37 UTC (rev 4893)
+++ lmi/trunk/ChangeLog 2010-05-02 17:06:17 UTC (rev 4894)
@@ -25319,3 +25319,23 @@
   product_file_test.cpp
 Merge two headers, renaming 'ihs_dbdict.hpp' to 'dbdict.hpp'.
 
+20100502T1520Z <address@hidden> [730]
+
+  database.cpp
+  dbdict.hpp
+Refactor.
+
+20100502T1523Z <address@hidden> [730]
+
+  dbdict.cpp
+  ihs_dbdict.cpp
+Make 'dbdict.cpp' dispensable.
+
+20100502T1706Z <address@hidden> [726]
+
+  Makefile.am
+  dbdict.cpp     [overwritten by renamed 'ihs_dbdict.cpp']
+  ihs_dbdict.cpp [renamed to 'dbdict.cpp']
+  objects.make
+Merge two TUs, renaming 'ihs_dbdict.cpp' to 'dbdict.cpp'.
+

Modified: lmi/trunk/Makefile.am
===================================================================
--- lmi/trunk/Makefile.am       2010-05-02 15:23:37 UTC (rev 4893)
+++ lmi/trunk/Makefile.am       2010-05-02 17:06:17 UTC (rev 4894)
@@ -242,6 +242,7 @@
     crc32.cpp \
     custom_io_0.cpp \
     data_directory.cpp \
+    dbdict.cpp \
     dbnames.cpp \
     dbvalue.cpp \
     death_benefits.cpp \
@@ -303,7 +304,6 @@
     antediluvian_stubs.cpp \
     basicvalues.cpp \
     database.cpp \
-    dbdict.cpp \
     mortality_rates.cpp \
     solve.cpp \
     $(liblmi_common_sources)
@@ -328,7 +328,6 @@
     ihs_avstrtgy.cpp \
     ihs_basicval.cpp \
     ihs_database.cpp \
-    ihs_dbdict.cpp \
     ihs_irc7702.cpp \
     ihs_irc7702a.cpp \
     ihs_mortal.cpp \
@@ -724,12 +723,12 @@
 test_product_file_SOURCES =   \
   $(common_test_objects) \
   data_directory.cpp \
+  dbdict.cpp \
   dbnames.cpp \
   dbvalue.cpp \
   expm1.cpp \
   fund_data.cpp \
   global_settings.cpp \
-  ihs_dbdict.cpp \
   miscellany.cpp \
   path_utility.cpp \
   product_data.cpp \

Deleted: lmi/trunk/dbdict.cpp
===================================================================
--- lmi/trunk/dbdict.cpp        2010-05-02 15:23:37 UTC (rev 4893)
+++ lmi/trunk/dbdict.cpp        2010-05-02 17:06:17 UTC (rev 4894)
@@ -1,267 +0,0 @@
-// Product-database map.
-//
-// Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 
2010 Gregory W. Chicares.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-//
-// http://savannah.nongnu.org/projects/lmi
-// email: <address@hidden>
-// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
-
-// $Id$
-
-#ifdef __BORLANDC__
-#   include "pchfile.hpp"
-#   pragma hdrstop
-#endif // __BORLANDC__
-
-#include "ihs_dbdict.cpp"
-
-#if 0
-#include "dbdict.hpp"
-
-#include "dbnames.hpp"
-#include "mc_enum_type_enums.hpp"
-
-#include <cstring>
-
-std::string DBDictionary::CachedFilename;
-
-//============================================================================
-DBDictionary& DBDictionary::instance()
-{
-    static DBDictionary z;
-    return z;
-}
-
-//============================================================================
-DBDictionary::DBDictionary()
-{
-    dictionary = new dict_map;
-}
-
-//============================================================================
-DBDictionary::~DBDictionary()
-{
-    (*dictionary).clear();
-    delete dictionary;
-    dictionary = 0;
-}
-
-dict_map const& DBDictionary::GetDictionary() const
-{
-    return *dictionary;
-}
-
-//============================================================================
-void DBDictionary::Init(std::string const& NewFilename)
-{
-    // We don't need to perform the expensive operation of reading the
-    // dictionary from file if it's the same dictionary we last read.
-    // We don't address the problem that someone might have modified
-    // that file in the meantime.
-
-    // TODO ?? Consider rewriting this as
-    // if(!condition)
-    //   {
-    //   [do something]
-    //   }
-
-    if
-        (
-                // But we must read the dictionary from file if we've
-                // never yet read in any dictionary.
-                ("" != CachedFilename)
-            && (CachedFilename == NewFilename)
-        )
-        {
-        // do nothing
-        }
-    else
-        {
-        CachedFilename = NewFilename;
-        delete dictionary;
-        dictionary = new dict_map;
-        // stream from file
-// TODO ?? HERE WE NEED TO ADD A STREAMING METHOD
-// TODO ?? CachedDBDictionary = Dictionary = new dict_map(CachedFilename);
-        InitAntediluvian(); // TODO ?? KLUDGE
-        }
-}
-
-//============================================================================
-void DBDictionary::InitAntediluvian()
-{
-    static int const n = 1 + TDBIndex::MaxIndex;
-    int dims[n] = {1, 1, 1, 1, 1, 1, 1};
-
-    dictionary->erase(dictionary->begin(), dictionary->end());
-
-    double zilch[1] = {0.0};
-    // Zero is inappropriate for some entities ("DB_CCOIMultiplier",
-    // e.g.), but the antediluvian branch doesn't actually use most
-    // database entities.
-    for(int j = DB_FIRST; j < DB_LAST; ++j)
-        {
-        AddEntry(dict_map_val(j, TDBValue(j, n, dims, zilch)));
-        }
-
-    double guar_int_rate[1] = {0.03};
-    AddEntry(dict_map_val(DB_GuarInt, TDBValue(DB_GuarInt, n, dims, 
guar_int_rate)));
-
-    double fixed_loan_rate[1] = {0.06};
-    AddEntry(dict_map_val(DB_FixedLoanRate, TDBValue(DB_FixedLoanRate, n, 
dims, fixed_loan_rate)));
-
-    double loan_spread[1] = {0.0};
-
-    AddEntry(dict_map_val(DB_GuarRegLoanSpread, TDBValue(DB_GuarRegLoanSpread, 
n, dims, loan_spread)));
-    AddEntry(dict_map_val(DB_CurrRegLoanSpread, TDBValue(DB_CurrRegLoanSpread, 
n, dims, loan_spread)));
-    AddEntry(dict_map_val(DB_GuarPrefLoanSpread, 
TDBValue(DB_GuarPrefLoanSpread, n, dims, loan_spread)));
-    AddEntry(dict_map_val(DB_CurrPrefLoanSpread, 
TDBValue(DB_CurrPrefLoanSpread, n, dims, loan_spread)));
-
-    double affirmative[1] = {1.0};
-
-    AddEntry(dict_map_val(DB_AllowGenAcct, TDBValue(DB_AllowGenAcct, n, dims, 
affirmative)));
-    AddEntry(dict_map_val(DB_AllowPreferredClass, 
TDBValue(DB_AllowPreferredClass, n, dims, affirmative)));
-
-    // premium loads
-
-    double load[1] = {0.025};
-    double cfee[1] = {5.00};
-    double gfee[1] = {12.00};
-    double zero[1] = {0.0};
-
-    AddEntry(dict_map_val(DB_GuarPolFee, TDBValue(DB_GuarPolFee, n, dims, 
gfee)));
-    AddEntry(dict_map_val(DB_GuarSpecAmtLoad, TDBValue(DB_GuarSpecAmtLoad, n, 
dims, zero)));
-    AddEntry(dict_map_val(DB_GuarPremLoadTgt, TDBValue(DB_GuarPremLoadTgt, n, 
dims, load)));
-    AddEntry(dict_map_val(DB_GuarPremLoadExc, TDBValue(DB_GuarPremLoadExc, n, 
dims, load)));
-    AddEntry(dict_map_val(DB_CurrPolFee, TDBValue(DB_CurrPolFee, n, dims, 
cfee)));
-    AddEntry(dict_map_val(DB_CurrSpecAmtLoad, TDBValue(DB_CurrSpecAmtLoad, n, 
dims, zero)));
-    AddEntry(dict_map_val(DB_CurrPremLoadTgt, TDBValue(DB_CurrPremLoadTgt, n, 
dims, load)));
-    AddEntry(dict_map_val(DB_CurrPremLoadExc, TDBValue(DB_CurrPremLoadExc, n, 
dims, load)));
-
-    double minwd[1] = {100.0};
-    AddEntry(dict_map_val(DB_MinWD, TDBValue(DB_MinWD, n, dims, minwd)));
-    double wdfee[1] = {5.0};
-    AddEntry(dict_map_val(DB_WDFee, TDBValue(DB_WDFee, n, dims, wdfee)));
-    double wdfeerate[1] = {0.01};
-    AddEntry(dict_map_val(DB_WDFeeRate, TDBValue(DB_WDFeeRate, n, dims, 
wdfeerate)));
-
-    int guar_coi_dims[n] = {1, 1, 3, 1, 1, 1, 1};
-    // smoker, nonsmoker, unismoke
-    double guar_coi_tables[] = {111, 109, 107};
-    AddEntry
-        (dict_map_val
-            (DB_GuarCOITable
-            ,TDBValue(DB_GuarCOITable, n, guar_coi_dims, guar_coi_tables)
-            )
-        );
-
-    int curr_coi_dims[n] = {1, 4, 3, 1, 1, 1, 1};
-    // preferred, standard, rated, ultrapreferred by smoker, nonsmoker, 
unismoke
-    double curr_coi_tables[] =
-        {
-        2, 3, 1, // pref  sm ns us
-        5, 6, 4, // std   sm ns us
-        5, 6, 4, // rated sm ns us
-        0, 0, 0, // ultra sm ns us
-        };
-    AddEntry
-        (dict_map_val
-            (DB_CurrCOITable
-            ,TDBValue(DB_CurrCOITable, n, curr_coi_dims, curr_coi_tables)
-            )
-        );
-
-    double corr_table[1] = {7};
-    AddEntry(dict_map_val(DB_CorridorTable, TDBValue(DB_CorridorTable, n, 
dims, corr_table)));
-
-    double wp_table[1] = {8};
-    AddEntry(dict_map_val(DB_WPTable, TDBValue(DB_WPTable, n, dims, 
wp_table)));
-
-    double add_table[1] = {9};
-    AddEntry(dict_map_val(DB_ADDTable, TDBValue(DB_ADDTable, n, dims, 
add_table)));
-
-    double endtage[1] = {100};
-    AddEntry(dict_map_val(DB_EndtAge, TDBValue(DB_EndtAge, n, dims, endtage)));
-
-    double anb[1] = {1.0};
-    AddEntry(dict_map_val(DB_AgeLastOrNearest, TDBValue(DB_AgeLastOrNearest, 
n, dims, anb)));
-
-    double minspecamt[1] = {10000.0};
-    AddEntry(dict_map_val(DB_MinSpecAmt, TDBValue(DB_MinSpecAmt, n, dims, 
minspecamt)));
-
-    double max_gen_acct_rate[1] = {0.12};
-    AddEntry(dict_map_val(DB_MaxGenAcctRate, TDBValue(DB_MaxGenAcctRate, n, 
dims, max_gen_acct_rate)));
-    double max_sep_acct_rate[1] = {0.12};
-    AddEntry(dict_map_val(DB_MaxSepAcctRate, TDBValue(DB_MaxSepAcctRate, n, 
dims, max_sep_acct_rate)));
-
-    double allow_loan[1] = {1.0};
-    AddEntry(dict_map_val(DB_AllowLoan, TDBValue(DB_AllowLoan, n, dims, 
allow_loan)));
-    double allow_wd[1] = {1.0};
-    AddEntry(dict_map_val(DB_AllowWD, TDBValue(DB_AllowWD, n, dims, 
allow_wd)));
-    double allow_flat_extras[1] = {1.0};
-    AddEntry(dict_map_val(DB_AllowFlatExtras, TDBValue(DB_AllowFlatExtras, n, 
dims, allow_flat_extras)));
-    double allow_change_to_dbo2[1] = {1.0};
-    AddEntry(dict_map_val(DB_AllowChangeToDBO2, TDBValue(DB_AllowChangeToDBO2, 
n, dims, allow_change_to_dbo2)));
-    double allow_dbo3[1] = {1.0};
-    AddEntry(dict_map_val(DB_AllowDBO3, TDBValue(DB_AllowDBO3, n, dims, 
allow_dbo3)));
-
-    double surrchg_prem_mult[1] = {0.0};
-    AddEntry(dict_map_val(DB_SurrChgPremMult, TDBValue(DB_SurrChgPremMult, n, 
dims, surrchg_prem_mult)));
-    double surrchg_av_mult[1] = {0.0};
-    AddEntry(dict_map_val(DB_SurrChgAVMult, TDBValue(DB_SurrChgAVMult, n, 
dims, surrchg_av_mult)));
-    double surrchg_sa_mult[1] = {0.0};
-    AddEntry(dict_map_val(DB_SurrChgSAMult, TDBValue(DB_SurrChgSAMult, n, 
dims, surrchg_sa_mult)));
-    double surrchg_av_dur_factor[1] = {1.0};
-    AddEntry(dict_map_val(DB_SurrChgAVDurFactor, 
TDBValue(DB_SurrChgAVDurFactor, n, dims, surrchg_av_dur_factor)));
-    double surrchg_sa_dur_factor[1] = {1.0};
-    AddEntry(dict_map_val(DB_SurrChgSADurFactor, 
TDBValue(DB_SurrChgSADurFactor, n, dims, surrchg_sa_dur_factor)));
-
-    double ledger_type[1] = {mce_ill_reg};
-    AddEntry(dict_map_val(DB_LedgerType, TDBValue(DB_LedgerType, n, dims, 
ledger_type)));
-
-    double no_lapse_always_active[1] = {0.0};
-    AddEntry(dict_map_val(DB_NoLapseAlwaysActive, 
TDBValue(DB_NoLapseAlwaysActive, n, dims, no_lapse_always_active)));
-    double no_lapse_min_dur[1] = {0.0};
-    AddEntry(dict_map_val(DB_NoLapseMinDur, TDBValue(DB_NoLapseMinDur, n, 
dims, no_lapse_min_dur)));
-    double no_lapse_min_age[1] = {0.0};
-    AddEntry(dict_map_val(DB_NoLapseMinAge, TDBValue(DB_NoLapseMinAge, n, 
dims, no_lapse_min_age)));
-
-    AddEntry(dict_map_val(DB_NominallyPar, TDBValue(DB_NominallyPar, n, dims, 
zero)));
-    AddEntry(dict_map_val(DB_Has1035ExchCharge, TDBValue(DB_Has1035ExchCharge, 
n, dims, zero)));
-    AddEntry(dict_map_val(DB_SmokeOrTobacco, TDBValue(DB_SmokeOrTobacco, n, 
dims, zero)));
-    AddEntry(dict_map_val(DB_DACTaxFundCharge, TDBValue(DB_DACTaxFundCharge, 
n, dims, zero)));
-    AddEntry(dict_map_val(DB_AllowWP, TDBValue(DB_AllowWP, n, dims, zero)));
-    AddEntry(dict_map_val(DB_AllowADD, TDBValue(DB_AllowADD, n, dims, zero)));
-    AddEntry(dict_map_val(DB_AllowSpouse, TDBValue(DB_AllowSpouse, n, dims, 
zero)));
-    AddEntry(dict_map_val(DB_AllowChild, TDBValue(DB_AllowChild, n, dims, 
zero)));
-
-    double exp_rat_amort_period[1] = {4.0};
-    AddEntry(dict_map_val(DB_ExpRatAmortPeriod, TDBValue(DB_ExpRatAmortPeriod, 
n, dims, exp_rat_amort_period)));
-}
-
-//===========================================================================
-void DBDictionary::AddEntry(dict_map_val const& e)
-{
-    (*dictionary)[e.first] = e.second;
-}
-
-//===========================================================================
-// Unimplemented in this branch.
-void print_databases()
-{
-}
-#endif // 0
-

Copied: lmi/trunk/dbdict.cpp (from rev 4893, lmi/trunk/ihs_dbdict.cpp)
===================================================================
--- lmi/trunk/dbdict.cpp                                (rev 0)
+++ lmi/trunk/dbdict.cpp        2010-05-02 17:06:17 UTC (rev 4894)
@@ -0,0 +1,806 @@
+// Product-database map.
+//
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 
2008, 2009, 2010 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif // __BORLANDC__
+
+#include "dbdict.hpp"
+
+#include "alert.hpp"
+#include "data_directory.hpp"
+#include "dbnames.hpp"
+#include "global_settings.hpp"
+#include "mc_enum_type_enums.hpp"
+#include "miscellany.hpp"
+#include "oecumenic_enumerations.hpp"
+#include "xml_lmi.hpp"
+#include "xml_serialize.hpp"
+
+#include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+
+#include <limits>
+#include <sstream>
+
+std::string DBDictionary::CachedFilename;
+
+int const NumberOfEntries = DB_LAST;
+
+//============================================================================
+DBDictionary& DBDictionary::instance()
+{
+    static DBDictionary z;
+    return z;
+}
+
+//============================================================================
+DBDictionary::DBDictionary()
+{
+}
+
+//============================================================================
+DBDictionary::~DBDictionary()
+{
+}
+
+namespace xml_serialize
+{
+template<> struct xml_io<TDBValue>
+{
+    typedef TDBValue T;
+    static void   to_xml(xml::element& e, T const& t) {t.write(e);}
+    static void from_xml(xml::element const& e, T& t) {t.read (e);}
+};
+
+/// Specialize xml_io<> for dict_map rather than coding a generic
+/// xml_io<std::map>, because the key would be stored redundantly:
+/// it's already part of TDBValue.
+
+template<> struct xml_io<dict_map>
+{
+    static void to_xml(xml::element& e, dict_map const& t)
+    {
+        e.erase(e.begin(), e.end());
+        typedef dict_map::const_iterator tci;
+        for(tci i = t.begin(); i != t.end(); ++i)
+            {
+            // This is not equivalent to calling set_element():
+            // multiple <item> elements are expressly permitted.
+            xml::element z("item");
+            xml_serialize::to_xml(z, i->second);
+            e.push_back(z);
+            }
+    }
+
+    static void from_xml(xml::element const& e, dict_map& t)
+    {
+        t.clear();
+        xml::const_nodes_view const items(e.elements("item"));
+        typedef xml::const_nodes_view::const_iterator cnvi;
+        for(cnvi i = items.begin(); i != items.end(); ++i)
+            {
+            TDBValue z;
+            xml_serialize::from_xml(*i, z);
+            t[z.GetKey()] = z;
+            }
+    }
+};
+} // namespace xml_serialize
+
+namespace
+{
+std::string xml_root_name()
+{
+    return "database";
+}
+} // Unnamed namespace.
+
+dict_map const& DBDictionary::GetDictionary() const
+{
+    return dictionary_;
+}
+
+//============================================================================
+void DBDictionary::Init(std::string const& NewFilename)
+{
+    // Perform the expensive operation of reading the dictionary from
+    // file only if the cached file name doesn't match the new file
+    // name, or if the cached file name is an empty string--which
+    // means either that no dictionary has yet been read, or that the
+    // cached file name was deliberately set to an empty string in
+    // order to invalidate the cached database.
+    //
+    // TODO ?? We ought to address the problem that someone might have
+    // modified that file in the meantime.
+
+    if
+        (
+           ""          != CachedFilename
+        && NewFilename == CachedFilename
+        )
+        {
+        return;
+        }
+
+    CachedFilename = NewFilename;
+
+    if(access(NewFilename.c_str(), R_OK))
+        {
+        BadFile(NewFilename, "could not be found."); // dubious
+        fatal_error()
+            << "File '"
+            << NewFilename
+            << "' is required but could not be found. Try reinstalling."
+            << LMI_FLUSH
+            ;
+        }
+
+    xml_lmi::dom_parser parser(NewFilename);
+    xml::element const& root = parser.root_node(xml_root_name());
+
+    xml_serialize::from_xml(root, dictionary_);
+
+    if(NumberOfEntries != static_cast<int>(dictionary_.size()))
+        {
+        std::ostringstream oss;
+        oss
+            << "is not up to date or is corrupted."
+            << " It should contain " << NumberOfEntries
+            << " elements, but it actually contains " << dictionary_.size()
+            << " elements."
+            ;
+        BadFile(NewFilename, oss.str());
+        }
+}
+
+//============================================================================
+void DBDictionary::InvalidateCache()
+{
+    CachedFilename = "";
+}
+
+//============================================================================
+// TODO ?? Does this function make the code clearer, or less clear?
+void DBDictionary::BadFile(std::string const& Filename, std::string const& why)
+{
+    InvalidateCache();
+
+    std::string s = ", which is required for the product selected, ";
+    s += why;
+    s += " Try reinstalling. Other products might work in the meantime.";
+
+    // It's generally pointless to proceed.
+    if(global_settings::instance().mellon())
+        {
+        hobsons_choice() << "File '" << Filename << "'" << s << LMI_FLUSH;
+        }
+    else
+        {
+        fatal_error() << "File '" << Filename << "'" << s << LMI_FLUSH;
+        }
+}
+
+//============================================================================
+void DBDictionary::WriteDB(std::string const& filename)
+{
+    if(NumberOfEntries != static_cast<int>(dictionary_.size()))
+        {
+        fatal_error()
+            << "Error writing database '"
+            << filename
+            << "': the database has " << dictionary_.size()
+            << " entries, but should have " << NumberOfEntries << '.'
+            ;
+        for(int j = 0; j < NumberOfEntries; j++)
+            {
+            if(!dictionary_.count(j))
+                {
+                fatal_error() << " Key " << j << " not found.";
+                }
+            }
+        fatal_error() << LMI_FLUSH;
+        }
+
+    xml_lmi::xml_document document(xml_root_name());
+    xml::element& root = document.root_node();
+
+    xml_lmi::set_attr(root, "version", "0");
+    xml_serialize::to_xml(root, dictionary_);
+
+    // Instead of this:
+//    document.save(filename);
+    // for the nonce, explicitly change the extension, in order to
+    // force external product-file code to use the new extension.
+    fs::path path(filename, fs::native);
+    path = fs::change_extension(path, ".database");
+    document.save(path.string());
+}
+
+//===========================================================================
+void DBDictionary::Add(TDBValue const& e)
+{
+    dictionary_.erase(e.GetKey());
+    dictionary_.insert(dict_map_val(e.GetKey(), e));
+}
+
+//============================================================================
+// Initialize all database entities to not-necessarily-plausible values.
+void DBDictionary::InitDB()
+{
+    static double const bignum = std::numeric_limits<double>::max();
+
+    dictionary_.clear();
+    for(int j = DB_FIRST; j < DB_LAST; ++j)
+        {
+        Add(TDBValue(j, 0.0));
+        }
+
+    // It would be dangerous to set these to zero.
+    Add(TDBValue(DB_CCOIMultiplier      , 1.0));
+    Add(TDBValue(DB_GCOIMultiplier      , 1.0));
+    Add(TDBValue(DB_SubstdTblMult       , 1.0));
+    Add(TDBValue(DB_SurrChgSADurFactor  , 1.0));
+    Add(TDBValue(DB_SurrChgAVDurFactor  , 1.0));
+
+    // Usually the maximum is a reciprocal, e.g., 1/11 or 1/12; for
+    // greatest precision, store the reciprocal of that reciprocal,
+    // e.g., 11 or 12.
+    Add(TDBValue(DB_MaxMonthlyCoiRate   , 12.0));
+
+    Add(TDBValue(DB_GuarIntSpread       , bignum));
+
+    Add(TDBValue(DB_CurrCOITable0Limit  , bignum));
+    Add(TDBValue(DB_CurrCOITable1       , 999));
+    Add(TDBValue(DB_CurrCOITable1Limit  , bignum));
+    Add(TDBValue(DB_CurrCOITable2       , 999));
+
+    Add(TDBValue(DB_SpecAmtLoadLimit    , bignum));
+    Add(TDBValue(DB_DynSepAcctLoadLimit , bignum));
+    Add(TDBValue(DB_ADDLimit            , bignum));
+    Add(TDBValue(DB_ExpPerKLimit        , bignum));
+
+    // SD Chapter 260 (HB 1200), signed 2008-02-19, amended 58-6-70
+    // by removing the former million-dollar threshold.
+    //
+    // TODO ?? For now, only the threshold here is changed. Much
+    // complex code elsewhere can be removed when time permits.
+
+    int premium_tax_dimensions[TDBValue::e_number_of_axes] = {1, 1, 1, 1, 1, 
53, 1};
+    double premium_tax_retaliation_threshold[53] =
+        {
+    //  AL      AK      AZ      AR      CA      CO      CT
+        bignum, 0.0   , bignum, bignum, bignum, bignum, bignum,
+    //  DE      DC      FL      GA      HI      ID
+        bignum, bignum, bignum, bignum, bignum, bignum,
+    //  IL      IN      IA      KS      KY      LA      ME
+        bignum, bignum, bignum, bignum, bignum, bignum, bignum,
+    //  MD      MA      MI      MN      MS      MO
+        bignum, bignum, bignum, bignum, bignum, bignum,
+    //  MT      NE      NV      NH      NJ      NM      NY
+        bignum, bignum, bignum, bignum, bignum, bignum, bignum,
+    //  NC      ND      OH      OK      OR      PA
+        bignum, bignum, bignum, bignum, bignum, bignum,
+    //  PR      RI      SC      SD      TN      TX      UT
+        bignum, bignum, bignum, 0.0   , bignum, bignum, bignum,
+    //  VT      VA      WA      WV      WI      WY      XX
+        bignum, bignum, bignum, bignum, bignum, bignum, 0.0   ,
+        };
+    Add
+        (TDBValue
+            (DB_PremTaxRetalLimit
+            ,TDBValue::e_number_of_axes
+            ,premium_tax_dimensions
+            ,premium_tax_retaliation_threshold
+            )
+        );
+}
+
+//============================================================================
+void DBDictionary::WriteSampleDBFile()
+{
+    InitDB();
+    Add(TDBValue(DB_GuarPolFee          , 8.00));
+    Add(TDBValue(DB_GuarSpecAmtLoad     , 0.0));
+    Add(TDBValue(DB_GuarIssueFee        , 0.0));
+    Add(TDBValue(DB_GuarFundAdminChg    , 0.0));
+    Add(TDBValue(DB_GuarPremLoadTgt     , 0.07));
+    Add(TDBValue(DB_GuarPremLoadExc     , 0.04));
+    Add(TDBValue(DB_GuarPremLoadTgtRfd  , 0.00));
+    Add(TDBValue(DB_GuarPremLoadExcRfd  , 0.00));
+    Add(TDBValue(DB_GuarAcctValLoadAMD  , 0.0));
+    Add(TDBValue(DB_CurrPolFee          , 5.00));
+    Add(TDBValue(DB_CurrSpecAmtLoad     , 0.0));
+    Add(TDBValue(DB_CurrIssueFee        , 0.0));
+    Add(TDBValue(DB_CurrFundAdminChg    , 0.0));
+    Add(TDBValue(DB_CurrPremLoadTgt     , 0.05));
+    Add(TDBValue(DB_CurrPremLoadExc     , 0.02));
+    Add(TDBValue(DB_CurrPremLoadTgtRfd  , 0.00));
+    Add(TDBValue(DB_CurrPremLoadExcRfd  , 0.00));
+    Add(TDBValue(DB_CurrAcctValLoadAMD  , 0.0));
+    Add(TDBValue(DB_DACTaxPremLoad      , 0.01));
+    Add(TDBValue(DB_FundCharge          , 0.0));
+    Add(TDBValue(DB_PremTaxFundCharge   , 0.0));
+    Add(TDBValue(DB_DACTaxFundCharge    , 0.0));
+    Add(TDBValue(DB_WaivePmTxInt1035    , true));
+    Add(TDBValue(DB_FirstWDYear         , 0.0));
+    Add(TDBValue(DB_MaxWDAVMult         , 1.0));
+    Add(TDBValue(DB_MaxWDDed            , mce_to_next_anniversary));
+    Add(TDBValue(DB_MinWD               , 100.0));
+    Add(TDBValue(DB_WDFee               , 25.0));
+    Add(TDBValue(DB_WDFeeRate           , 0.02));
+    Add(TDBValue(DB_WDCanDecrSADBO1     , true));
+    Add(TDBValue(DB_WDCanDecrSADBO2     , true));
+    Add(TDBValue(DB_WDCanDecrSADBO3     , true));
+    Add(TDBValue(DB_FirstLoanYear       , 0.0));
+    Add(TDBValue(DB_AllowPrefLoan       , false));
+    Add(TDBValue(DB_AllowFixedLoan      , true));
+    Add(TDBValue(DB_FixedLoanRate       , 0.06));
+    Add(TDBValue(DB_AllowVLR            , true));
+    Add(TDBValue(DB_MaxLoanAVMult       , 1.0));
+    Add(TDBValue(DB_MaxLoanDed          , mce_to_next_anniversary));
+    Add(TDBValue(DB_GuarPrefLoanSpread  , 0.0));
+    Add(TDBValue(DB_GuarRegLoanSpread   , 0.04));
+    Add(TDBValue(DB_CurrPrefLoanSpread  , 0.0));
+    Add(TDBValue(DB_CurrRegLoanSpread   , 0.02));
+    Add(TDBValue(DB_GuarInt             , 0.03));
+    Add(TDBValue(DB_NAARDiscount        , 0.00246627));
+    Add(TDBValue(DB_GuarIntSpread       , 0.03));
+    Add(TDBValue(DB_GuarMandE           , 0.009));
+    Add(TDBValue(DB_CurrIntSpread       , 0.01));
+    Add(TDBValue(DB_CurrMandE           , 0.009));
+    Add(TDBValue(DB_BonusInt            , 0.0));
+    Add(TDBValue(DB_IntFloor            , 0.0));
+    Add(TDBValue(DB_SepAcctSpreadMethod , mce_spread_is_effective_annual));
+    Add(TDBValue(DB_DynamicMandE        , false));
+
+    // gender, smoker
+    int dims313[TDBValue::e_number_of_axes] = {3, 1, 3, 1, 1, 1, 1};
+
+    // US 1980 CSO age last; unisex = table D.
+    // Male uses table E, which is correct, as opposed to table F,
+    // which contains a numerical error but was adopted by NAIC.
+    double TgCOI[9] =
+        {
+         39,  37,  35, // female: sm ns us
+         45,  57,  41, // male:   sm ns us
+        111, 109, 107, // unisex: sm ns us
+        };
+
+    // For now at least, just use (a multiple of) guaranteed COI rates
+    // as current.
+    Add(TDBValue(DB_CurrCOITable, TDBValue::e_number_of_axes, dims313, TgCOI));
+    Add(TDBValue(DB_GuarCOITable, TDBValue::e_number_of_axes, dims313, TgCOI));
+
+    Add(TDBValue(DB_COINYMinTable       , 0.0));
+
+    double coimult[9] =
+        {
+        0.40, 0.30, 0.35, // female: sm ns us
+        0.60, 0.50, 0.55, // male:   sm ns us
+        0.50, 0.40, 0.45, // unisex: sm ns us
+        };
+    Add(TDBValue(DB_CCOIMultiplier, TDBValue::e_number_of_axes, dims313, 
coimult));
+
+    Add(TDBValue(DB_UseNYCOIFloor       , 0.0));
+    Add(TDBValue(DB_GuarCOICeiling      , 0.0));
+    Add(TDBValue(DB_COIGuarIsMin        , 0.0));
+    Add(TDBValue(DB_COINonforfIsGuar    , 0.0));
+    Add(TDBValue(DB_CCoiIsAnnual        , true));
+    Add(TDBValue(DB_GCoiIsAnnual        , true));
+    Add(TDBValue(DB_MCoiIsAnnual        , true));
+    Add(TDBValue(DB_AgeLastOrNearest    , 0, "0 = ALB")); // ALB
+    Add(TDBValue(DB_AllowRetirees       , true));
+    Add(TDBValue(DB_MinSpecAmt          , 100000.0));
+    Add(TDBValue(DB_AllowSubstdTable    , true));
+    Add(TDBValue(DB_AllowFlatExtras     , true));
+    Add(TDBValue(DB_MinIssAge           , 15));
+    Add(TDBValue(DB_MaxIssAge           , 70));
+    Add(TDBValue(DB_MinIssSpecAmt       , 0.0));
+    Add(TDBValue(DB_MaxIssSpecAmt       , 0.0));
+    Add(TDBValue(DB_MinRenlBaseSpecAmt  , 50000.0));
+    Add(TDBValue(DB_MinRenlSpecAmt      , 50000.0));
+    Add(TDBValue(DB_MaxRenlSpecAmt      , 0.0));
+    Add(TDBValue(DB_MinSpecAmtIncr      , 0.0));
+    Add(TDBValue(DB_MaxIncrAge          , 99));
+    Add(TDBValue(DB_MinPmt              , 0.0));
+    Add(TDBValue(DB_SmokeOrTobacco      , oe_tobacco_nontobacco));
+    Add(TDBValue(DB_AllowUnisex         , true));
+    Add(TDBValue(DB_AllowSexDistinct    , true));
+    Add(TDBValue(DB_AllowUnismoke       , true));
+    Add(TDBValue(DB_AllowSmokeDistinct  , true));
+    Add(TDBValue(DB_AllowFullUW         , true));
+    Add(TDBValue(DB_AllowSimpUW         , true));
+    Add(TDBValue(DB_AllowGuarUW         , true));
+    Add(TDBValue(DB_AllowMortBlendSex   , true));
+    Add(TDBValue(DB_AllowMortBlendSmoke , true));
+    Add(TDBValue(DB_AllowRatedWP        , true));
+    Add(TDBValue(DB_AllowRatedADD       , true));
+    Add(TDBValue(DB_AllowRatedTerm      , true));
+    Add(TDBValue(DB_Allowable           , true));
+    Add(TDBValue(DB_AllowPreferredClass , true));
+    Add(TDBValue(DB_AllowCVAT           , true));
+    Add(TDBValue(DB_AllowGPT            , true));
+
+    // This is just a sample product, so we make do with plausible
+    // all-male seven-pay premiums, and use GPT corridor factors for
+    // CVAT.
+    Add(TDBValue(DB_CorridorTable       , 7));
+    Add(TDBValue(DB_TAMRA7PayTable      , 10));
+
+    // Following IRS Notice 88-128, use only the male and female
+    // tables with no smoker distinction, and a unisex table where
+    // required by state law.
+    //
+    // US 1980 CSO age last, not smoker distinct. Unisex = table D.
+    // Male uses table E, which is correct, as opposed to table F,
+    // which contains a numerical error but was adopted by NAIC.
+    int dims311[TDBValue::e_number_of_axes] = {3, 1, 1, 1, 1, 1, 1}; // gender
+    double T7702q[9] = {35, 41, 107,}; // Female, male, unisex.
+    Add(TDBValue(DB_IRC7702QTable, TDBValue::e_number_of_axes, dims311, 
T7702q));
+
+    Add(TDBValue(DB_PremLoad7702        , 0.02));
+    Add(TDBValue(DB_AllowDBO1           , true));
+    Add(TDBValue(DB_AllowDBO2           , true));
+    Add(TDBValue(DB_AllowDBO3           , true));
+    Add(TDBValue(DB_OptChgCanIncrSA     , true));
+    Add(TDBValue(DB_OptChgCanDecrSA     , true));
+    Add(TDBValue(DB_NonforfQTable       , 0.0));
+    Add(TDBValue(DB_SurrChgByFormula    , 0.0));
+    Add(TDBValue(DB_SurrChgPeriod       , 0.0));
+    Add(TDBValue(DB_SurrChgZeroDur      , 0.0));
+    Add(TDBValue(DB_SurrChgNLPMult      , 0.0));
+    Add(TDBValue(DB_SurrChgNLPMax       , 0.0));
+    Add(TDBValue(DB_SurrChgEAMax        , 0.0));
+    Add(TDBValue(DB_SurrChgPremMult     , 0.0));
+    Add(TDBValue(DB_SurrChgIsMly        , 0.0));
+
+    // These aren't actual premium tax rates. Actual rates change
+    // often, and depend on the insurer's domicile because of
+    // retaliation. Instead of giving rates that appear to be 'right'
+    // but could be valid only on a certain date in a certain
+    // domicile, we use two percent in every state except AK and SD
+    // because those two states have a tiered premium tax that this
+    // program can handle, and except fictitious state XX, which may
+    // be used where no premium tax applies, as for offshore business.
+    // DE has a tiered premium tax that this program cannot yet
+    // handle, so we punt and use two percent in DE.
+    int premium_tax_dimensions[TDBValue::e_number_of_axes] = {1, 1, 1, 1, 1, 
53, 1};
+    double const tiered = 0.0;
+    double premium_tax_rates[53] =
+        {
+    //  AL      AK      AZ      AR      CA      CO      CT
+        0.0200, tiered, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
+    //  DE      DC      FL      GA      HI      ID
+        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
+    //  IL      IN      IA      KS      KY      LA      ME
+        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
+    //  MD      MA      MI      MN      MS      MO
+        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
+    //  MT      NE      NV      NH      NJ      NM      NY
+        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
+    //  NC      ND      OH      OK      OR      PA
+        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
+    //  PR      RI      SC      SD      TN      TX      UT
+        0.0200, 0.0200, 0.0200, tiered, 0.0200, 0.0200, 0.0200,
+    //  VT      VA      WA      WV      WI      WY      XX
+        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0000,
+        };
+    Add
+        (TDBValue
+            (DB_PremTaxRate
+            ,TDBValue::e_number_of_axes
+            ,premium_tax_dimensions
+            ,premium_tax_rates
+            )
+        );
+
+    Add(TDBValue(DB_PremTaxState        , oe_ee_state));
+    Add(TDBValue(DB_EndtAge             , 100));
+    Add(TDBValue(DB_AllowExtEndt        , true));
+    Add(TDBValue(DB_AllowGenAcct        , true));
+    Add(TDBValue(DB_AllowSepAcct        , true));
+    Add(TDBValue(DB_MinPremType         , oe_monthly_deduction));
+    Add(TDBValue(DB_TgtPremType         , oe_modal_nonmec));
+    Add(TDBValue(DB_TgtPmFixedAtIssue   , false));
+    Add(TDBValue(DB_TgtPmIgnoreSubstd   , true));
+    Add(TDBValue(DB_NoLapseMinDur       , 0.0));
+    Add(TDBValue(DB_NoLapseMinAge       , 0.0));
+    Add(TDBValue(DB_NoLapseUnratedOnly  , false));
+    Add(TDBValue(DB_NoLapseOpt1Only     , false));
+    Add(TDBValue(DB_PremRefund          , 0.0));
+    // Reuse current COI rates as current and guaranteed term rates.
+    Add(TDBValue(DB_TermTable, TDBValue::e_number_of_axes, dims313, TgCOI));
+    Add(TDBValue(DB_GuarTermTable, TDBValue::e_number_of_axes, dims313, 
TgCOI));
+    Add(TDBValue(DB_AllowTerm           , true));
+    Add(TDBValue(DB_TermMinIssAge       , 0.0));
+    Add(TDBValue(DB_TermMaxIssAge       , 0.0));
+    Add(TDBValue(DB_TermForcedConvAge   , 0.0));
+    Add(TDBValue(DB_MaxTermProportion   , 0.0));
+    Add(TDBValue(DB_TermCOIRate         , 0.0));
+    Add(TDBValue(DB_TermPremRate        , 0.0));
+    Add(TDBValue(DB_WPTable             , 8));
+    Add(TDBValue(DB_AllowWP             , true));
+    Add(TDBValue(DB_WPMinIssAge         , 0.0));
+    Add(TDBValue(DB_WPMaxIssAge         , 0.0));
+    Add(TDBValue(DB_WPMax               , 0.0));
+    Add(TDBValue(DB_WPCOIRate           , 0.0));
+    Add(TDBValue(DB_WPPremRate          , 0.0));
+    // SOA qx_ins table 708 is 70-75 US ADB experience.
+    Add(TDBValue(DB_ADDTable            , 708));
+    Add(TDBValue(DB_AllowADD            , true));
+    Add(TDBValue(DB_ADDMinIssAge        , 0.0));
+    Add(TDBValue(DB_ADDMaxIssAge        , 0.0));
+    Add(TDBValue(DB_ADDLimit            , 1000000.0));
+    Add(TDBValue(DB_ADDCOIRate          , 0.0));
+    Add(TDBValue(DB_ADDPremRate         , 0.0));
+    Add(TDBValue(DB_WeightClass         , 0.0));
+    Add(TDBValue(DB_WeightGender        , 0.0));
+    Add(TDBValue(DB_WeightSmoking       , 0.0));
+    Add(TDBValue(DB_WeightAge           , 0.0));
+    Add(TDBValue(DB_WeightSpecAmt       , 0.0));
+    Add(TDBValue(DB_WeightState         , 0.0));
+    Add(TDBValue(DB_FullExpPol          , 0.0));
+    Add(TDBValue(DB_FullExpPrem         , 0.0));
+    Add(TDBValue(DB_FullExpDumpin       , 0.0));
+    Add(TDBValue(DB_FullExpPerK         , 0.0));
+    Add(TDBValue(DB_VarExpPol           , 0.0));
+    Add(TDBValue(DB_VarExpPrem          , 0.0));
+    Add(TDBValue(DB_VarExpDumpin        , 0.0));
+    Add(TDBValue(DB_VarExpPerK          , 0.0));
+    Add(TDBValue(DB_MedicalProportion   , 0.0));
+    Add(TDBValue(DB_UWTestCost          , 0.0));
+    Add(TDBValue(DB_VxBasicQTable       , 0.0));
+    Add(TDBValue(DB_VxDeficQTable       , 0.0));
+    Add(TDBValue(DB_VxTaxQTable         , 0.0));
+    Add(TDBValue(DB_StatVxInt           , 0.0));
+    Add(TDBValue(DB_TaxVxInt            , 0.0));
+    Add(TDBValue(DB_StatVxQ             , 0.0));
+    Add(TDBValue(DB_TaxVxQ              , 0.0));
+    Add(TDBValue(DB_DefVxQ              , 0.0));
+    Add(TDBValue(DB_NonforfQ            , 0.0));
+    Add(TDBValue(DB_CompTarget          , 0.0));
+    Add(TDBValue(DB_CompExcess          , 0.0));
+    Add(TDBValue(DB_CompChargeBack      , 0.0));
+    Add(TDBValue(DB_LapseRate           , 0.0));
+    Add(TDBValue(DB_ReqSurpNAAR         , 0.0));
+    Add(TDBValue(DB_ReqSurpVx           , 0.0));
+    Add(TDBValue(DB_LICFitRate          , 0.0));
+    Add(TDBValue(DB_LicDacTaxRate       , 0.0));
+    Add(TDBValue(DB_GDBVxMethod         , 0.0));
+    Add(TDBValue(DB_PrimaryHurdle       , 0.0));
+    Add(TDBValue(DB_SecondaryHurdle     , 0.0));
+    Add(TDBValue(DB_LedgerType          , mce_ill_reg));
+    Add(TDBValue(DB_AllowExpRating      , false));
+
+    // These aren't really NY Table Y group rates--in fact, they're
+    // US 65-70 male ALB. Though NY Table Y is occasionally
+    // encountered in the group-carveout market, it's not included
+    // in the SOA's databases; for default initialization, a widely-
+    // available table is preferred.
+    //
+    // DATABASE !! Hence, the entity is misnamed; it really means
+    // something like "group proxy rate". However, what's really
+    // wanted is a choice among tables. The same can be said of
+    // 'DB_83GamTable', which really means "partial-mortality table";
+    // this support request:
+    //   http://savannah.nongnu.org/support/?105593
+    // would offer a choice and make that database entity unnecessary.
+    Add(TDBValue(DB_TableYTable         , 358));
+
+    // Use male rates for unisex--1983 GAM seems to have no unisex version.
+    double T83Gam[3] = {825, 826, 826,};
+    Add(TDBValue(DB_83GamTable, TDBValue::e_number_of_axes, dims311, T83Gam, 
"Use male rates for unisex--1983 GAM seems to have no unisex version."));
+
+    Add(TDBValue(DB_AllowWD             , true));
+    Add(TDBValue(DB_AllowLoan           , true));
+    Add(TDBValue(DB_AllowChangeToDBO2   , true));
+    Add(TDBValue(DB_AllowSAIncr         , true));
+    Add(TDBValue(DB_NoLapseAlwaysActive , false));
+    Add(TDBValue(DB_PrefOrSelect        , oe_called_select));
+    Add(TDBValue(DB_ExpRatStdDevMult    , 0.0));
+    Add(TDBValue(DB_ExpRatIBNRMult      , 0.0));
+    Add(TDBValue(DB_ExpRatCOIRetention  , 0.0));
+    Add(TDBValue(DB_StableValFundCharge , 0.0));
+    Add(TDBValue(DB_AmortPmLdFundCharge , 0.0030));
+    Add(TDBValue(DB_AllowAmortPremLoad  , false));
+    Add(TDBValue(DB_PmTxAmortPeriod     , 0));
+    Add(TDBValue(DB_PmTxAmortIntRate    , 0.0));
+    // Pass through premium tax.
+    Add
+        (TDBValue
+            (DB_PremTaxLoad
+            ,TDBValue::e_number_of_axes
+            ,premium_tax_dimensions
+            ,premium_tax_rates
+            )
+        );
+    Add(TDBValue(DB_AllowHoneymoon      , true));
+    // Set target equal to seven-pay premium.
+    Add(TDBValue(DB_TgtPremTable        , 10));
+    Add(TDBValue(DB_TgtPremPolFee       , 0.0));
+    Add(TDBValue(DB_AllowExtraAssetComp , true));
+    Add(TDBValue(DB_AllowExtraPremComp  , true));
+    Add(TDBValue(DB_AssetChargeType     , oe_asset_charge_spread));
+    Add(TDBValue(DB_AllowUltraPrefClass , false));
+    Add(TDBValue(DB_MaxGenAcctRate      , 0.06));
+    Add(TDBValue(DB_MaxSepAcctRate      , 0.12));
+    Add(TDBValue(DB_MaxVLRRate          , 0.18));
+    Add(TDBValue(DB_SurrChgAVMult       , 0.0));
+    Add(TDBValue(DB_IntSpreadFreq       , mce_spread_daily));
+    Add(TDBValue(DB_StateApproved       , true));
+    Add(TDBValue(DB_AllowStateXX        , true));
+    Add(TDBValue(DB_AllowForeign        , true));
+    Add(TDBValue(DB_AllowCustomFund     , false));
+    Add(TDBValue(DB_AllowNo7702         , false));
+    Add(TDBValue(DB_EnforceNAARLimit    , true));
+    Add(TDBValue(DB_DynamicSepAcctLoad  , false));
+    Add(TDBValue(DB_SpecAmtLoadLimit    , 10000000.0));
+    Add(TDBValue(DB_Equiv7702DBO3       , 0));
+    Add(TDBValue(DB_ExpRatRiskCOIMult   , 0));
+    Add(TDBValue(DB_SurrChgSAMult       , 0.0));
+    Add(TDBValue(DB_AllowSpouse         , false));
+    Add(TDBValue(DB_AllowChild          , false));
+
+    // Spouse and child riders unavailable, so it doesn't matter
+    // what table we specify.
+    Add(TDBValue(DB_SpouseRiderTable    , 708));
+    Add(TDBValue(DB_ChildRiderTable     , 708));
+
+    Add(TDBValue(DB_GAIntBonus          , 0.0));
+
+    // Allow experience rating.
+    Add(TDBValue(DB_AllowExpRating      , 1.0));
+    Add(TDBValue(DB_ExpRatIBNRMult      , 6.0));
+    Add(TDBValue(DB_ExpRatAmortPeriod   , 4.0));
+
+    WriteDB(AddDataDir("sample.database"));
+}
+
+/// Initialize the built-in database for the antediluvian branch.
+
+void DBDictionary::InitAntediluvian()
+{
+    dictionary_.clear();
+
+    // Zero is inappropriate for some entities ("DB_CCOIMultiplier",
+    // e.g.), but the antediluvian branch doesn't actually use most
+    // database entities.
+    for(int j = DB_FIRST; j < DB_LAST; ++j)
+        {
+        Add(TDBValue(j, 0.0));
+        }
+
+    Add(TDBValue(DB_GuarInt, 0.03));
+
+    Add(TDBValue(DB_FixedLoanRate, 0.06));
+
+    Add(TDBValue(DB_GuarRegLoanSpread, 0.0));
+    Add(TDBValue(DB_CurrRegLoanSpread, 0.0));
+    Add(TDBValue(DB_GuarPrefLoanSpread, 0.0));
+    Add(TDBValue(DB_CurrPrefLoanSpread, 0.0));
+
+    Add(TDBValue(DB_AllowGenAcct, 1.0));
+    Add(TDBValue(DB_AllowPreferredClass, 1.0));
+
+    // premium loads
+
+    Add(TDBValue(DB_GuarPolFee, 12.00));
+    Add(TDBValue(DB_GuarSpecAmtLoad, 0.0));
+    Add(TDBValue(DB_GuarPremLoadTgt, 0.025));
+    Add(TDBValue(DB_GuarPremLoadExc, 0.025));
+    Add(TDBValue(DB_CurrPolFee, 5.00));
+    Add(TDBValue(DB_CurrSpecAmtLoad, 0.0));
+    Add(TDBValue(DB_CurrPremLoadTgt, 0.025));
+    Add(TDBValue(DB_CurrPremLoadExc, 0.025));
+
+    Add(TDBValue(DB_MinWD, 100.0));
+    Add(TDBValue(DB_WDFee, 5.0));
+    Add(TDBValue(DB_WDFeeRate, 0.01));
+
+    int guar_coi_dims[TDBValue::e_number_of_axes] = {1, 1, 3, 1, 1, 1, 1};
+    // smoker, nonsmoker, unismoke
+    double guar_coi_tables[3] = {111, 109, 107};
+    Add(TDBValue(DB_GuarCOITable, TDBValue::e_number_of_axes, guar_coi_dims, 
guar_coi_tables));
+
+    int curr_coi_dims[TDBValue::e_number_of_axes] = {1, 4, 3, 1, 1, 1, 1};
+    // preferred, standard, rated, ultrapreferred by smoker, nonsmoker, 
unismoke
+    double curr_coi_tables[] =
+        {
+        2, 3, 1, // pref  sm ns us
+        5, 6, 4, // std   sm ns us
+        5, 6, 4, // rated sm ns us
+        0, 0, 0, // ultra sm ns us
+        };
+    Add(TDBValue(DB_CurrCOITable, TDBValue::e_number_of_axes, curr_coi_dims, 
curr_coi_tables));
+
+    Add(TDBValue(DB_CorridorTable, 7));
+    Add(TDBValue(DB_WPTable, 8));
+    Add(TDBValue(DB_ADDTable, 9));
+    Add(TDBValue(DB_EndtAge, 100));
+    Add(TDBValue(DB_AgeLastOrNearest, 1.0));
+    Add(TDBValue(DB_MinSpecAmt, 10000.0));
+
+    Add(TDBValue(DB_MaxGenAcctRate, 0.12));
+    Add(TDBValue(DB_MaxSepAcctRate, 0.12));
+
+    Add(TDBValue(DB_AllowLoan, 1.0));
+    Add(TDBValue(DB_AllowWD, 1.0));
+    Add(TDBValue(DB_AllowFlatExtras, 1.0));
+    Add(TDBValue(DB_AllowChangeToDBO2, 1.0));
+    Add(TDBValue(DB_AllowDBO3, 1.0));
+
+    Add(TDBValue(DB_SurrChgPremMult, 0.0));
+    Add(TDBValue(DB_SurrChgAVMult, 0.0));
+    Add(TDBValue(DB_SurrChgSAMult, 0.0));
+    Add(TDBValue(DB_SurrChgAVDurFactor, 1.0));
+    Add(TDBValue(DB_SurrChgSADurFactor, 1.0));
+
+    Add(TDBValue(DB_LedgerType, mce_ill_reg));
+
+    Add(TDBValue(DB_NoLapseAlwaysActive, 0.0));
+    Add(TDBValue(DB_NoLapseMinDur, 0.0));
+    Add(TDBValue(DB_NoLapseMinAge, 0.0));
+
+    Add(TDBValue(DB_NominallyPar, 0.0));
+    Add(TDBValue(DB_Has1035ExchCharge, 0.0));
+    Add(TDBValue(DB_SmokeOrTobacco, 0.0));
+    Add(TDBValue(DB_DACTaxFundCharge, 0.0));
+    Add(TDBValue(DB_AllowWP, 0.0));
+    Add(TDBValue(DB_AllowADD, 0.0));
+    Add(TDBValue(DB_AllowSpouse, 0.0));
+    Add(TDBValue(DB_AllowChild, 0.0));
+
+    Add(TDBValue(DB_ExpRatAmortPeriod, 4.0));
+}
+
+//============================================================================
+void print_databases()
+{
+    fs::path path(global_settings::instance().data_directory());
+    fs::directory_iterator i(path);
+    fs::directory_iterator end_i;
+    for(; i != end_i; ++i)
+        {
+        if(is_directory(*i) || ".database" != fs::extension(*i))
+            {
+            continue;
+            }
+
+        DBDictionary::instance().Init(i->string());
+        fs::path out_file = fs::change_extension(*i, ".dbt");
+        fs::ofstream os(out_file, ios_out_trunc_binary());
+        dict_map const& dictionary = DBDictionary::instance().GetDictionary();
+        // std::ostream_iterator not used because it doesn't work
+        // nicely with std::map (a name-lookup issue).
+        typedef dict_map::const_iterator dmci;
+        for(dmci i = dictionary.begin(); i != dictionary.end(); ++i)
+            {
+            i->second.write(os);
+            }
+        }
+}
+

Deleted: lmi/trunk/ihs_dbdict.cpp
===================================================================
--- lmi/trunk/ihs_dbdict.cpp    2010-05-02 15:23:37 UTC (rev 4893)
+++ lmi/trunk/ihs_dbdict.cpp    2010-05-02 17:06:17 UTC (rev 4894)
@@ -1,806 +0,0 @@
-// Product-database map.
-//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 
2008, 2009, 2010 Gregory W. Chicares.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-//
-// http://savannah.nongnu.org/projects/lmi
-// email: <address@hidden>
-// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
-
-// $Id$
-
-#ifdef __BORLANDC__
-#   include "pchfile.hpp"
-#   pragma hdrstop
-#endif // __BORLANDC__
-
-#include "dbdict.hpp"
-
-#include "alert.hpp"
-#include "data_directory.hpp"
-#include "dbnames.hpp"
-#include "global_settings.hpp"
-#include "mc_enum_type_enums.hpp"
-#include "miscellany.hpp"
-#include "oecumenic_enumerations.hpp"
-#include "xml_lmi.hpp"
-#include "xml_serialize.hpp"
-
-#include <boost/filesystem/convenience.hpp>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-
-#include <limits>
-#include <sstream>
-
-std::string DBDictionary::CachedFilename;
-
-int const NumberOfEntries = DB_LAST;
-
-//============================================================================
-DBDictionary& DBDictionary::instance()
-{
-    static DBDictionary z;
-    return z;
-}
-
-//============================================================================
-DBDictionary::DBDictionary()
-{
-}
-
-//============================================================================
-DBDictionary::~DBDictionary()
-{
-}
-
-namespace xml_serialize
-{
-template<> struct xml_io<TDBValue>
-{
-    typedef TDBValue T;
-    static void   to_xml(xml::element& e, T const& t) {t.write(e);}
-    static void from_xml(xml::element const& e, T& t) {t.read (e);}
-};
-
-/// Specialize xml_io<> for dict_map rather than coding a generic
-/// xml_io<std::map>, because the key would be stored redundantly:
-/// it's already part of TDBValue.
-
-template<> struct xml_io<dict_map>
-{
-    static void to_xml(xml::element& e, dict_map const& t)
-    {
-        e.erase(e.begin(), e.end());
-        typedef dict_map::const_iterator tci;
-        for(tci i = t.begin(); i != t.end(); ++i)
-            {
-            // This is not equivalent to calling set_element():
-            // multiple <item> elements are expressly permitted.
-            xml::element z("item");
-            xml_serialize::to_xml(z, i->second);
-            e.push_back(z);
-            }
-    }
-
-    static void from_xml(xml::element const& e, dict_map& t)
-    {
-        t.clear();
-        xml::const_nodes_view const items(e.elements("item"));
-        typedef xml::const_nodes_view::const_iterator cnvi;
-        for(cnvi i = items.begin(); i != items.end(); ++i)
-            {
-            TDBValue z;
-            xml_serialize::from_xml(*i, z);
-            t[z.GetKey()] = z;
-            }
-    }
-};
-} // namespace xml_serialize
-
-namespace
-{
-std::string xml_root_name()
-{
-    return "database";
-}
-} // Unnamed namespace.
-
-dict_map const& DBDictionary::GetDictionary() const
-{
-    return dictionary_;
-}
-
-//============================================================================
-void DBDictionary::Init(std::string const& NewFilename)
-{
-    // Perform the expensive operation of reading the dictionary from
-    // file only if the cached file name doesn't match the new file
-    // name, or if the cached file name is an empty string--which
-    // means either that no dictionary has yet been read, or that the
-    // cached file name was deliberately set to an empty string in
-    // order to invalidate the cached database.
-    //
-    // TODO ?? We ought to address the problem that someone might have
-    // modified that file in the meantime.
-
-    if
-        (
-           ""          != CachedFilename
-        && NewFilename == CachedFilename
-        )
-        {
-        return;
-        }
-
-    CachedFilename = NewFilename;
-
-    if(access(NewFilename.c_str(), R_OK))
-        {
-        BadFile(NewFilename, "could not be found."); // dubious
-        fatal_error()
-            << "File '"
-            << NewFilename
-            << "' is required but could not be found. Try reinstalling."
-            << LMI_FLUSH
-            ;
-        }
-
-    xml_lmi::dom_parser parser(NewFilename);
-    xml::element const& root = parser.root_node(xml_root_name());
-
-    xml_serialize::from_xml(root, dictionary_);
-
-    if(NumberOfEntries != static_cast<int>(dictionary_.size()))
-        {
-        std::ostringstream oss;
-        oss
-            << "is not up to date or is corrupted."
-            << " It should contain " << NumberOfEntries
-            << " elements, but it actually contains " << dictionary_.size()
-            << " elements."
-            ;
-        BadFile(NewFilename, oss.str());
-        }
-}
-
-//============================================================================
-void DBDictionary::InvalidateCache()
-{
-    CachedFilename = "";
-}
-
-//============================================================================
-// TODO ?? Does this function make the code clearer, or less clear?
-void DBDictionary::BadFile(std::string const& Filename, std::string const& why)
-{
-    InvalidateCache();
-
-    std::string s = ", which is required for the product selected, ";
-    s += why;
-    s += " Try reinstalling. Other products might work in the meantime.";
-
-    // It's generally pointless to proceed.
-    if(global_settings::instance().mellon())
-        {
-        hobsons_choice() << "File '" << Filename << "'" << s << LMI_FLUSH;
-        }
-    else
-        {
-        fatal_error() << "File '" << Filename << "'" << s << LMI_FLUSH;
-        }
-}
-
-//============================================================================
-void DBDictionary::WriteDB(std::string const& filename)
-{
-    if(NumberOfEntries != static_cast<int>(dictionary_.size()))
-        {
-        fatal_error()
-            << "Error writing database '"
-            << filename
-            << "': the database has " << dictionary_.size()
-            << " entries, but should have " << NumberOfEntries << '.'
-            ;
-        for(int j = 0; j < NumberOfEntries; j++)
-            {
-            if(!dictionary_.count(j))
-                {
-                fatal_error() << " Key " << j << " not found.";
-                }
-            }
-        fatal_error() << LMI_FLUSH;
-        }
-
-    xml_lmi::xml_document document(xml_root_name());
-    xml::element& root = document.root_node();
-
-    xml_lmi::set_attr(root, "version", "0");
-    xml_serialize::to_xml(root, dictionary_);
-
-    // Instead of this:
-//    document.save(filename);
-    // for the nonce, explicitly change the extension, in order to
-    // force external product-file code to use the new extension.
-    fs::path path(filename, fs::native);
-    path = fs::change_extension(path, ".database");
-    document.save(path.string());
-}
-
-//===========================================================================
-void DBDictionary::Add(TDBValue const& e)
-{
-    dictionary_.erase(e.GetKey());
-    dictionary_.insert(dict_map_val(e.GetKey(), e));
-}
-
-//============================================================================
-// Initialize all database entities to not-necessarily-plausible values.
-void DBDictionary::InitDB()
-{
-    static double const bignum = std::numeric_limits<double>::max();
-
-    dictionary_.clear();
-    for(int j = DB_FIRST; j < DB_LAST; ++j)
-        {
-        Add(TDBValue(j, 0.0));
-        }
-
-    // It would be dangerous to set these to zero.
-    Add(TDBValue(DB_CCOIMultiplier      , 1.0));
-    Add(TDBValue(DB_GCOIMultiplier      , 1.0));
-    Add(TDBValue(DB_SubstdTblMult       , 1.0));
-    Add(TDBValue(DB_SurrChgSADurFactor  , 1.0));
-    Add(TDBValue(DB_SurrChgAVDurFactor  , 1.0));
-
-    // Usually the maximum is a reciprocal, e.g., 1/11 or 1/12; for
-    // greatest precision, store the reciprocal of that reciprocal,
-    // e.g., 11 or 12.
-    Add(TDBValue(DB_MaxMonthlyCoiRate   , 12.0));
-
-    Add(TDBValue(DB_GuarIntSpread       , bignum));
-
-    Add(TDBValue(DB_CurrCOITable0Limit  , bignum));
-    Add(TDBValue(DB_CurrCOITable1       , 999));
-    Add(TDBValue(DB_CurrCOITable1Limit  , bignum));
-    Add(TDBValue(DB_CurrCOITable2       , 999));
-
-    Add(TDBValue(DB_SpecAmtLoadLimit    , bignum));
-    Add(TDBValue(DB_DynSepAcctLoadLimit , bignum));
-    Add(TDBValue(DB_ADDLimit            , bignum));
-    Add(TDBValue(DB_ExpPerKLimit        , bignum));
-
-    // SD Chapter 260 (HB 1200), signed 2008-02-19, amended 58-6-70
-    // by removing the former million-dollar threshold.
-    //
-    // TODO ?? For now, only the threshold here is changed. Much
-    // complex code elsewhere can be removed when time permits.
-
-    int premium_tax_dimensions[TDBValue::e_number_of_axes] = {1, 1, 1, 1, 1, 
53, 1};
-    double premium_tax_retaliation_threshold[53] =
-        {
-    //  AL      AK      AZ      AR      CA      CO      CT
-        bignum, 0.0   , bignum, bignum, bignum, bignum, bignum,
-    //  DE      DC      FL      GA      HI      ID
-        bignum, bignum, bignum, bignum, bignum, bignum,
-    //  IL      IN      IA      KS      KY      LA      ME
-        bignum, bignum, bignum, bignum, bignum, bignum, bignum,
-    //  MD      MA      MI      MN      MS      MO
-        bignum, bignum, bignum, bignum, bignum, bignum,
-    //  MT      NE      NV      NH      NJ      NM      NY
-        bignum, bignum, bignum, bignum, bignum, bignum, bignum,
-    //  NC      ND      OH      OK      OR      PA
-        bignum, bignum, bignum, bignum, bignum, bignum,
-    //  PR      RI      SC      SD      TN      TX      UT
-        bignum, bignum, bignum, 0.0   , bignum, bignum, bignum,
-    //  VT      VA      WA      WV      WI      WY      XX
-        bignum, bignum, bignum, bignum, bignum, bignum, 0.0   ,
-        };
-    Add
-        (TDBValue
-            (DB_PremTaxRetalLimit
-            ,TDBValue::e_number_of_axes
-            ,premium_tax_dimensions
-            ,premium_tax_retaliation_threshold
-            )
-        );
-}
-
-//============================================================================
-void DBDictionary::WriteSampleDBFile()
-{
-    InitDB();
-    Add(TDBValue(DB_GuarPolFee          , 8.00));
-    Add(TDBValue(DB_GuarSpecAmtLoad     , 0.0));
-    Add(TDBValue(DB_GuarIssueFee        , 0.0));
-    Add(TDBValue(DB_GuarFundAdminChg    , 0.0));
-    Add(TDBValue(DB_GuarPremLoadTgt     , 0.07));
-    Add(TDBValue(DB_GuarPremLoadExc     , 0.04));
-    Add(TDBValue(DB_GuarPremLoadTgtRfd  , 0.00));
-    Add(TDBValue(DB_GuarPremLoadExcRfd  , 0.00));
-    Add(TDBValue(DB_GuarAcctValLoadAMD  , 0.0));
-    Add(TDBValue(DB_CurrPolFee          , 5.00));
-    Add(TDBValue(DB_CurrSpecAmtLoad     , 0.0));
-    Add(TDBValue(DB_CurrIssueFee        , 0.0));
-    Add(TDBValue(DB_CurrFundAdminChg    , 0.0));
-    Add(TDBValue(DB_CurrPremLoadTgt     , 0.05));
-    Add(TDBValue(DB_CurrPremLoadExc     , 0.02));
-    Add(TDBValue(DB_CurrPremLoadTgtRfd  , 0.00));
-    Add(TDBValue(DB_CurrPremLoadExcRfd  , 0.00));
-    Add(TDBValue(DB_CurrAcctValLoadAMD  , 0.0));
-    Add(TDBValue(DB_DACTaxPremLoad      , 0.01));
-    Add(TDBValue(DB_FundCharge          , 0.0));
-    Add(TDBValue(DB_PremTaxFundCharge   , 0.0));
-    Add(TDBValue(DB_DACTaxFundCharge    , 0.0));
-    Add(TDBValue(DB_WaivePmTxInt1035    , true));
-    Add(TDBValue(DB_FirstWDYear         , 0.0));
-    Add(TDBValue(DB_MaxWDAVMult         , 1.0));
-    Add(TDBValue(DB_MaxWDDed            , mce_to_next_anniversary));
-    Add(TDBValue(DB_MinWD               , 100.0));
-    Add(TDBValue(DB_WDFee               , 25.0));
-    Add(TDBValue(DB_WDFeeRate           , 0.02));
-    Add(TDBValue(DB_WDCanDecrSADBO1     , true));
-    Add(TDBValue(DB_WDCanDecrSADBO2     , true));
-    Add(TDBValue(DB_WDCanDecrSADBO3     , true));
-    Add(TDBValue(DB_FirstLoanYear       , 0.0));
-    Add(TDBValue(DB_AllowPrefLoan       , false));
-    Add(TDBValue(DB_AllowFixedLoan      , true));
-    Add(TDBValue(DB_FixedLoanRate       , 0.06));
-    Add(TDBValue(DB_AllowVLR            , true));
-    Add(TDBValue(DB_MaxLoanAVMult       , 1.0));
-    Add(TDBValue(DB_MaxLoanDed          , mce_to_next_anniversary));
-    Add(TDBValue(DB_GuarPrefLoanSpread  , 0.0));
-    Add(TDBValue(DB_GuarRegLoanSpread   , 0.04));
-    Add(TDBValue(DB_CurrPrefLoanSpread  , 0.0));
-    Add(TDBValue(DB_CurrRegLoanSpread   , 0.02));
-    Add(TDBValue(DB_GuarInt             , 0.03));
-    Add(TDBValue(DB_NAARDiscount        , 0.00246627));
-    Add(TDBValue(DB_GuarIntSpread       , 0.03));
-    Add(TDBValue(DB_GuarMandE           , 0.009));
-    Add(TDBValue(DB_CurrIntSpread       , 0.01));
-    Add(TDBValue(DB_CurrMandE           , 0.009));
-    Add(TDBValue(DB_BonusInt            , 0.0));
-    Add(TDBValue(DB_IntFloor            , 0.0));
-    Add(TDBValue(DB_SepAcctSpreadMethod , mce_spread_is_effective_annual));
-    Add(TDBValue(DB_DynamicMandE        , false));
-
-    // gender, smoker
-    int dims313[TDBValue::e_number_of_axes] = {3, 1, 3, 1, 1, 1, 1};
-
-    // US 1980 CSO age last; unisex = table D.
-    // Male uses table E, which is correct, as opposed to table F,
-    // which contains a numerical error but was adopted by NAIC.
-    double TgCOI[9] =
-        {
-         39,  37,  35, // female: sm ns us
-         45,  57,  41, // male:   sm ns us
-        111, 109, 107, // unisex: sm ns us
-        };
-
-    // For now at least, just use (a multiple of) guaranteed COI rates
-    // as current.
-    Add(TDBValue(DB_CurrCOITable, TDBValue::e_number_of_axes, dims313, TgCOI));
-    Add(TDBValue(DB_GuarCOITable, TDBValue::e_number_of_axes, dims313, TgCOI));
-
-    Add(TDBValue(DB_COINYMinTable       , 0.0));
-
-    double coimult[9] =
-        {
-        0.40, 0.30, 0.35, // female: sm ns us
-        0.60, 0.50, 0.55, // male:   sm ns us
-        0.50, 0.40, 0.45, // unisex: sm ns us
-        };
-    Add(TDBValue(DB_CCOIMultiplier, TDBValue::e_number_of_axes, dims313, 
coimult));
-
-    Add(TDBValue(DB_UseNYCOIFloor       , 0.0));
-    Add(TDBValue(DB_GuarCOICeiling      , 0.0));
-    Add(TDBValue(DB_COIGuarIsMin        , 0.0));
-    Add(TDBValue(DB_COINonforfIsGuar    , 0.0));
-    Add(TDBValue(DB_CCoiIsAnnual        , true));
-    Add(TDBValue(DB_GCoiIsAnnual        , true));
-    Add(TDBValue(DB_MCoiIsAnnual        , true));
-    Add(TDBValue(DB_AgeLastOrNearest    , 0, "0 = ALB")); // ALB
-    Add(TDBValue(DB_AllowRetirees       , true));
-    Add(TDBValue(DB_MinSpecAmt          , 100000.0));
-    Add(TDBValue(DB_AllowSubstdTable    , true));
-    Add(TDBValue(DB_AllowFlatExtras     , true));
-    Add(TDBValue(DB_MinIssAge           , 15));
-    Add(TDBValue(DB_MaxIssAge           , 70));
-    Add(TDBValue(DB_MinIssSpecAmt       , 0.0));
-    Add(TDBValue(DB_MaxIssSpecAmt       , 0.0));
-    Add(TDBValue(DB_MinRenlBaseSpecAmt  , 50000.0));
-    Add(TDBValue(DB_MinRenlSpecAmt      , 50000.0));
-    Add(TDBValue(DB_MaxRenlSpecAmt      , 0.0));
-    Add(TDBValue(DB_MinSpecAmtIncr      , 0.0));
-    Add(TDBValue(DB_MaxIncrAge          , 99));
-    Add(TDBValue(DB_MinPmt              , 0.0));
-    Add(TDBValue(DB_SmokeOrTobacco      , oe_tobacco_nontobacco));
-    Add(TDBValue(DB_AllowUnisex         , true));
-    Add(TDBValue(DB_AllowSexDistinct    , true));
-    Add(TDBValue(DB_AllowUnismoke       , true));
-    Add(TDBValue(DB_AllowSmokeDistinct  , true));
-    Add(TDBValue(DB_AllowFullUW         , true));
-    Add(TDBValue(DB_AllowSimpUW         , true));
-    Add(TDBValue(DB_AllowGuarUW         , true));
-    Add(TDBValue(DB_AllowMortBlendSex   , true));
-    Add(TDBValue(DB_AllowMortBlendSmoke , true));
-    Add(TDBValue(DB_AllowRatedWP        , true));
-    Add(TDBValue(DB_AllowRatedADD       , true));
-    Add(TDBValue(DB_AllowRatedTerm      , true));
-    Add(TDBValue(DB_Allowable           , true));
-    Add(TDBValue(DB_AllowPreferredClass , true));
-    Add(TDBValue(DB_AllowCVAT           , true));
-    Add(TDBValue(DB_AllowGPT            , true));
-
-    // This is just a sample product, so we make do with plausible
-    // all-male seven-pay premiums, and use GPT corridor factors for
-    // CVAT.
-    Add(TDBValue(DB_CorridorTable       , 7));
-    Add(TDBValue(DB_TAMRA7PayTable      , 10));
-
-    // Following IRS Notice 88-128, use only the male and female
-    // tables with no smoker distinction, and a unisex table where
-    // required by state law.
-    //
-    // US 1980 CSO age last, not smoker distinct. Unisex = table D.
-    // Male uses table E, which is correct, as opposed to table F,
-    // which contains a numerical error but was adopted by NAIC.
-    int dims311[TDBValue::e_number_of_axes] = {3, 1, 1, 1, 1, 1, 1}; // gender
-    double T7702q[9] = {35, 41, 107,}; // Female, male, unisex.
-    Add(TDBValue(DB_IRC7702QTable, TDBValue::e_number_of_axes, dims311, 
T7702q));
-
-    Add(TDBValue(DB_PremLoad7702        , 0.02));
-    Add(TDBValue(DB_AllowDBO1           , true));
-    Add(TDBValue(DB_AllowDBO2           , true));
-    Add(TDBValue(DB_AllowDBO3           , true));
-    Add(TDBValue(DB_OptChgCanIncrSA     , true));
-    Add(TDBValue(DB_OptChgCanDecrSA     , true));
-    Add(TDBValue(DB_NonforfQTable       , 0.0));
-    Add(TDBValue(DB_SurrChgByFormula    , 0.0));
-    Add(TDBValue(DB_SurrChgPeriod       , 0.0));
-    Add(TDBValue(DB_SurrChgZeroDur      , 0.0));
-    Add(TDBValue(DB_SurrChgNLPMult      , 0.0));
-    Add(TDBValue(DB_SurrChgNLPMax       , 0.0));
-    Add(TDBValue(DB_SurrChgEAMax        , 0.0));
-    Add(TDBValue(DB_SurrChgPremMult     , 0.0));
-    Add(TDBValue(DB_SurrChgIsMly        , 0.0));
-
-    // These aren't actual premium tax rates. Actual rates change
-    // often, and depend on the insurer's domicile because of
-    // retaliation. Instead of giving rates that appear to be 'right'
-    // but could be valid only on a certain date in a certain
-    // domicile, we use two percent in every state except AK and SD
-    // because those two states have a tiered premium tax that this
-    // program can handle, and except fictitious state XX, which may
-    // be used where no premium tax applies, as for offshore business.
-    // DE has a tiered premium tax that this program cannot yet
-    // handle, so we punt and use two percent in DE.
-    int premium_tax_dimensions[TDBValue::e_number_of_axes] = {1, 1, 1, 1, 1, 
53, 1};
-    double const tiered = 0.0;
-    double premium_tax_rates[53] =
-        {
-    //  AL      AK      AZ      AR      CA      CO      CT
-        0.0200, tiered, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
-    //  DE      DC      FL      GA      HI      ID
-        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
-    //  IL      IN      IA      KS      KY      LA      ME
-        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
-    //  MD      MA      MI      MN      MS      MO
-        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
-    //  MT      NE      NV      NH      NJ      NM      NY
-        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
-    //  NC      ND      OH      OK      OR      PA
-        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200,
-    //  PR      RI      SC      SD      TN      TX      UT
-        0.0200, 0.0200, 0.0200, tiered, 0.0200, 0.0200, 0.0200,
-    //  VT      VA      WA      WV      WI      WY      XX
-        0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0200, 0.0000,
-        };
-    Add
-        (TDBValue
-            (DB_PremTaxRate
-            ,TDBValue::e_number_of_axes
-            ,premium_tax_dimensions
-            ,premium_tax_rates
-            )
-        );
-
-    Add(TDBValue(DB_PremTaxState        , oe_ee_state));
-    Add(TDBValue(DB_EndtAge             , 100));
-    Add(TDBValue(DB_AllowExtEndt        , true));
-    Add(TDBValue(DB_AllowGenAcct        , true));
-    Add(TDBValue(DB_AllowSepAcct        , true));
-    Add(TDBValue(DB_MinPremType         , oe_monthly_deduction));
-    Add(TDBValue(DB_TgtPremType         , oe_modal_nonmec));
-    Add(TDBValue(DB_TgtPmFixedAtIssue   , false));
-    Add(TDBValue(DB_TgtPmIgnoreSubstd   , true));
-    Add(TDBValue(DB_NoLapseMinDur       , 0.0));
-    Add(TDBValue(DB_NoLapseMinAge       , 0.0));
-    Add(TDBValue(DB_NoLapseUnratedOnly  , false));
-    Add(TDBValue(DB_NoLapseOpt1Only     , false));
-    Add(TDBValue(DB_PremRefund          , 0.0));
-    // Reuse current COI rates as current and guaranteed term rates.
-    Add(TDBValue(DB_TermTable, TDBValue::e_number_of_axes, dims313, TgCOI));
-    Add(TDBValue(DB_GuarTermTable, TDBValue::e_number_of_axes, dims313, 
TgCOI));
-    Add(TDBValue(DB_AllowTerm           , true));
-    Add(TDBValue(DB_TermMinIssAge       , 0.0));
-    Add(TDBValue(DB_TermMaxIssAge       , 0.0));
-    Add(TDBValue(DB_TermForcedConvAge   , 0.0));
-    Add(TDBValue(DB_MaxTermProportion   , 0.0));
-    Add(TDBValue(DB_TermCOIRate         , 0.0));
-    Add(TDBValue(DB_TermPremRate        , 0.0));
-    Add(TDBValue(DB_WPTable             , 8));
-    Add(TDBValue(DB_AllowWP             , true));
-    Add(TDBValue(DB_WPMinIssAge         , 0.0));
-    Add(TDBValue(DB_WPMaxIssAge         , 0.0));
-    Add(TDBValue(DB_WPMax               , 0.0));
-    Add(TDBValue(DB_WPCOIRate           , 0.0));
-    Add(TDBValue(DB_WPPremRate          , 0.0));
-    // SOA qx_ins table 708 is 70-75 US ADB experience.
-    Add(TDBValue(DB_ADDTable            , 708));
-    Add(TDBValue(DB_AllowADD            , true));
-    Add(TDBValue(DB_ADDMinIssAge        , 0.0));
-    Add(TDBValue(DB_ADDMaxIssAge        , 0.0));
-    Add(TDBValue(DB_ADDLimit            , 1000000.0));
-    Add(TDBValue(DB_ADDCOIRate          , 0.0));
-    Add(TDBValue(DB_ADDPremRate         , 0.0));
-    Add(TDBValue(DB_WeightClass         , 0.0));
-    Add(TDBValue(DB_WeightGender        , 0.0));
-    Add(TDBValue(DB_WeightSmoking       , 0.0));
-    Add(TDBValue(DB_WeightAge           , 0.0));
-    Add(TDBValue(DB_WeightSpecAmt       , 0.0));
-    Add(TDBValue(DB_WeightState         , 0.0));
-    Add(TDBValue(DB_FullExpPol          , 0.0));
-    Add(TDBValue(DB_FullExpPrem         , 0.0));
-    Add(TDBValue(DB_FullExpDumpin       , 0.0));
-    Add(TDBValue(DB_FullExpPerK         , 0.0));
-    Add(TDBValue(DB_VarExpPol           , 0.0));
-    Add(TDBValue(DB_VarExpPrem          , 0.0));
-    Add(TDBValue(DB_VarExpDumpin        , 0.0));
-    Add(TDBValue(DB_VarExpPerK          , 0.0));
-    Add(TDBValue(DB_MedicalProportion   , 0.0));
-    Add(TDBValue(DB_UWTestCost          , 0.0));
-    Add(TDBValue(DB_VxBasicQTable       , 0.0));
-    Add(TDBValue(DB_VxDeficQTable       , 0.0));
-    Add(TDBValue(DB_VxTaxQTable         , 0.0));
-    Add(TDBValue(DB_StatVxInt           , 0.0));
-    Add(TDBValue(DB_TaxVxInt            , 0.0));
-    Add(TDBValue(DB_StatVxQ             , 0.0));
-    Add(TDBValue(DB_TaxVxQ              , 0.0));
-    Add(TDBValue(DB_DefVxQ              , 0.0));
-    Add(TDBValue(DB_NonforfQ            , 0.0));
-    Add(TDBValue(DB_CompTarget          , 0.0));
-    Add(TDBValue(DB_CompExcess          , 0.0));
-    Add(TDBValue(DB_CompChargeBack      , 0.0));
-    Add(TDBValue(DB_LapseRate           , 0.0));
-    Add(TDBValue(DB_ReqSurpNAAR         , 0.0));
-    Add(TDBValue(DB_ReqSurpVx           , 0.0));
-    Add(TDBValue(DB_LICFitRate          , 0.0));
-    Add(TDBValue(DB_LicDacTaxRate       , 0.0));
-    Add(TDBValue(DB_GDBVxMethod         , 0.0));
-    Add(TDBValue(DB_PrimaryHurdle       , 0.0));
-    Add(TDBValue(DB_SecondaryHurdle     , 0.0));
-    Add(TDBValue(DB_LedgerType          , mce_ill_reg));
-    Add(TDBValue(DB_AllowExpRating      , false));
-
-    // These aren't really NY Table Y group rates--in fact, they're
-    // US 65-70 male ALB. Though NY Table Y is occasionally
-    // encountered in the group-carveout market, it's not included
-    // in the SOA's databases; for default initialization, a widely-
-    // available table is preferred.
-    //
-    // DATABASE !! Hence, the entity is misnamed; it really means
-    // something like "group proxy rate". However, what's really
-    // wanted is a choice among tables. The same can be said of
-    // 'DB_83GamTable', which really means "partial-mortality table";
-    // this support request:
-    //   http://savannah.nongnu.org/support/?105593
-    // would offer a choice and make that database entity unnecessary.
-    Add(TDBValue(DB_TableYTable         , 358));
-
-    // Use male rates for unisex--1983 GAM seems to have no unisex version.
-    double T83Gam[3] = {825, 826, 826,};
-    Add(TDBValue(DB_83GamTable, TDBValue::e_number_of_axes, dims311, T83Gam, 
"Use male rates for unisex--1983 GAM seems to have no unisex version."));
-
-    Add(TDBValue(DB_AllowWD             , true));
-    Add(TDBValue(DB_AllowLoan           , true));
-    Add(TDBValue(DB_AllowChangeToDBO2   , true));
-    Add(TDBValue(DB_AllowSAIncr         , true));
-    Add(TDBValue(DB_NoLapseAlwaysActive , false));
-    Add(TDBValue(DB_PrefOrSelect        , oe_called_select));
-    Add(TDBValue(DB_ExpRatStdDevMult    , 0.0));
-    Add(TDBValue(DB_ExpRatIBNRMult      , 0.0));
-    Add(TDBValue(DB_ExpRatCOIRetention  , 0.0));
-    Add(TDBValue(DB_StableValFundCharge , 0.0));
-    Add(TDBValue(DB_AmortPmLdFundCharge , 0.0030));
-    Add(TDBValue(DB_AllowAmortPremLoad  , false));
-    Add(TDBValue(DB_PmTxAmortPeriod     , 0));
-    Add(TDBValue(DB_PmTxAmortIntRate    , 0.0));
-    // Pass through premium tax.
-    Add
-        (TDBValue
-            (DB_PremTaxLoad
-            ,TDBValue::e_number_of_axes
-            ,premium_tax_dimensions
-            ,premium_tax_rates
-            )
-        );
-    Add(TDBValue(DB_AllowHoneymoon      , true));
-    // Set target equal to seven-pay premium.
-    Add(TDBValue(DB_TgtPremTable        , 10));
-    Add(TDBValue(DB_TgtPremPolFee       , 0.0));
-    Add(TDBValue(DB_AllowExtraAssetComp , true));
-    Add(TDBValue(DB_AllowExtraPremComp  , true));
-    Add(TDBValue(DB_AssetChargeType     , oe_asset_charge_spread));
-    Add(TDBValue(DB_AllowUltraPrefClass , false));
-    Add(TDBValue(DB_MaxGenAcctRate      , 0.06));
-    Add(TDBValue(DB_MaxSepAcctRate      , 0.12));
-    Add(TDBValue(DB_MaxVLRRate          , 0.18));
-    Add(TDBValue(DB_SurrChgAVMult       , 0.0));
-    Add(TDBValue(DB_IntSpreadFreq       , mce_spread_daily));
-    Add(TDBValue(DB_StateApproved       , true));
-    Add(TDBValue(DB_AllowStateXX        , true));
-    Add(TDBValue(DB_AllowForeign        , true));
-    Add(TDBValue(DB_AllowCustomFund     , false));
-    Add(TDBValue(DB_AllowNo7702         , false));
-    Add(TDBValue(DB_EnforceNAARLimit    , true));
-    Add(TDBValue(DB_DynamicSepAcctLoad  , false));
-    Add(TDBValue(DB_SpecAmtLoadLimit    , 10000000.0));
-    Add(TDBValue(DB_Equiv7702DBO3       , 0));
-    Add(TDBValue(DB_ExpRatRiskCOIMult   , 0));
-    Add(TDBValue(DB_SurrChgSAMult       , 0.0));
-    Add(TDBValue(DB_AllowSpouse         , false));
-    Add(TDBValue(DB_AllowChild          , false));
-
-    // Spouse and child riders unavailable, so it doesn't matter
-    // what table we specify.
-    Add(TDBValue(DB_SpouseRiderTable    , 708));
-    Add(TDBValue(DB_ChildRiderTable     , 708));
-
-    Add(TDBValue(DB_GAIntBonus          , 0.0));
-
-    // Allow experience rating.
-    Add(TDBValue(DB_AllowExpRating      , 1.0));
-    Add(TDBValue(DB_ExpRatIBNRMult      , 6.0));
-    Add(TDBValue(DB_ExpRatAmortPeriod   , 4.0));
-
-    WriteDB(AddDataDir("sample.database"));
-}
-
-/// Initialize the built-in database for the antediluvian branch.
-
-void DBDictionary::InitAntediluvian()
-{
-    dictionary_.clear();
-
-    // Zero is inappropriate for some entities ("DB_CCOIMultiplier",
-    // e.g.), but the antediluvian branch doesn't actually use most
-    // database entities.
-    for(int j = DB_FIRST; j < DB_LAST; ++j)
-        {
-        Add(TDBValue(j, 0.0));
-        }
-
-    Add(TDBValue(DB_GuarInt, 0.03));
-
-    Add(TDBValue(DB_FixedLoanRate, 0.06));
-
-    Add(TDBValue(DB_GuarRegLoanSpread, 0.0));
-    Add(TDBValue(DB_CurrRegLoanSpread, 0.0));
-    Add(TDBValue(DB_GuarPrefLoanSpread, 0.0));
-    Add(TDBValue(DB_CurrPrefLoanSpread, 0.0));
-
-    Add(TDBValue(DB_AllowGenAcct, 1.0));
-    Add(TDBValue(DB_AllowPreferredClass, 1.0));
-
-    // premium loads
-
-    Add(TDBValue(DB_GuarPolFee, 12.00));
-    Add(TDBValue(DB_GuarSpecAmtLoad, 0.0));
-    Add(TDBValue(DB_GuarPremLoadTgt, 0.025));
-    Add(TDBValue(DB_GuarPremLoadExc, 0.025));
-    Add(TDBValue(DB_CurrPolFee, 5.00));
-    Add(TDBValue(DB_CurrSpecAmtLoad, 0.0));
-    Add(TDBValue(DB_CurrPremLoadTgt, 0.025));
-    Add(TDBValue(DB_CurrPremLoadExc, 0.025));
-
-    Add(TDBValue(DB_MinWD, 100.0));
-    Add(TDBValue(DB_WDFee, 5.0));
-    Add(TDBValue(DB_WDFeeRate, 0.01));
-
-    int guar_coi_dims[TDBValue::e_number_of_axes] = {1, 1, 3, 1, 1, 1, 1};
-    // smoker, nonsmoker, unismoke
-    double guar_coi_tables[3] = {111, 109, 107};
-    Add(TDBValue(DB_GuarCOITable, TDBValue::e_number_of_axes, guar_coi_dims, 
guar_coi_tables));
-
-    int curr_coi_dims[TDBValue::e_number_of_axes] = {1, 4, 3, 1, 1, 1, 1};
-    // preferred, standard, rated, ultrapreferred by smoker, nonsmoker, 
unismoke
-    double curr_coi_tables[] =
-        {
-        2, 3, 1, // pref  sm ns us
-        5, 6, 4, // std   sm ns us
-        5, 6, 4, // rated sm ns us
-        0, 0, 0, // ultra sm ns us
-        };
-    Add(TDBValue(DB_CurrCOITable, TDBValue::e_number_of_axes, curr_coi_dims, 
curr_coi_tables));
-
-    Add(TDBValue(DB_CorridorTable, 7));
-    Add(TDBValue(DB_WPTable, 8));
-    Add(TDBValue(DB_ADDTable, 9));
-    Add(TDBValue(DB_EndtAge, 100));
-    Add(TDBValue(DB_AgeLastOrNearest, 1.0));
-    Add(TDBValue(DB_MinSpecAmt, 10000.0));
-
-    Add(TDBValue(DB_MaxGenAcctRate, 0.12));
-    Add(TDBValue(DB_MaxSepAcctRate, 0.12));
-
-    Add(TDBValue(DB_AllowLoan, 1.0));
-    Add(TDBValue(DB_AllowWD, 1.0));
-    Add(TDBValue(DB_AllowFlatExtras, 1.0));
-    Add(TDBValue(DB_AllowChangeToDBO2, 1.0));
-    Add(TDBValue(DB_AllowDBO3, 1.0));
-
-    Add(TDBValue(DB_SurrChgPremMult, 0.0));
-    Add(TDBValue(DB_SurrChgAVMult, 0.0));
-    Add(TDBValue(DB_SurrChgSAMult, 0.0));
-    Add(TDBValue(DB_SurrChgAVDurFactor, 1.0));
-    Add(TDBValue(DB_SurrChgSADurFactor, 1.0));
-
-    Add(TDBValue(DB_LedgerType, mce_ill_reg));
-
-    Add(TDBValue(DB_NoLapseAlwaysActive, 0.0));
-    Add(TDBValue(DB_NoLapseMinDur, 0.0));
-    Add(TDBValue(DB_NoLapseMinAge, 0.0));
-
-    Add(TDBValue(DB_NominallyPar, 0.0));
-    Add(TDBValue(DB_Has1035ExchCharge, 0.0));
-    Add(TDBValue(DB_SmokeOrTobacco, 0.0));
-    Add(TDBValue(DB_DACTaxFundCharge, 0.0));
-    Add(TDBValue(DB_AllowWP, 0.0));
-    Add(TDBValue(DB_AllowADD, 0.0));
-    Add(TDBValue(DB_AllowSpouse, 0.0));
-    Add(TDBValue(DB_AllowChild, 0.0));
-
-    Add(TDBValue(DB_ExpRatAmortPeriod, 4.0));
-}
-
-//============================================================================
-void print_databases()
-{
-    fs::path path(global_settings::instance().data_directory());
-    fs::directory_iterator i(path);
-    fs::directory_iterator end_i;
-    for(; i != end_i; ++i)
-        {
-        if(is_directory(*i) || ".database" != fs::extension(*i))
-            {
-            continue;
-            }
-
-        DBDictionary::instance().Init(i->string());
-        fs::path out_file = fs::change_extension(*i, ".dbt");
-        fs::ofstream os(out_file, ios_out_trunc_binary());
-        dict_map const& dictionary = DBDictionary::instance().GetDictionary();
-        // std::ostream_iterator not used because it doesn't work
-        // nicely with std::map (a name-lookup issue).
-        typedef dict_map::const_iterator dmci;
-        for(dmci i = dictionary.begin(); i != dictionary.end(); ++i)
-            {
-            i->second.write(os);
-            }
-        }
-}
-

Modified: lmi/trunk/objects.make
===================================================================
--- lmi/trunk/objects.make      2010-05-02 15:23:37 UTC (rev 4893)
+++ lmi/trunk/objects.make      2010-05-02 17:06:17 UTC (rev 4894)
@@ -188,6 +188,7 @@
   datum_base.o \
   datum_boolean.o \
   datum_string.o \
+  dbdict.o \
   dbnames.o \
   dbvalue.o \
   death_benefits.o \
@@ -255,7 +256,6 @@
   antediluvian_stubs.o \
   basicvalues.o \
   database.o \
-  dbdict.o \
   mortality_rates.o \
   solve.o \
 
@@ -275,7 +275,6 @@
   ihs_avstrtgy.o \
   ihs_basicval.o \
   ihs_database.o \
-  ihs_dbdict.o \
   ihs_irc7702.o \
   ihs_irc7702a.o \
   ihs_mortal.o \
@@ -376,6 +375,7 @@
   data_directory.o \
   datum_base.o \
   datum_string.o \
+  dbdict.o \
   dbnames.o \
   dbvalue.o \
   death_benefits.o \
@@ -386,7 +386,6 @@
   global_settings.o \
   ihs_basicval.o \
   ihs_database.o \
-  ihs_dbdict.o \
   ihs_mortal.o \
   input.o \
   input_harmonization.o \
@@ -770,13 +769,13 @@
   $(xmlwrapp_objects) \
   data_directory.o \
   datum_base.o \
+  dbdict.o \
   dbnames.o \
   dbvalue.o \
   expm1.o \
   facets.o \
   fund_data.o \
   global_settings.o \
-  ihs_dbdict.o \
   mc_enum.o \
   mc_enum_types.o \
   miscellany.o \





reply via email to

[Prev in Thread] Current Thread [Next in Thread]