lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] valyuta/004 cf9d220: Merge branch 'master' into valy


From: Greg Chicares
Subject: [lmi-commits] [lmi] valyuta/004 cf9d220: Merge branch 'master' into valyuta/002
Date: Fri, 11 Dec 2020 17:02:52 -0500 (EST)

branch: valyuta/004
commit cf9d220d4cbbe36416ae4e6845d6292d6058a419
Merge: a3f1b6f e79b927
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Merge branch 'master' into valyuta/002
---
 .github/workflows/ci.yml                           |  143 ++-
 .gitmodules                                        |   12 +
 GNUmakefile                                        |   13 +
 Makefile.am                                        |    5 +
 Speed_gcc_i686-w64-mingw32                         |    7 +
 Speed_gcc_x86_64-pc-linux-gnu                      |    7 +
 Speed_gcc_x86_64-w64-mingw32                       |    7 +
 alert.cpp                                          |    2 +-
 alert.hpp                                          |   32 +-
 antediluvian_stubs.cpp                             |    6 +
 authenticity.cpp                                   |    2 +-
 authenticity.hpp                                   |    2 +-
 basic_tables.cpp                                   |   14 +-
 basic_tables.hpp                                   |   10 +-
 basic_values.hpp                                   |    2 +
 bcc_ar.cpp                                         |    2 +-
 bcc_cc.cpp                                         |    2 +-
 bcc_ld.cpp                                         |    2 +-
 bcc_rc.cpp                                         |    2 +-
 calendar_date.hpp                                  |   20 +-
 callback.hpp                                       |    4 +-
 catch_exceptions.hpp                               |   36 +-
 ce_product_name.hpp                                |    3 +-
 check_git_setup.sh                                 |    5 +-
 check_script.sh                                    |    2 +-
 configurable_settings.cpp                          |   25 +-
 configurable_settings.hpp                          |    4 +-
 configuration.make                                 |    2 +-
 contains.hpp                                       |    5 +-
 contains_test.cpp                                  |   10 +
 cso_table.hpp                                      |    4 +-
 custom_io_0.hpp                                    |    6 +-
 custom_io_1.hpp                                    |    6 +-
 data_directory.hpp                                 |    2 +-
 database_view.cpp                                  |    4 +-
 db_sort.sed                                        |  675 +++++------
 dbdict.cpp                                         | 1240 ++++++++++++++------
 dbdict.hpp                                         |  846 +++++++------
 dbnames.hpp                                        |  183 ++-
 dbnames.xpp                                        |  175 ++-
 dbvalue.cpp                                        |    2 +-
 dbvalue.hpp                                        |    2 +-
 elapsed_time.cpp                                   |    2 +-
 ellipsis.png                                       |  Bin 0 -> 165 bytes
 emit_ledger.hpp                                    |    2 +-
 facets.hpp                                         |    4 +-
 fenv_lmi.hpp                                       |   18 +-
 file_command.hpp                                   |    2 +-
 finra_notes1.mst                                   |    6 -
 generate_product_files.cpp                         |    3 +
 global_settings.cpp                                |    2 +-
 gpt_view.cpp                                       |    2 +-
 gui_test.sh                                        |    4 -
 gwc/.zshrc                                         |    2 +-
 gwc/allow_perf.sh                                  |    8 +-
 gwc/develop1.txt                                   |   41 +
 gwc/develop2.txt                                   |   26 +-
 install_msw.sh => gwc/install_posix.sh             |  209 +---
 gwc/perf_ln.sh                                     |   60 +
 gwc/perf_static.sh                                 |   94 ++
 gwc/redhat_rebuild.sh                              |    2 +-
 gwc/rh.sh                                          |   13 +-
 hooks/post-checkout                                |    6 +-
 ieee754.hpp                                        |    6 +-
 ihs_acctval.cpp                                    |   11 +-
 ihs_basicval.cpp                                   |    7 +-
 ihs_irc7702a.hpp                                   |    2 +-
 ihs_server7702.hpp                                 |    2 +-
 ill_reg_narr_summary2.mst                          |    8 -
 illustration_view.cpp                              |    2 +-
 illustrator.cpp                                    |    2 +-
 illustrator.hpp                                    |    4 +-
 input_realization.cpp                              |    2 +-
 input_sequence.cpp                                 |    4 +-
 input_sequence_aux.hpp                             |    4 +-
 input_sequence_interval.hpp                        |    2 +-
 install_miscellanea.make                           |   26 +-
 install_msw.sh                                     |   72 +-
 install_wx.sh                                      |   53 +-
 install_wxpdfdoc.sh                                |   67 +-
 ..._libxml2_libxslt.sh => install_xml_libraries.sh |   86 +-
 interpolate_string.hpp                             |    2 +-
 ledger.hpp                                         |    4 +-
 ledger_evaluator.cpp                               |    2 +-
 ledger_invariant.cpp                               |    3 +-
 ledger_invariant.hpp                               |    5 +-
 ledger_invariant_init.cpp                          |   61 +-
 ledger_text_formats.hpp                            |   16 +-
 license.hpp                                        |    8 +-
 lingo.cpp                                          |  687 +++++++++++
 lingo.hpp                                          |   62 +
 lmi.hpp                                            |    2 +-
 lmi_setup_00.sh                                    |    2 +-
 lmi_setup_00c.sh                                   |    1 +
 lmi_setup_01.sh                                    |    1 +
 lmi_setup_01c.sh                                   |    1 +
 lmi_setup_01r.sh                                   |    8 +-
 lmi_setup_02.sh                                    |    1 +
 lmi_setup_02c.sh                                   |    1 +
 lmi_setup_05c.sh                                   |    1 +
 lmi_setup_05r.sh                                   |    1 +
 lmi_setup_07r.sh                                   |    1 +
 lmi_setup_10.sh                                    |    1 +
 lmi_setup_10c.sh                                   |    1 +
 lmi_setup_10r.sh                                   |    1 +
 lmi_setup_11.sh                                    |    1 +
 lmi_setup_20.sh                                    |    2 +
 lmi_setup_21.sh                                    |    1 +
 lmi_setup_24.sh                                    |    1 +
 lmi_setup_24c.sh                                   |    1 +
 lmi_setup_25.sh                                    |    2 +
 lmi_setup_29.sh                                    |    1 +
 lmi_setup_30.sh                                    |    1 +
 lmi_setup_40.sh                                    |    1 +
 lmi_setup_42.sh                                    |    1 +
 lmi_setup_43.sh                                    |    4 +-
 lmi_setup_44.sh                                    |    1 +
 main_cgi.cpp                                       |   14 +-
 main_cli.cpp                                       |   45 +-
 main_common.cpp                                    |    2 +-
 main_common_non_wx.cpp                             |    2 +-
 main_wx.cpp                                        |    2 +-
 main_wx_test.cpp                                   |   22 +
 math_functions.hpp                                 |   20 +-
 math_functions_test.cpp                            |   89 +-
 mc_enum.hpp                                        |    2 +-
 mc_enum_types_aux.hpp                              |   16 +-
 mec_view.cpp                                       |    2 +-
 miscellany.hpp                                     |   14 +-
 msw_common.make                                    |   10 +-
 msw_workarounds.cpp                                |    2 +-
 multidimgrid_safe.hpp                              |    2 +-
 multidimgrid_tools.hpp                             |    2 +-
 mvc_controller.tpp                                 |    4 +-
 my_lingo.cpp                                       |   43 +
 my_prod.cpp                                        |    5 +-
 null_stream.hpp                                    |    4 +-
 numeric_io_cast.hpp                                |    8 +-
 numeric_io_test.cpp                                |    2 +-
 numeric_io_traits.hpp                              |    2 +-
 nychthemeral_test.sh                               |   45 +-
 objects.make                                       |   21 +-
 path_utility.cpp                                   |   27 +-
 path_utility.hpp                                   |   18 +-
 path_utility_test.cpp                              |   59 +
 pdf_command.hpp                                    |    4 +-
 policy_document.cpp                                |   40 +-
 policy_view.xrc                                    |  274 +----
 posix_fhs.make                                     |   13 -
 preferences_model.cpp                              |    3 +-
 premium_tax.cpp                                    |   28 +-
 product_data.cpp                                   |  171 +--
 product_data.hpp                                   |   14 +-
 product_file_test.cpp                              |   24 +-
 progress_meter.hpp                                 |    6 +-
 reg_d_group_narr_summary2.mst                      |    2 +-
 reg_d_indiv_cover_page.mst                         |    2 +-
 report_table.hpp                                   |    4 +-
 round_to.hpp                                       |    2 +-
 rounding_rules.hpp                                 |    4 +-
 safely_dereference_as.hpp                          |    2 +-
 sample.hpp                                         |  439 +++++++
 sequence_editor.png                                |  Bin 0 -> 13947 bytes
 set_toolchain.sh                                   |   40 +-
 sigfpe.hpp                                         |    4 +-
 skeleton.cpp                                       |    5 +-
 so_attributes.hpp                                  |   32 +-
 stratified_charges.hpp                             |   10 +-
 stream_cast.hpp                                    |    6 +-
 system_command.hpp                                 |    4 +-
 test_coding_rules.cpp                              |    7 +-
 test_coding_rules_test.sh                          |   19 +-
 third_party/libxml2                                |    2 +-
 third_party/wx                                     |    1 +
 third_party/wxpdfdoc                               |    1 +
 third_party/xmlwrapp                               |    1 +
 tn_range.hpp                                       |    2 +-
 tn_range.tpp                                       |   19 +-
 tn_range_test.cpp                                  |    2 +-
 tn_range_type_trammels.hpp                         |    2 +-
 tools/pete-2.1.1/Makefile                          |    2 +-
 transume_toolchain.sh                              |   18 +-
 value_cast.hpp                                     |   21 +-
 value_cast_test.cpp                                |   28 +-
 verify_products.hpp                                |    2 +-
 version.hpp                                        |    2 +-
 view_ex.tpp                                        |    2 +-
 workhorse.make                                     |   52 +-
 wx_utility.hpp                                     |    6 +-
 xml_serializable.tpp                               |    8 +-
 xml_serialize.hpp                                  |  158 ++-
 xml_serialize_test.cpp                             |  157 +--
 xml_xslt_wrapp.cpp                                 |   53 -
 xmlwrapp-0.9.0.md5sums                             |   45 -
 194 files changed, 5114 insertions(+), 2402 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8327ec3..c94945e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -12,10 +12,19 @@ on:
 jobs:
   build-msw32-cross:
     runs-on: ubuntu-20.04
-    name: Cross-compile for MSW-32
+    name: ${{ matrix.name }}
+    strategy:
+      matrix:
+        include:
+          - name: Cross-compile for MSW-32
+            triplet: i686-w64-mingw32
+            mingw: true
+          - name: Native Linux build
+            triplet: x86_64-pc-linux-gnu
+            mingw: false
     env:
       LMI_COMPILER: gcc
-      LMI_TRIPLET: i686-w64-mingw32
+      LMI_TRIPLET: ${{ matrix.triplet }}
 
     steps:
       - name: Checkout
@@ -27,45 +36,72 @@ jobs:
         run: |
           sudo dpkg --add-architecture i386
           sudo apt-get update
-          sudo apt-get dist-upgrade -o APT::Immediate-Configure=0 # Avoid 
configuration error later
           sudo apt-get --assume-yes install \
             automake bc bsdmainutils bzip2 curl cvs default-jre \
-            g++-mingw-w64-i686 g++-multilib git jing libarchive-tools \
+            g++-multilib git jing libarchive-tools \
             libtool libxml2-utils libxslt1-dev make patch pkg-config rsync \
-            shellcheck sudo trang unzip wget wine32 xsltproc
+            shellcheck sudo trang unzip wget xsltproc xvfb zsh
+
+          if ${{ matrix.mingw }}
+          then
+            sudo apt-get --assume-yes install \
+              g++-mingw-w64-i686 wine32
+          else
+            sudo apt-get --assume-yes install \
+              libgtk-3-dev
+          fi
 
       - name: Fix up libtool
         run: sudo sed -i'' -e 's/^int _putenv/_CRTIMP int _putenv/' 
/usr/share/libtool/build-aux/ltmain.sh
 
       - name: Set environment variables
         run: |
-          echo "::set-env name=NORMAL_UID::`id --user`"
-          echo "::set-env name=coefficiency::--jobs=`nproc`"
-          gcc_version=$(${LMI_TRIPLET}-${LMI_COMPILER} -dumpversion|tr -d '\r')
-          echo "::set-env name=gcc_version::$gcc_version"
+          echo "NORMAL_UID=`id --user`" >> $GITHUB_ENV
+          echo "coefficiency=--jobs=`nproc`" >> $GITHUB_ENV
+          if ${{ matrix.mingw }}
+          then
+            compiler=${LMI_TRIPLET}-${LMI_COMPILER}
+          else
+            compiler=${LMI_COMPILER}
+          fi
+          gcc_version=$($compiler -dumpversion|tr -d '\r')
+          echo "gcc_version=$gcc_version" >> $GITHUB_ENV
+
+          echo "xml2_sha1=$(git rev-parse HEAD:third_party/libxml2)" >> 
$GITHUB_ENV
+          echo "xmlwrapp_sha1=$(git rev-parse HEAD:third_party/xmlwrapp)" >> 
$GITHUB_ENV
+          echo "xslt_sha1=$(git rev-parse HEAD:third_party/libxslt)" >> 
$GITHUB_ENV
+
+          echo "PATH=$PATH:/opt/lmi/local/${LMI_COMPILER}_${LMI_TRIPLET}/bin" 
>> $GITHUB_ENV
+
+          LD_LIBRARY_PATH=/opt/lmi/local/${LMI_COMPILER}_${LMI_TRIPLET}/lib
+          
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/lmi/${LMI_COMPILER}_${LMI_TRIPLET}/build/ship
+          echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> $GITHUB_ENV
 
       - name: Create lmi directories
-        run: >
-          for d in /opt/lmi /etc/opt/lmi /srv/cache_for_lmi; do
-            sudo mkdir --parents $d;
-            sudo --preserve-env chown $NORMAL_UID $d;
-          done;
+        run: |
+          for d in /opt/lmi /opt/lmi/print /etc/opt/lmi /srv/cache_for_lmi; do
+            sudo mkdir --parents $d
+            sudo --preserve-env chown $NORMAL_UID $d
+          done
           mkdir /srv/cache_for_lmi/downloads
+          mkdir /opt/lmi/gui_test
+          mkdir /opt/lmi/src
 
       - name: Cache downloaded archives
         uses: actions/cache@v2
         with:
-          # Use combined key for files downloaded by both makefiles, even
-          # though this means that we would redownload the same files from the
-          # unchanged makefile if only one of them changes -- but they don't
-          # change often enough to make this a real problem in practice.
+          # Using the hash of the makefile means that we're going to have
+          # false negatives, i.e. re-download the files unnecessarily if the
+          # makefile changes but the MD5 checksums of the files in it do not,
+          # but this is much simpler than extracting those MD5s from it and it
+          # changes rarely enough that this shouldn't be a problem in practice.
           path: /srv/cache_for_lmi/downloads
-          key: downloads-${{ hashFiles('install_miscellanea.make') }}-${{ 
hashFiles('install_libxml2_libxslt.make') }}
+          key: downloads-${{ hashFiles('install_miscellanea.make') }}
 
       - name: Build miscellanea
         run: make $coefficiency --output-sync=recurse -f 
install_miscellanea.make
 
-      - name: Cache libxml2, wxWidgets and wxPdfDoc
+      - name: Cache third-party libraries
         id: cache-local
         uses: actions/cache@v2
         with:
@@ -73,11 +109,11 @@ jobs:
             /opt/lmi/local/${{ env.LMI_COMPILER }}_${{ env.LMI_TRIPLET }}
             /opt/lmi/local/include
             /opt/lmi/local/share
-          key: build-${{ env.LMI_COMPILER }}-${{ env.gcc_version }}-${{ 
env.LMI_TRIPLET }}-${{ hashFiles('install_libxml2_libxslt.sh', 'install_wx.sh', 
'install_wxpdfdoc.sh') }}
+          key: build-${{ env.LMI_COMPILER }}-${{ env.gcc_version }}-${{ 
env.LMI_TRIPLET }}-${{ hashFiles('install_xml_libraries.sh', 'install_wx.sh', 
'install_wxpdfdoc.sh') }}-${{ env.xml2_sha1 }}-${{ env.xmlwrapp_sha1 }}-${{ 
env.xslt_sha1 }}
 
-      - name: Build libxml2
+      - name: Build XML libraries
         if: steps.cache-local.outputs.cache-hit != 'true'
-        run: ./install_libxml2_libxslt.sh
+        run: ./install_xml_libraries.sh
 
       - name: Build wxWidgets
         if: steps.cache-local.outputs.cache-hit != 'true'
@@ -88,7 +124,66 @@ jobs:
         run: ./install_wxpdfdoc.sh
 
       - name: Build lmi
-        run: make $coefficiency --output-sync=recurse install
+        run: make $coefficiency --output-sync=recurse
 
       - name: Build lmi with SO attributes
         run: make $coefficiency --output-sync=recurse build_type=so_test 
USE_SO_ATTRIBUTES=1 all
+
+      - name: Setup lmi for tests
+        run: |
+          cat >/opt/lmi/data/configurable_settings.xml <<EOF
+          <?xml version="1.0"?>
+          <configurable_settings version="2">
+            <calculation_summary_columns/>
+            <census_paste_palimpsestically>1</census_paste_palimpsestically>
+            <cgi_bin_log_filename>cgi_bin.log</cgi_bin_log_filename>
+            <custom_input_0_filename>custom.ini</custom_input_0_filename>
+            <custom_input_1_filename>custom.inix</custom_input_1_filename>
+            <custom_output_0_filename>custom.out0</custom_output_0_filename>
+            <custom_output_1_filename>custom.out1</custom_output_1_filename>
+            
<default_input_filename>/etc/opt/lmi/default.ill</default_input_filename>
+            <libraries_to_preload/>
+            <offer_hobsons_choice>0</offer_hobsons_choice>
+            <print_directory>/opt/lmi/print</print_directory>
+            
<seconds_to_pause_between_printouts>10</seconds_to_pause_between_printouts>
+            <skin_filename>skin.xrc</skin_filename>
+            <spreadsheet_file_extension>.tsv</spreadsheet_file_extension>
+            
<use_builtin_calculation_summary>1</use_builtin_calculation_summary>
+          </configurable_settings>
+          EOF
+
+          # Tests rely on the symlinks set up by this script, so run it.
+          ./check_git_setup.sh
+
+          # Copy a placeholder logo image.
+          cp ./gwc/company_logo.png /opt/lmi/data/
+
+          # Create authentication files.
+          printf '2450449 2472011'                            
>/opt/lmi/data/expiry
+          printf '5fc68a795c9c60da1b32be989efc299a  expiry\n' 
>/opt/lmi/data/validated.md5
+          printf '391daa5cbc54e118c4737446bcb84eea'           
>/opt/lmi/data/passkey
+
+      - name: Install
+        run: make install
+
+      - name: Check concinnity
+        run: make $coefficiency check_concinnity
+
+      - name: Check physical closure
+        run: make $coefficiency check_physical_closure
+
+      - name: Run CLI tests
+        run: make $coefficiency cli_tests
+
+      - name: Run unit tests
+        run: |
+          if [ !${{ matrix.mingw }} ]
+          then
+            # Currently failing tests.
+            exclude_args="excluded_unit_test_targets=path_utility_test"
+          fi
+          make $coefficiency unit_tests $exclude_args
+
+      - name: Run GUI tests
+        if: matrix.mingw
+        run: xvfb-run ./gui_test.sh
diff --git a/.gitmodules b/.gitmodules
index e0378ac..788b9b6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,3 +6,15 @@
        path = third_party/libxslt
        url = https://github.com/let-me-illustrate/libxslt.git
        branch = lmi
+[submodule "third_party/xmlwrapp"]
+       path = third_party/xmlwrapp
+       url = https://github.com/let-me-illustrate/xmlwrapp.git
+       branch = lmi
+[submodule "third_party/wx"]
+       path = third_party/wx
+       url = https://github.com/let-me-illustrate/wx.git
+       branch = lmi
+[submodule "third_party/wxpdfdoc"]
+       path = third_party/wxpdfdoc
+       url = https://github.com/let-me-illustrate/wxpdfdoc.git
+       branch = lmi
diff --git a/GNUmakefile b/GNUmakefile
index e905135..00b7b1b 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -414,6 +414,19 @@ eviscerate: source_clean
        -$(RM) --force --recursive $(prefix)/gcc_x86_64-w64-mingw32
        -$(RM) --force --recursive $(prefix)/gcc_x86_64-pc-linux-gnu
 
+# A simple '$(RM) --force --recursive $(bindir)' would remove the
+# directory as well as its contents. However, if $(bindir) is the
+# current working directory in another terminal, hilarity ensues:
+#   sh: 0: getcwd() failed: No such file or directory
+# While '-delete' is not POSIX, it's supported by GNU coreutils and
+# {Open,Free}BSD. The command might instead have been written thus:
+#   find $(bindir) -type f -print0 | xargs -0 rm -rf
+# but '-print0' isn't POSIX either.
+
+.PHONY: uninstall
+uninstall:
+       -find $(bindir) -type f -delete
+
 
################################################################################
 
 # Custom tools built from source.
diff --git a/Makefile.am b/Makefile.am
index bed9d4c..62b10ea 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -424,6 +424,7 @@ liblmi_la_SOURCES = \
     ihs_mortal.cpp \
     ihs_server7702.cpp \
     irc7702_tables.cpp \
+    lingo.cpp \
     lmi.cpp \
     md5.cpp \
     md5sum.cpp \
@@ -529,6 +530,7 @@ product_files_SOURCES = \
     main_common_non_wx.cpp \
     my_db.cpp \
     my_fund.cpp \
+    my_lingo.cpp \
     my_prod.cpp \
     my_proem.cpp \
     my_rnd.cpp \
@@ -1076,6 +1078,7 @@ test_product_file_SOURCES = \
   facets.cpp \
   fund_data.cpp \
   global_settings.cpp \
+  lingo.cpp \
   lmi.cpp \
   mc_enum.cpp \
   mc_enum_types.cpp \
@@ -1367,6 +1370,7 @@ noinst_HEADERS = \
     ledger_variant.hpp \
     ledgervalues.hpp \
     license.hpp \
+    lingo.hpp \
     lmi.hpp \
     loads.hpp \
     loads_impl.hpp \
@@ -1436,6 +1440,7 @@ noinst_HEADERS = \
     rounding_view_editor.hpp \
     rtti_lmi.hpp \
     safely_dereference_as.hpp \
+    sample.hpp \
     sigfpe.hpp \
     single_cell_document.hpp \
     single_choice_popup_menu.hpp \
diff --git a/Speed_gcc_i686-w64-mingw32 b/Speed_gcc_i686-w64-mingw32
new file mode 100644
index 0000000..a638840
--- /dev/null
+++ b/Speed_gcc_i686-w64-mingw32
@@ -0,0 +1,7 @@
+Test speed:
+  naic, no solve      : 5.390e-02 s mean;      52385 us least of  19 runs
+  naic, specamt solve : 9.371e-02 s mean;      92922 us least of  11 runs
+  naic, ee prem solve : 8.619e-02 s mean;      85534 us least of  12 runs
+  finra, no solve     : 2.242e-02 s mean;      22026 us least of  45 runs
+  finra, specamt solve: 5.979e-02 s mean;      59157 us least of  17 runs
+  finra, ee prem solve: 5.580e-02 s mean;      55186 us least of  18 runs
diff --git a/Speed_gcc_x86_64-pc-linux-gnu b/Speed_gcc_x86_64-pc-linux-gnu
new file mode 100644
index 0000000..34ba62b
--- /dev/null
+++ b/Speed_gcc_x86_64-pc-linux-gnu
@@ -0,0 +1,7 @@
+Test speed:
+  naic, no solve      : 1.934e-02 s mean;      18847 us least of  52 runs
+  naic, specamt solve : 3.334e-02 s mean;      32772 us least of  31 runs
+  naic, ee prem solve : 3.055e-02 s mean;      29841 us least of  33 runs
+  finra, no solve     : 7.784e-03 s mean;       7317 us least of 100 runs
+  finra, specamt solve: 2.056e-02 s mean;      20189 us least of  49 runs
+  finra, ee prem solve: 1.924e-02 s mean;      18760 us least of  52 runs
diff --git a/Speed_gcc_x86_64-w64-mingw32 b/Speed_gcc_x86_64-w64-mingw32
new file mode 100644
index 0000000..dc1c45c
--- /dev/null
+++ b/Speed_gcc_x86_64-w64-mingw32
@@ -0,0 +1,7 @@
+Test speed:
+  naic, no solve      : 2.687e-02 s mean;      26503 us least of  38 runs
+  naic, specamt solve : 4.217e-02 s mean;      41668 us least of  24 runs
+  naic, ee prem solve : 3.923e-02 s mean;      38847 us least of  26 runs
+  finra, no solve     : 1.499e-02 s mean;      14714 us least of  67 runs
+  finra, specamt solve: 2.901e-02 s mean;      28656 us least of  35 runs
+  finra, ee prem solve: 2.745e-02 s mean;      27094 us least of  37 runs
diff --git a/alert.cpp b/alert.cpp
index b1c6469..cab4db6 100644
--- a/alert.cpp
+++ b/alert.cpp
@@ -191,7 +191,7 @@ class alarum_buf
 template<typename T>
 inline std::ostream& alert_stream()
 {
-    static_assert(std::is_base_of<alert_buf,T>::value);
+    static_assert(std::is_base_of_v<alert_buf,T>);
     static T buffer_;
     static std::ostream stream_(&buffer_);
     stream_.clear();
diff --git a/alert.hpp b/alert.hpp
index 9665ce9..8bd0e11 100644
--- a/alert.hpp
+++ b/alert.hpp
@@ -158,15 +158,15 @@
 
 namespace alert_classes{} // doxygen workaround.
 
-std::ostream& LMI_SO status();
-std::ostream& LMI_SO warning();
-std::ostream& LMI_SO hobsons_choice();
-std::ostream& LMI_SO alarum();
+LMI_SO std::ostream& status();
+LMI_SO std::ostream& warning();
+LMI_SO std::ostream& hobsons_choice();
+LMI_SO std::ostream& alarum();
 
-void LMI_SO safely_show_on_stderr(char const*);
+LMI_SO void safely_show_on_stderr(char const*);
 
-void LMI_SO safely_show_message(char const*);
-void LMI_SO safely_show_message(std::string const&);
+LMI_SO void safely_show_message(char const*);
+LMI_SO void safely_show_message(std::string const&);
 
 // Implement these functions for each platform. Any might throw an
 // exception, which normally would be caught by the standard library
@@ -200,7 +200,7 @@ void safe_message_alert   (char const*);
 /// here:
 ///   https://lists.nongnu.org/archive/html/lmi/2005-11/msg00016.html
 
-bool LMI_SO set_alert_functions
+LMI_SO bool set_alert_functions
     (void(*status_alert_function_pointer        )(std::string const&)
     ,void(*warning_alert_function_pointer       )(std::string const&)
     ,void(*hobsons_choice_alert_function_pointer)(std::string const&)
@@ -220,7 +220,7 @@ bool LMI_SO set_alert_functions
 /// stderr and signals an exception. A server application probably
 /// should fail and write a message in a log file.
 
-std::string const& LMI_SO hobsons_prompt();
+LMI_SO std::string const& hobsons_prompt();
 
 /// Rejecting Hobson's Choice throws a distinctive exception. Design
 /// intention: a user interface can catch this and take appropriate
@@ -243,15 +243,15 @@ class hobsons_choice_exception
 /// library to demonstrate that alerts can be raised there and
 /// processed in the main application.
 
-void LMI_SO test_status();
-void LMI_SO test_warning();
-void LMI_SO test_hobsons_choice();
-void LMI_SO test_alarum();
+LMI_SO void test_status();
+LMI_SO void test_warning();
+LMI_SO void test_hobsons_choice();
+LMI_SO void test_alarum();
 [[noreturn]]
-void LMI_SO test_standard_exception();
+LMI_SO void test_standard_exception();
 [[noreturn]]
-void LMI_SO test_arbitrary_exception();
-void LMI_SO test_catastrophe_report();
+LMI_SO void test_arbitrary_exception();
+LMI_SO void test_catastrophe_report();
 
 /// Write file name and line number to diagnostic stream, and flush.
 
diff --git a/antediluvian_stubs.cpp b/antediluvian_stubs.cpp
index c3123a8..236d0c1 100644
--- a/antediluvian_stubs.cpp
+++ b/antediluvian_stubs.cpp
@@ -23,6 +23,7 @@
 
 #include "fund_data.hpp"
 #include "gpt_server.hpp"
+#include "lingo.hpp"
 #include "lmi.hpp"                      // is_antediluvian_fork()
 #include "mec_server.hpp"
 #include "product_data.hpp"
@@ -88,6 +89,11 @@ bool gpt_state::is_detritus(std::string const&) const
     return false;
 }
 
+std::string const& lingo::lookup(int) const
+{
+    return empty_string;
+}
+
 mec_server::mec_server(mcenum_emission)
 {}
 
diff --git a/authenticity.cpp b/authenticity.cpp
index fa2eb7e..cc0cce5 100644
--- a/authenticity.cpp
+++ b/authenticity.cpp
@@ -27,7 +27,7 @@
 #include "calendar_date.hpp"
 #include "contains.hpp"
 #include "global_settings.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "md5.hpp"
 #include "md5sum.hpp"
 #include "path_utility.hpp"             // fs::path inserter
diff --git a/authenticity.hpp b/authenticity.hpp
index 7e2da72..73dfefe 100644
--- a/authenticity.hpp
+++ b/authenticity.hpp
@@ -66,7 +66,7 @@ class Authenticity final
 /// Terminate the program immediately if authentication fails. But
 /// skip authentication altogether for the most-privileged password.
 
-void LMI_SO authenticate_system();
+LMI_SO void authenticate_system();
 
 /// Name of file containing md5sums of secured files.
 
diff --git a/basic_tables.cpp b/basic_tables.cpp
index 810e29f..1c1de91 100644
--- a/basic_tables.cpp
+++ b/basic_tables.cpp
@@ -34,7 +34,7 @@
 
 #if 0 // For debugging only.
 #include "alert.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #endif // 0
 
 #include <string>
@@ -90,7 +90,7 @@ std::vector<double> basic_table_rates
 #endif // 0
 }
 
-std::vector<double> LMI_SO irc_7702_q_builtin
+std::vector<double> irc_7702_q_builtin
     (product_database const& db
     ,int                     issue_age
     ,int                     years_to_maturity
@@ -117,7 +117,7 @@ std::vector<double> LMI_SO irc_7702_q_builtin
 }
 } // Unnamed namespace.
 
-std::vector<double> LMI_SO irc_7702_q
+std::vector<double> irc_7702_q
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
@@ -149,7 +149,7 @@ std::vector<double> LMI_SO irc_7702_q
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
-std::vector<double> LMI_SO irc_7702A_7pp
+std::vector<double> irc_7702A_7pp
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
@@ -177,7 +177,7 @@ std::vector<double> LMI_SO irc_7702A_7pp
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
-std::vector<double> LMI_SO irc_7702_nsp
+std::vector<double> irc_7702_nsp
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
@@ -209,7 +209,7 @@ std::vector<double> LMI_SO irc_7702_nsp
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
-std::vector<double> LMI_SO cvat_corridor_factors
+std::vector<double> cvat_corridor_factors
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
@@ -237,7 +237,7 @@ std::vector<double> LMI_SO cvat_corridor_factors
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
-std::vector<double> LMI_SO target_premium_rates
+std::vector<double> target_premium_rates
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
diff --git a/basic_tables.hpp b/basic_tables.hpp
index 954f29c..a94ef13 100644
--- a/basic_tables.hpp
+++ b/basic_tables.hpp
@@ -31,35 +31,35 @@
 class LMI_SO_FWD_DECL product_data;
 class LMI_SO_FWD_DECL product_database;
 
-std::vector<double> LMI_SO irc_7702_q
+LMI_SO std::vector<double> irc_7702_q
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
     ,int                     years_to_maturity
     );
 
-std::vector<double> LMI_SO irc_7702A_7pp
+LMI_SO std::vector<double> irc_7702A_7pp
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
     ,int                     years_to_maturity
     );
 
-std::vector<double> LMI_SO irc_7702_nsp
+LMI_SO std::vector<double> irc_7702_nsp
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
     ,int                     years_to_maturity
     );
 
-std::vector<double> LMI_SO cvat_corridor_factors
+LMI_SO std::vector<double> cvat_corridor_factors
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
     ,int                     years_to_maturity
     );
 
-std::vector<double> LMI_SO target_premium_rates
+LMI_SO std::vector<double> target_premium_rates
     (product_data     const& product
     ,product_database const& database
     ,int                     issue_age
diff --git a/basic_values.hpp b/basic_values.hpp
index 0e72ed0..aeda9b7 100644
--- a/basic_values.hpp
+++ b/basic_values.hpp
@@ -60,6 +60,7 @@ class Irc7702A;
 class Loads;
 class MortalityRates;
 class death_benefits;
+class lingo;
 class modal_outlay;
 class premium_tax;
 class rounding_rules;
@@ -120,6 +121,7 @@ class LMI_SO BasicValues
     yare_input                          yare_input_;
     product_data     const              product_;
     product_database const              database_;
+    std::shared_ptr<lingo>              lingo_;
     std::shared_ptr<FundData>           FundData_;
     std::shared_ptr<rounding_rules>     RoundingRules_;
     std::shared_ptr<stratified_charges> StratifiedCharges_;
diff --git a/bcc_ar.cpp b/bcc_ar.cpp
index 4bb2fe8..aaaaaca 100644
--- a/bcc_ar.cpp
+++ b/bcc_ar.cpp
@@ -36,7 +36,7 @@
 // any existing library and create a new one from scratch.
 
 #include "getopt.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "license.hpp"
 #include "system_command.hpp"
 
diff --git a/bcc_cc.cpp b/bcc_cc.cpp
index c5d687d..a856f0d 100644
--- a/bcc_cc.cpp
+++ b/bcc_cc.cpp
@@ -20,7 +20,7 @@
 // snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 #include "getopt.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "license.hpp"
 #include "system_command.hpp"
 
diff --git a/bcc_ld.cpp b/bcc_ld.cpp
index 44d4ec3..3b20a96 100644
--- a/bcc_ld.cpp
+++ b/bcc_ld.cpp
@@ -36,7 +36,7 @@
 // in '.o' are objects, and files ending in '.lib' or '.a' are libraries.
 
 #include "getopt.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "license.hpp"
 #include "miscellany.hpp"               // ends_with()
 #include "system_command.hpp"
diff --git a/bcc_rc.cpp b/bcc_rc.cpp
index e8d8a5b..91965c2 100644
--- a/bcc_rc.cpp
+++ b/bcc_rc.cpp
@@ -20,7 +20,7 @@
 // snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 #include "getopt.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "license.hpp"
 #include "system_command.hpp"
 
diff --git a/calendar_date.hpp b/calendar_date.hpp
index d1bb9aa..a236b48 100644
--- a/calendar_date.hpp
+++ b/calendar_date.hpp
@@ -68,8 +68,8 @@ class ymd_t
     int value_;
 };
 
-ymd_t LMI_SO JdnToYmd(jdn_t);
-jdn_t LMI_SO YmdToJdn(ymd_t);
+LMI_SO ymd_t JdnToYmd(jdn_t);
+LMI_SO jdn_t YmdToJdn(ymd_t);
 
 /// Class calendar_date represents a gregorian-calendar date in the
 /// range [1752-09-14, 9999-12-31]. Date calculations are probably
@@ -174,12 +174,12 @@ class LMI_SO calendar_date
     mutable int cached_day_;
 };
 
-calendar_date LMI_SO operator+(int, calendar_date);
-calendar_date LMI_SO operator+(calendar_date, int);
-calendar_date LMI_SO operator-(calendar_date, int);
+LMI_SO calendar_date operator+(int, calendar_date);
+LMI_SO calendar_date operator+(calendar_date, int);
+LMI_SO calendar_date operator-(calendar_date, int);
 
-std::ostream& LMI_SO operator<<(std::ostream&, calendar_date const&);
-std::istream& LMI_SO operator>>(std::istream&, calendar_date&);
+LMI_SO std::ostream& operator<<(std::ostream&, calendar_date const&);
+LMI_SO std::istream& operator>>(std::istream&, calendar_date&);
 
 calendar_date add_years
     (calendar_date const& date
@@ -237,8 +237,8 @@ std::string month_name(int);
 
 // Some particularly useful dates.
 
-calendar_date const& LMI_SO gregorian_epoch();
-calendar_date const& LMI_SO last_yyyy_date();
-calendar_date        LMI_SO today();
+LMI_SO calendar_date const& gregorian_epoch();
+LMI_SO calendar_date const& last_yyyy_date();
+LMI_SO calendar_date        today();
 
 #endif // calendar_date_hpp
diff --git a/callback.hpp b/callback.hpp
index d8f62e0..d13926d 100644
--- a/callback.hpp
+++ b/callback.hpp
@@ -96,9 +96,9 @@
 template<typename FunctionPointer>
 class LMI_SO callback final
 {
-    static_assert(std::is_pointer<FunctionPointer>::value);
+    static_assert(std::is_pointer_v<FunctionPointer>);
     typedef typename std::remove_pointer<FunctionPointer>::type f_type;
-    static_assert(std::is_function<f_type>::value);
+    static_assert(std::is_function_v<f_type>);
 
   public:
     callback() = default;
diff --git a/catch_exceptions.hpp b/catch_exceptions.hpp
index 19c0482..9474ba9 100644
--- a/catch_exceptions.hpp
+++ b/catch_exceptions.hpp
@@ -73,7 +73,7 @@ namespace lmi_test
   namespace detail
   {
     // A separate reporting function was requested during formal review.
-    inline void report_exception
+    inline void herald_exception
         (std::ostream& os
         ,char const*   name
         ,char const*   info
@@ -117,42 +117,42 @@ namespace lmi_test
     // required, but it doesn't hurt and some programmers ask for it.
 
         catch(char const*& e)
-            {detail::report_exception(out, ""                      , e);}
+            {detail::herald_exception(out, ""                      , e);}
         catch(std::string const& e)
-            {detail::report_exception(out, ""                      , 
e.c_str());}
+            {detail::herald_exception(out, ""                      
,e.c_str());}
 
         // std:: exceptions
         catch(std::bad_alloc const& e)
-            {detail::report_exception(out, "std::bad_alloc:"       , 
e.what());}
+            {detail::herald_exception(out, "std::bad_alloc:"       , 
e.what());}
         catch(std::bad_cast const& e)
-            {detail::report_exception(out, "std::bad_cast:"        , 
e.what());}
+            {detail::herald_exception(out, "std::bad_cast:"        , 
e.what());}
         catch(std::bad_typeid const& e)
-            {detail::report_exception(out, "std::bad_typeid:"      , 
e.what());}
+            {detail::herald_exception(out, "std::bad_typeid:"      , 
e.what());}
         catch(std::bad_exception const& e)
-            {detail::report_exception(out, "std::bad_exception:"   , 
e.what());}
+            {detail::herald_exception(out, "std::bad_exception:"   , 
e.what());}
         catch(std::domain_error const& e)
-            {detail::report_exception(out, "std::domain_error:"    , 
e.what());}
+            {detail::herald_exception(out, "std::domain_error:"    , 
e.what());}
         catch(std::invalid_argument const& e)
-            {detail::report_exception(out, "std::invalid_argument:", 
e.what());}
+            {detail::herald_exception(out, "std::invalid_argument:", 
e.what());}
         catch(std::length_error const& e)
-            {detail::report_exception(out, "std::length_error:"    , 
e.what());}
+            {detail::herald_exception(out, "std::length_error:"    , 
e.what());}
         catch(std::out_of_range const& e)
-            {detail::report_exception(out, "std::out_of_range:"    , 
e.what());}
+            {detail::herald_exception(out, "std::out_of_range:"    , 
e.what());}
         catch(std::range_error const& e)
-            {detail::report_exception(out, "std::range_error:"     , 
e.what());}
+            {detail::herald_exception(out, "std::range_error:"     , 
e.what());}
         catch(std::overflow_error const& e)
-            {detail::report_exception(out, "std::overflow_error:"  , 
e.what());}
+            {detail::herald_exception(out, "std::overflow_error:"  , 
e.what());}
         catch(std::underflow_error const& e)
-            {detail::report_exception(out, "std::underflow_error:" , 
e.what());}
+            {detail::herald_exception(out, "std::underflow_error:" , 
e.what());}
         catch(std::logic_error const& e)
-            {detail::report_exception(out, "std::logic_error:"     , 
e.what());}
+            {detail::herald_exception(out, "std::logic_error:"     , 
e.what());}
         catch(std::runtime_error const& e)
-            {detail::report_exception(out, "std::runtime_error:"   , 
e.what());}
+            {detail::herald_exception(out, "std::runtime_error:"   , 
e.what());}
         catch(std::exception const& e)
-            {detail::report_exception(out, "std::exception:"       , 
e.what());}
+            {detail::herald_exception(out, "std::exception:"       , 
e.what());}
 
         catch(...)
-            {detail::report_exception(out, "unknown exception"     , "");}
+            {detail::herald_exception(out, "unknown exception"     , "");}
 
         if(exception_thrown) result = lmi_test::exit_exception_failure;
 
diff --git a/ce_product_name.hpp b/ce_product_name.hpp
index 708c561..165f515 100644
--- a/ce_product_name.hpp
+++ b/ce_product_name.hpp
@@ -25,6 +25,7 @@
 #include "config.hpp"
 
 #include "mc_enum.hpp"
+#include "so_attributes.hpp"
 
 #include <iosfwd>
 #include <string>
@@ -51,7 +52,7 @@
 /// possible without adjusting the base class's 'allowed_' vector and
 /// perhaps changing the way ordinal() works?
 
-class ce_product_name
+class LMI_SO ce_product_name
     :public mc_enum_base
 {
   public:
diff --git a/check_git_setup.sh b/check_git_setup.sh
index f8d3873..5262e85 100755
--- a/check_git_setup.sh
+++ b/check_git_setup.sh
@@ -24,7 +24,8 @@
 # Navigate to the directory where this script resides, and make sure
 # it's a git "toplevel" directory.
 
-cd "$(dirname "$(readlink -f "$0")")" || printf 'Cannot cd\n'
+srcdir=$(dirname "$(readlink --canonicalize "$0")")
+cd "$srcdir" || printf 'Cannot cd\n'
 toplevel=$(git rev-parse --show-toplevel)
 printf '"%s" is current directory\n' "$PWD"
 printf '"%s" is git toplevel directory\n' "$toplevel"
@@ -35,7 +36,7 @@ printf '"%s" is git toplevel directory\n' "$toplevel"
 # 'core.filemode' is "false". See:
 #   https://lists.nongnu.org/archive/html/lmi/2017-11/msg00018.html
 
-lmi_build_type=$(/usr/share/libtool/build-aux/config.guess)
+lmi_build_type=$(/usr/share/misc/config.guess)
 case "$lmi_build_type" in
   (*-*-cygwin*)
     printf 'cygwin detected\n'
diff --git a/check_script.sh b/check_script.sh
index ee2797b..72ec429 100755
--- a/check_script.sh
+++ b/check_script.sh
@@ -23,7 +23,7 @@
 
 # Do nothing for cygwin, which has no 'shellcheck' package.
 
-lmi_build_type=$(/usr/share/libtool/build-aux/config.guess)
+lmi_build_type=$(/usr/share/misc/config.guess)
 case "$lmi_build_type" in
   (*-*-cygwin*) exit 0 ;;
 esac
diff --git a/configurable_settings.cpp b/configurable_settings.cpp
index f01a3be..2f0238b 100644
--- a/configurable_settings.cpp
+++ b/configurable_settings.cpp
@@ -27,7 +27,7 @@
 #include "alert.hpp"
 #include "contains.hpp"
 #include "data_directory.hpp"           // AddDataDir()
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "map_lookup.hpp"
 #include "mc_enum.hpp"                  // all_strings<>()
 #include "mc_enum_type_enums.hpp"       // mcenum_report_column
@@ -146,19 +146,34 @@ configurable_settings::configurable_settings()
     ascribe_members();
     load();
 
-    default_input_filename_ = 
fs::system_complete(default_input_filename_).string();
-    print_directory_        = fs::system_complete(print_directory_       
).string();
+    try
+        {
+        default_input_filename_ = 
fs::system_complete(default_input_filename_).string();
+// Performing this test seems like a good idea, but it would flag
+// an empty path as an error.
+//      validate_filepath(default_input_filename_, "Default input file");
+        }
+    catch(...)
+        {
+        report_exception();
+        // Silently replace invalid path with an empty string,
+        // which will produce an informative diagnostic when
+        // a default is needed.
+        default_input_filename_ = {};
+        }
 
     try
         {
+        print_directory_ = remove_alien_msw_root(print_directory_).string();
+        print_directory_ = fs::system_complete(print_directory_).string();
         validate_directory(print_directory_, "Print directory");
         }
     catch(...)
         {
         report_exception();
-        print_directory_ = fs::system_complete(".").string();
+        print_directory_ = fs::system_complete(AddDataDir(".")).string();
         warning()
-            << "If possible, current directory '"
+            << "If possible, data directory '"
             << print_directory_
             << "' will be used for print files instead."
             << LMI_FLUSH
diff --git a/configurable_settings.hpp b/configurable_settings.hpp
index f8eac12..a1f1b0e 100644
--- a/configurable_settings.hpp
+++ b/configurable_settings.hpp
@@ -110,10 +110,10 @@ class LMI_SO configurable_settings final
     bool        use_builtin_calculation_summary_;
 };
 
-std::string const& LMI_SO configuration_filepath();
+LMI_SO std::string const&       configuration_filepath();
 
 std::vector<std::string>        input_calculation_summary_columns();
 // This function must be visible to 'wx_test_calculation_summary.cpp'.
-std::vector<std::string> LMI_SO effective_calculation_summary_columns();
+LMI_SO std::vector<std::string> effective_calculation_summary_columns();
 
 #endif // configurable_settings_hpp
diff --git a/configuration.make b/configuration.make
index dd76c29..b4f92d1 100644
--- a/configuration.make
+++ b/configuration.make
@@ -23,7 +23,7 @@
 
 # Include platform-specific makefile.
 
-lmi_build_type := $(shell /usr/share/libtool/build-aux/config.guess)
+lmi_build_type := $(shell /usr/share/misc/config.guess)
 
 ifeq (msys,$(findstring msys,$(lmi_build_type)))
   platform_makefile := msw_msys.make
diff --git a/contains.hpp b/contains.hpp
index ca4aba0..9ac6d3d 100644
--- a/contains.hpp
+++ b/contains.hpp
@@ -56,6 +56,9 @@ struct has_member_find
     static bool const value = sizeof(yea_t) == sizeof 
deduce(static_cast<Derived*>(nullptr));
 };
 
+template<typename T>
+inline constexpr bool has_member_find_v = has_member_find<T>::value;
+
 /// Ascertain whether a "container" includes a given element.
 ///
 /// Here, std::basic_string is considered a "container", this:
@@ -69,7 +72,7 @@ template<typename T>
 bool contains
     (T const& t
     ,typename T::value_type const& element
-    ,typename std::enable_if<!has_member_find<T>::value>::type* = nullptr
+    ,typename std::enable_if<!has_member_find_v<T>>::type* = nullptr
     )
 {
     return t.end() != std::find(t.begin(), t.end(), element);
diff --git a/contains_test.cpp b/contains_test.cpp
index 5294c70..d1af4cf 100644
--- a/contains_test.cpp
+++ b/contains_test.cpp
@@ -46,6 +46,16 @@ void test_has_member_find()
     static_assert( has_member_find<std::map   <int,int>>::value);
     static_assert( has_member_find<std::set   <int    >>::value);
     static_assert(!has_member_find<std::vector<int    >>::value);
+
+    // same, with has_member_find_v
+    static_assert( has_member_find_v<HasFind  >);
+    static_assert(!has_member_find_v<LacksFind>);
+
+    static_assert( has_member_find_v<std::string>);
+
+    static_assert( has_member_find_v<std::map   <int,int>>);
+    static_assert( has_member_find_v<std::set   <int    >>);
+    static_assert(!has_member_find_v<std::vector<int    >>);
 }
 
 /// Test standard "containers" for which find() makes sense.
diff --git a/cso_table.hpp b/cso_table.hpp
index 4b21d8b..074e6d5 100644
--- a/cso_table.hpp
+++ b/cso_table.hpp
@@ -30,7 +30,7 @@
 
 #include <vector>
 
-std::vector<double> LMI_SO cso_table
+LMI_SO std::vector<double> cso_table
     (mcenum_cso_era
     ,oenum_autopisty
     ,oenum_alb_or_anb
@@ -40,7 +40,7 @@ std::vector<double> LMI_SO cso_table
     ,int              max_age
     );
 
-std::vector<double> LMI_SO cso_table
+LMI_SO std::vector<double> cso_table
     (mcenum_cso_era
     ,oenum_autopisty
     ,oenum_alb_or_anb
diff --git a/custom_io_0.hpp b/custom_io_0.hpp
index 5cc6b92..a5bfe0d 100644
--- a/custom_io_0.hpp
+++ b/custom_io_0.hpp
@@ -31,7 +31,7 @@
 class Input;
 class Ledger;
 
-bool LMI_SO custom_io_0_file_exists();
+LMI_SO bool custom_io_0_file_exists();
 
 // These two functions take std::string arguments that either contain
 // filenames or are blank. If they're blank, as they normally are,
@@ -43,7 +43,7 @@ bool LMI_SO custom_io_0_file_exists();
 // that input and output files share a common stem; in this custom
 // situation, that need not be the case.
 
-bool LMI_SO custom_io_0_read (Input&       , std::string const& filename);
-void LMI_SO custom_io_0_write(Ledger const&, std::string const& filename);
+LMI_SO bool custom_io_0_read (Input&       , std::string const& filename);
+LMI_SO void custom_io_0_write(Ledger const&, std::string const& filename);
 
 #endif // custom_io_0_hpp
diff --git a/custom_io_1.hpp b/custom_io_1.hpp
index 75a5da9..5f30130 100644
--- a/custom_io_1.hpp
+++ b/custom_io_1.hpp
@@ -31,7 +31,7 @@
 class Input;
 class Ledger;
 
-bool LMI_SO custom_io_1_file_exists();
+LMI_SO bool custom_io_1_file_exists();
 
 // These two functions take std::string arguments that either contain
 // filenames or are blank. If they're blank, as they normally are,
@@ -43,7 +43,7 @@ bool LMI_SO custom_io_1_file_exists();
 // that input and output files share a common stem; in this custom
 // situation, that need not be the case.
 
-bool LMI_SO custom_io_1_read (Input&       , std::string const& filename);
-void LMI_SO custom_io_1_write(Ledger const&, std::string const& filename);
+LMI_SO bool custom_io_1_read (Input&       , std::string const& filename);
+LMI_SO void custom_io_1_write(Ledger const&, std::string const& filename);
 
 #endif // custom_io_1_hpp
diff --git a/data_directory.hpp b/data_directory.hpp
index 34544d5..b323b2b 100644
--- a/data_directory.hpp
+++ b/data_directory.hpp
@@ -28,6 +28,6 @@
 
 #include <string>
 
-std::string LMI_SO AddDataDir(std::string const& filename);
+LMI_SO std::string AddDataDir(std::string const& filename);
 
 #endif // data_directory_hpp
diff --git a/database_view.cpp b/database_view.cpp
index 560c0a5..cd5524f 100644
--- a/database_view.cpp
+++ b/database_view.cpp
@@ -62,7 +62,7 @@ namespace
 ///    char const*         ShortName;
 /// The fields not included are of course accessed by indexing a
 /// db_names object from the vector returned by this function:
-///   std::vector<db_names> const& LMI_SO GetDBNames();
+///   LMI_SO std::vector<db_names> const& GetDBNames();
 /// Even db_names::Idx is accessed that way, and I think our
 /// discussions have raised the issue of whether that member's value
 /// should be asserted to equal the value of the loop counter in
@@ -77,7 +77,7 @@ namespace
 ///
 /// (1) This class holds only an e_database_key enum. That's enough to
 /// find the corresponding struct db_names in the vector returned by
-///   std::vector<db_names> const& LMI_SO GetDBNames();
+///   LMI_SO std::vector<db_names> const& GetDBNames();
 /// and we can then access that struct's members directly. And we
 /// don't have to know that description() here is 'LongName' there.
 /// Then the only thing we have to worry about is mapping between
diff --git a/db_sort.sed b/db_sort.sed
index 4c217df..4ffb009 100644
--- a/db_sort.sed
+++ b/db_sort.sed
@@ -31,360 +31,363 @@
 #   :execute "'<,'>!sed -f db_sort.sed" | '<,'>sort | '<,'>s/^[A-Z][0-9][0-9]//
 
 # DB_Topic_Underwriting
-/DB_MinIssAge\>/           s/^/A01/
-/DB_MaxIssAge\>/           s/^/A02/
-/DB_MaxIncrAge\>/          s/^/A03/
-/DB_AllowFullUw\>/         s/^/A04/
-/DB_AllowParamedUw\>/      s/^/A05/
-/DB_AllowNonmedUw\>/       s/^/A06/
-/DB_AllowSimpUw\>/         s/^/A07/
-/DB_AllowGuarUw\>/         s/^/A08/
-/DB_SmokeOrTobacco\>/      s/^/A09/
-/DB_AllowPreferredClass\>/ s/^/A10/
-/DB_AllowUltraPrefClass\>/ s/^/A11/
-/DB_AllowSubstdTable\>/    s/^/A12/
-/DB_AllowFlatExtras\>/     s/^/A13/
-/DB_AllowRatedWp\>/        s/^/A14/
-/DB_AllowRatedAdb\>/       s/^/A15/
-/DB_AllowRatedTerm\>/      s/^/A16/
-/DB_AllowRetirees\>/       s/^/A17/
-/DB_AllowUnisex\>/         s/^/A18/
-/DB_AllowSexDistinct\>/    s/^/A19/
-/DB_AllowUnismoke\>/       s/^/A20/
-/DB_AllowSmokeDistinct\>/  s/^/A21/
-/DB_StateApproved\>/       s/^/A22/
-/DB_AllowStateXX\>/        s/^/A23/
-/DB_AllowForeign\>/        s/^/A24/
-/DB_GroupIndivSelection\>/ s/^/A25/
-/DB_TxCallsGuarUwSubstd\>/ s/^/A26/
-/DB_Allowable\>/           s/^/A27/
+/DB_MinIssAge\>/                 s/^/A01/
+/DB_MaxIssAge\>/                 s/^/A02/
+/DB_MaxIncrAge\>/                s/^/A03/
+/DB_AllowFullUw\>/               s/^/A04/
+/DB_AllowParamedUw\>/            s/^/A05/
+/DB_AllowNonmedUw\>/             s/^/A06/
+/DB_AllowSimpUw\>/               s/^/A07/
+/DB_AllowGuarUw\>/               s/^/A08/
+/DB_SmokeOrTobacco\>/            s/^/A09/
+/DB_AllowPreferredClass\>/       s/^/A10/
+/DB_AllowUltraPrefClass\>/       s/^/A11/
+/DB_AllowSubstdTable\>/          s/^/A12/
+/DB_AllowFlatExtras\>/           s/^/A13/
+/DB_AllowRatedWp\>/              s/^/A14/
+/DB_AllowRatedAdb\>/             s/^/A15/
+/DB_AllowRatedTerm\>/            s/^/A16/
+/DB_AllowRetirees\>/             s/^/A17/
+/DB_AllowUnisex\>/               s/^/A18/
+/DB_AllowSexDistinct\>/          s/^/A19/
+/DB_AllowUnismoke\>/             s/^/A20/
+/DB_AllowSmokeDistinct\>/        s/^/A21/
+/DB_StateApproved\>/             s/^/A22/
+/DB_AllowStateXX\>/              s/^/A23/
+/DB_AllowForeign\>/              s/^/A24/
+/DB_GroupIndivSelection\>/       s/^/A25/
+/DB_TxCallsGuarUwSubstd\>/       s/^/A26/
+/DB_Allowable\>/                 s/^/A27/
 # DB_Topic_7702And7702A
-/DB_AllowCvat\>/           s/^/B01/
-/DB_AllowGpt\>/            s/^/B02/
-/DB_AllowNo7702\>/         s/^/B03/
-/DB_Irc7702Obreption\>/    s/^/B04/
-/DB_CorridorWhence\>/      s/^/B05/
-/DB_Irc7702NspWhence\>/    s/^/B06/
-/DB_SevenPayWhence\>/      s/^/B07/
-/DB_Irc7702QWhence\>/      s/^/B08/
-/DB_CorridorTable\>/       s/^/B09/
-/DB_Irc7702NspTable\>/     s/^/B10/
-/DB_SevenPayTable\>/       s/^/B11/
-/DB_Irc7702QTable\>/       s/^/B12/
-/DB_Irc7702QAxisGender\>/  s/^/B13/
-/DB_Irc7702QAxisSmoking\>/ s/^/B14/
-/DB_RatingsAffect7702\>/   s/^/B15/
-/DB_CvatMatChangeDefn\>/   s/^/B16/
-/DB_GptMatChangeDefn\>/    s/^/B17/
-/DB_Irc7702BftIsSpecAmt\>/ s/^/B18/
-/DB_RiskyInitial7702Db\>/  s/^/B19/
-/DB_Irc7702Endowment\>/    s/^/B20/
-/DB_Effective7702DboRop\>/ s/^/B21/
-/DB_TermIsQABOrDb7702\>/   s/^/B22/
-/DB_TermIsQABOrDb7702A\>/  s/^/B23/
-/DB_GioIsQAB\>/            s/^/B24/
-/DB_AdbIsQAB\>/            s/^/B25/
-/DB_SpouseRiderIsQAB\>/    s/^/B26/
-/DB_ChildRiderIsQAB\>/     s/^/B27/
-/DB_WpIsQAB\>/             s/^/B28/
+/DB_AllowCvat\>/                 s/^/B01/
+/DB_AllowGpt\>/                  s/^/B02/
+/DB_AllowNo7702\>/               s/^/B03/
+/DB_Irc7702Obreption\>/          s/^/B04/
+/DB_CorridorWhence\>/            s/^/B05/
+/DB_Irc7702NspWhence\>/          s/^/B06/
+/DB_SevenPayWhence\>/            s/^/B07/
+/DB_Irc7702QWhence\>/            s/^/B08/
+/DB_CorridorTable\>/             s/^/B09/
+/DB_Irc7702NspTable\>/           s/^/B10/
+/DB_SevenPayTable\>/             s/^/B11/
+/DB_Irc7702QTable\>/             s/^/B12/
+/DB_Irc7702QAxisGender\>/        s/^/B13/
+/DB_Irc7702QAxisSmoking\>/       s/^/B14/
+/DB_RatingsAffect7702\>/         s/^/B15/
+/DB_CvatMatChangeDefn\>/         s/^/B16/
+/DB_GptMatChangeDefn\>/          s/^/B17/
+/DB_Irc7702BftIsSpecAmt\>/       s/^/B18/
+/DB_RiskyInitial7702Db\>/        s/^/B19/
+/DB_Irc7702Endowment\>/          s/^/B20/
+/DB_Effective7702DboRop\>/       s/^/B21/
+/DB_TermIsQABOrDb7702\>/         s/^/B22/
+/DB_TermIsQABOrDb7702A\>/        s/^/B23/
+/DB_GioIsQAB\>/                  s/^/B24/
+/DB_AdbIsQAB\>/                  s/^/B25/
+/DB_SpouseRiderIsQAB\>/          s/^/B26/
+/DB_ChildRiderIsQAB\>/           s/^/B27/
+/DB_WpIsQAB\>/                   s/^/B28/
 # DB_Topic_MortalityCharges
-/DB_CsoEra\>/              s/^/C01/
-/DB_CsoMisprint\>/         s/^/C02/
-/DB_GuarCoiWhence\>/       s/^/C03/
-/DB_GuarCoiTable\>/        s/^/C04/
-/DB_GuarCoiIsAnnual\>/     s/^/C05/
-/DB_GuarCoiMultiplier\>/   s/^/C06/
-/DB_CurrCoiTable\>/        s/^/C07/
-/DB_CurrCoiIsAnnual\>/     s/^/C08/
-/DB_MinInputCoiMult\>/     s/^/C09/
-/DB_CurrCoiMultiplier\>/   s/^/C10/
-/DB_UnusualCoiBanding\>/   s/^/C11/
-/DB_CurrCoiTable0Limit\>/  s/^/C12/
-/DB_CurrCoiTable1\>/       s/^/C13/
-/DB_CurrCoiTable1Limit\>/  s/^/C14/
-/DB_CurrCoiTable2\>/       s/^/C15/
-/DB_MdptCoiTable\>/        s/^/C16/
-/DB_MdptCoiIsAnnual\>/     s/^/C17/
-/DB_CoiNyMinTable\>/       s/^/C18/
-/DB_UseNyCoiFloor\>/       s/^/C19/
-/DB_MaxMonthlyCoiRate\>/   s/^/C20/
-/DB_GuarCoiCeiling\>/      s/^/C21/
-/DB_CoiGuarIsMin\>/        s/^/C22/
-/DB_SubstdTableMult\>/     s/^/C23/
-/DB_SubstdTableMultTable\>/s/^/C24/
-/DB_CoiUpper12Method\>/    s/^/C25/
-/DB_CoiInforceReentry\>/   s/^/C26/
-/DB_CoiResetMinDate\>/     s/^/C27/
-/DB_CoiResetMaxDate\>/     s/^/C28/
-/DB_AllowMortBlendSex\>/   s/^/C29/
-/DB_AllowMortBlendSmoke\>/ s/^/C30/
+/DB_CsoEra\>/                    s/^/C01/
+/DB_CsoMisprint\>/               s/^/C02/
+/DB_GuarCoiWhence\>/             s/^/C03/
+/DB_GuarCoiTable\>/              s/^/C04/
+/DB_GuarCoiIsAnnual\>/           s/^/C05/
+/DB_GuarCoiMultiplier\>/         s/^/C06/
+/DB_CurrCoiTable\>/              s/^/C07/
+/DB_CurrCoiIsAnnual\>/           s/^/C08/
+/DB_MinInputCoiMult\>/           s/^/C09/
+/DB_CurrCoiMultiplier\>/         s/^/C10/
+/DB_UnusualCoiBanding\>/         s/^/C11/
+/DB_CurrCoiTable0Limit\>/        s/^/C12/
+/DB_CurrCoiTable1\>/             s/^/C13/
+/DB_CurrCoiTable1Limit\>/        s/^/C14/
+/DB_CurrCoiTable2\>/             s/^/C15/
+/DB_MdptCoiTable\>/              s/^/C16/
+/DB_MdptCoiIsAnnual\>/           s/^/C17/
+/DB_CoiNyMinTable\>/             s/^/C18/
+/DB_UseNyCoiFloor\>/             s/^/C19/
+/DB_MaxMonthlyCoiRate\>/         s/^/C20/
+/DB_GuarCoiCeiling\>/            s/^/C21/
+/DB_CoiGuarIsMin\>/              s/^/C22/
+/DB_SubstdTableMult\>/           s/^/C23/
+/DB_SubstdTableMultTable\>/      s/^/C24/
+/DB_CoiUpper12Method\>/          s/^/C25/
+/DB_CoiInforceReentry\>/         s/^/C26/
+/DB_CoiResetMinDate\>/           s/^/C27/
+/DB_CoiResetMaxDate\>/           s/^/C28/
+/DB_AllowMortBlendSex\>/         s/^/C29/
+/DB_AllowMortBlendSmoke\>/       s/^/C30/
 # DB_Topic_Interest
-/DB_GuarInt\>/             s/^/D01/
-/DB_NaarDiscount\>/        s/^/D02/
-/DB_GuarIntSpread\>/       s/^/D03/
-/DB_GuarMandE\>/           s/^/D04/
-/DB_CurrIntSpread\>/       s/^/D05/
-/DB_CurrMandE\>/           s/^/D06/
-/DB_GenAcctIntBonus\>/     s/^/D07/
-/DB_BonusInt\>/            s/^/D08/
-/DB_IntFloor\>/            s/^/D09/
-/DB_AllowGenAcct\>/        s/^/D10/
-/DB_AllowSepAcct\>/        s/^/D11/
-/DB_AllowGenAcctEarnRate\>/s/^/D12/
-/DB_AllowSepAcctNetRate\>/ s/^/D13/
-/DB_MaxGenAcctRate\>/      s/^/D14/
-/DB_MaxSepAcctRate\>/      s/^/D15/
-/DB_SepAcctSpreadMethod\>/ s/^/D16/
-/DB_IntSpreadMode\>/       s/^/D17/
-/DB_DynamicMandE\>/        s/^/D18/
+/DB_GuarInt\>/                   s/^/D01/
+/DB_NaarDiscount\>/              s/^/D02/
+/DB_GuarIntSpread\>/             s/^/D03/
+/DB_GuarMandE\>/                 s/^/D04/
+/DB_CurrIntSpread\>/             s/^/D05/
+/DB_CurrMandE\>/                 s/^/D06/
+/DB_GenAcctIntBonus\>/           s/^/D07/
+/DB_BonusInt\>/                  s/^/D08/
+/DB_IntFloor\>/                  s/^/D09/
+/DB_AllowGenAcct\>/              s/^/D10/
+/DB_AllowSepAcct\>/              s/^/D11/
+/DB_AllowGenAcctEarnRate\>/      s/^/D12/
+/DB_AllowSepAcctNetRate\>/       s/^/D13/
+/DB_MaxGenAcctRate\>/            s/^/D14/
+/DB_MaxSepAcctRate\>/            s/^/D15/
+/DB_SepAcctSpreadMethod\>/       s/^/D16/
+/DB_IntSpreadMode\>/             s/^/D17/
+/DB_DynamicMandE\>/              s/^/D18/
 # DB_Topic_AssetCharges
-/DB_AllowAmortPremLoad\>/  s/^/E01/
-/DB_LoadAmortFundCharge\>/ s/^/E02/
-/DB_AllowImfOverride\>/    s/^/E03/
-/DB_AssetChargeType\>/     s/^/E04/
-/DB_StableValFundCharge\>/ s/^/E05/
-/DB_GuarFundAdminChg\>/    s/^/E06/
-/DB_CurrFundAdminChg\>/    s/^/E07/
-/DB_FundCharge\>/          s/^/E08/
+/DB_AllowAmortPremLoad\>/        s/^/E01/
+/DB_LoadAmortFundCharge\>/       s/^/E02/
+/DB_AllowImfOverride\>/          s/^/E03/
+/DB_AssetChargeType\>/           s/^/E04/
+/DB_StableValFundCharge\>/       s/^/E05/
+/DB_GuarFundAdminChg\>/          s/^/E06/
+/DB_CurrFundAdminChg\>/          s/^/E07/
+/DB_FundCharge\>/                s/^/E08/
 # DB_Topic_Loads
-/DB_GuarMonthlyPolFee\>/   s/^/F01/
-/DB_GuarAnnualPolFee\>/    s/^/F02/
-/DB_GuarPremLoadTgt\>/     s/^/F03/
-/DB_GuarPremLoadExc\>/     s/^/F04/
-/DB_GuarPremLoadTgtRfd\>/  s/^/F05/
-/DB_GuarPremLoadExcRfd\>/  s/^/F06/
-/DB_GuarSpecAmtLoad\>/     s/^/F07/
-/DB_GuarSpecAmtLoadTable\>/s/^/F08/
-/DB_GuarAcctValLoad\>/     s/^/F09/
-/DB_CurrMonthlyPolFee\>/   s/^/F10/
-/DB_CurrAnnualPolFee\>/    s/^/F11/
-/DB_CurrPremLoadTgt\>/     s/^/F12/
-/DB_CurrPremLoadExc\>/     s/^/F13/
-/DB_CurrPremLoadTgtRfd\>/  s/^/F14/
-/DB_CurrPremLoadExcRfd\>/  s/^/F15/
-/DB_CurrSpecAmtLoad\>/     s/^/F16/
-/DB_CurrSpecAmtLoadTable\>/s/^/F17/
-/DB_CurrAcctValLoad\>/     s/^/F18/
-/DB_TgtPremMonthlyPolFee\>/s/^/F19/
-/DB_LoadRfdProportion\>/   s/^/F20/
-/DB_SpecAmtLoadLimit\>/    s/^/F21/
-/DB_DynamicSepAcctLoad\>/  s/^/F22/
-/DB_DynSepAcctLoadLimit\>/ s/^/F23/
+/DB_GuarMonthlyPolFee\>/         s/^/F01/
+/DB_GuarAnnualPolFee\>/          s/^/F02/
+/DB_GuarPremLoadTgt\>/           s/^/F03/
+/DB_GuarPremLoadExc\>/           s/^/F04/
+/DB_GuarPremLoadTgtRfd\>/        s/^/F05/
+/DB_GuarPremLoadExcRfd\>/        s/^/F06/
+/DB_GuarSpecAmtLoad\>/           s/^/F07/
+/DB_GuarSpecAmtLoadTable\>/      s/^/F08/
+/DB_GuarAcctValLoad\>/           s/^/F09/
+/DB_CurrMonthlyPolFee\>/         s/^/F10/
+/DB_CurrAnnualPolFee\>/          s/^/F11/
+/DB_CurrPremLoadTgt\>/           s/^/F12/
+/DB_CurrPremLoadExc\>/           s/^/F13/
+/DB_CurrPremLoadTgtRfd\>/        s/^/F14/
+/DB_CurrPremLoadExcRfd\>/        s/^/F15/
+/DB_CurrSpecAmtLoad\>/           s/^/F16/
+/DB_CurrSpecAmtLoadTable\>/      s/^/F17/
+/DB_CurrAcctValLoad\>/           s/^/F18/
+/DB_TgtPremMonthlyPolFee\>/      s/^/F19/
+/DB_LoadRfdProportion\>/         s/^/F20/
+/DB_SpecAmtLoadLimit\>/          s/^/F21/
+/DB_DynamicSepAcctLoad\>/        s/^/F22/
+/DB_DynSepAcctLoadLimit\>/       s/^/F23/
 # DB_Topic_DacAndPremiumTax
-/DB_DacTaxFundCharge\>/    s/^/G01/
-/DB_DacTaxPremLoad\>/      s/^/G02/
-/DB_PremTaxFundCharge\>/   s/^/G03/
-/DB_PremTaxLoad\>/         s/^/G04/
-/DB_WaivePremTaxInt1035\>/ s/^/G05/
-/DB_PremTaxRetalLimit\>/   s/^/G06/
-/DB_PremTaxTierGroup\>/    s/^/G07/
-/DB_PremTaxTierPeriod\>/   s/^/G08/
-/DB_PremTaxTierNonDecr\>/  s/^/G09/
-/DB_PremTaxAmortPeriod\>/  s/^/G10/
-/DB_PremTaxAmortIntRate\>/ s/^/G11/
-/DB_PremTaxRate\>/         s/^/G12/
-/DB_PremTaxState\>/        s/^/G13/
+/DB_DacTaxFundCharge\>/          s/^/G01/
+/DB_DacTaxPremLoad\>/            s/^/G02/
+/DB_PremTaxFundCharge\>/         s/^/G03/
+/DB_PremTaxLoad\>/               s/^/G04/
+/DB_WaivePremTaxInt1035\>/       s/^/G05/
+/DB_PremTaxRetalLimit\>/         s/^/G06/
+/DB_PremTaxTierGroup\>/          s/^/G07/
+/DB_PremTaxTierPeriod\>/         s/^/G08/
+/DB_PremTaxTierNonDecr\>/        s/^/G09/
+/DB_PremTaxAmortPeriod\>/        s/^/G10/
+/DB_PremTaxAmortIntRate\>/       s/^/G11/
+/DB_PremTaxRate\>/               s/^/G12/
+/DB_PremTaxState\>/              s/^/G13/
 # DB_Topic_SurrenderCharges
-/DB_SurrChgOnIncr\>/       s/^/H01/
-/DB_SurrChgOnDecr\>/       s/^/H02/
-/DB_Has1035ExchCharge\>/   s/^/H03/
-/DB_SnflQTable\>/          s/^/H04/
-/DB_CoiSnflIsGuar\>/       s/^/H05/
-/DB_SurrChgByFormula\>/    s/^/H06/
-/DB_SurrChgPeriod\>/       s/^/H07/
-/DB_SurrChgZeroDur\>/      s/^/H08/
-/DB_SurrChgNlpMult\>/      s/^/H09/
-/DB_SurrChgNlpMax\>/       s/^/H10/
-/DB_SurrChgEaMax\>/        s/^/H11/
-/DB_SurrChgAmort\>/        s/^/H12/
+/DB_SurrChgOnIncr\>/             s/^/H01/
+/DB_SurrChgOnDecr\>/             s/^/H02/
+/DB_Has1035ExchCharge\>/         s/^/H03/
+/DB_SnflQTable\>/                s/^/H04/
+/DB_CoiSnflIsGuar\>/             s/^/H05/
+/DB_SurrChgByFormula\>/          s/^/H06/
+/DB_SurrChgPeriod\>/             s/^/H07/
+/DB_SurrChgZeroDur\>/            s/^/H08/
+/DB_SurrChgNlpMult\>/            s/^/H09/
+/DB_SurrChgNlpMax\>/             s/^/H10/
+/DB_SurrChgEaMax\>/              s/^/H11/
+/DB_SurrChgAmort\>/              s/^/H12/
 # DB_Topic_DeathBenefits
-/DB_AllowSpecAmtIncr\>/    s/^/I01/
-/DB_MinSpecAmtIncr\>/      s/^/I02/
-/DB_EnforceNaarLimit\>/    s/^/I03/
-/DB_MinSpecAmt\>/          s/^/I04/
-/DB_MinIssSpecAmt\>/       s/^/I05/
-/DB_MinIssBaseSpecAmt\>/   s/^/I06/
-/DB_MinRenlSpecAmt\>/      s/^/I07/
-/DB_MinRenlBaseSpecAmt\>/  s/^/I08/
-/DB_MaxIssSpecAmt\>/       s/^/I09/
-/DB_MaxRenlSpecAmt\>/      s/^/I10/
-/DB_AllowDboLvl\>/         s/^/I11/
-/DB_AllowDboInc\>/         s/^/I12/
-/DB_AllowDboRop\>/         s/^/I13/
-/DB_AllowDboMdb\>/         s/^/I14/
-/DB_DboLvlChangeToWhat\>/  s/^/I15/
-/DB_DboLvlChangeMethod\>/  s/^/I16/
-/DB_DboIncChangeToWhat\>/  s/^/I17/
-/DB_DboIncChangeMethod\>/  s/^/I18/
-/DB_DboRopChangeToWhat\>/  s/^/I19/
-/DB_DboRopChangeMethod\>/  s/^/I20/
-/DB_DboMdbChangeToWhat\>/  s/^/I21/
-/DB_DboMdbChangeMethod\>/  s/^/I22/
-/DB_AllowChangeToDbo2\>/   s/^/I23/
-/DB_DboChgCanIncrSpecAmt\>/s/^/I24/
-/DB_DboChgCanDecrSpecAmt\>/s/^/I25/
-/DB_AllowExtEndt\>/        s/^/I26/
+/DB_AllowSpecAmtIncr\>/          s/^/I01/
+/DB_MinSpecAmtIncr\>/            s/^/I02/
+/DB_EnforceNaarLimit\>/          s/^/I03/
+/DB_MinSpecAmt\>/                s/^/I04/
+/DB_MinIssSpecAmt\>/             s/^/I05/
+/DB_MinIssBaseSpecAmt\>/         s/^/I06/
+/DB_MinRenlSpecAmt\>/            s/^/I07/
+/DB_MinRenlBaseSpecAmt\>/        s/^/I08/
+/DB_MaxIssSpecAmt\>/             s/^/I09/
+/DB_MaxRenlSpecAmt\>/            s/^/I10/
+/DB_AllowDboLvl\>/               s/^/I11/
+/DB_AllowDboInc\>/               s/^/I12/
+/DB_AllowDboRop\>/               s/^/I13/
+/DB_AllowDboMdb\>/               s/^/I14/
+/DB_DboLvlChangeToWhat\>/        s/^/I15/
+/DB_DboLvlChangeMethod\>/        s/^/I16/
+/DB_DboIncChangeToWhat\>/        s/^/I17/
+/DB_DboIncChangeMethod\>/        s/^/I18/
+/DB_DboRopChangeToWhat\>/        s/^/I19/
+/DB_DboRopChangeMethod\>/        s/^/I20/
+/DB_DboMdbChangeToWhat\>/        s/^/I21/
+/DB_DboMdbChangeMethod\>/        s/^/I22/
+/DB_AllowChangeToDbo2\>/         s/^/I23/
+/DB_DboChgCanIncrSpecAmt\>/      s/^/I24/
+/DB_DboChgCanDecrSpecAmt\>/      s/^/I25/
+/DB_AllowExtEndt\>/              s/^/I26/
 # DB_Topic_Riders
-/DB_AllowTerm\>/           s/^/J01/
-/DB_GuarTermTable\>/       s/^/J02/
-/DB_TermTable\>/           s/^/J03/
-/DB_TermMinIssAge\>/       s/^/J04/
-/DB_TermMaxIssAge\>/       s/^/J05/
-/DB_TermIsNotRider\>/      s/^/J06/
-/DB_TermCanLapse\>/        s/^/J07/
-/DB_TermForcedConvAge\>/   s/^/J08/
-/DB_TermForcedConvDur\>/   s/^/J09/
-/DB_MaxTermProportion\>/   s/^/J10/
-/DB_TermCoiRate\>/         s/^/J11/
-/DB_TermPremRate\>/        s/^/J12/
-/DB_AllowWp\>/             s/^/J13/
-/DB_WpTable\>/             s/^/J14/
-/DB_WpMinIssAge\>/         s/^/J15/
-/DB_WpMaxIssAge\>/         s/^/J16/
-/DB_WpLimit\>/             s/^/J17/
-/DB_WpCoiRate\>/           s/^/J18/
-/DB_WpPremRate\>/          s/^/J19/
-/DB_WpChargeMethod\>/      s/^/J20/
-/DB_AllowAdb\>/            s/^/J21/
-/DB_AdbTable\>/            s/^/J22/
-/DB_AdbMinIssAge\>/        s/^/J23/
-/DB_AdbMaxIssAge\>/        s/^/J24/
-/DB_AdbLimit\>/            s/^/J25/
-/DB_AdbCoiRate\>/          s/^/J26/
-/DB_AdbPremRate\>/         s/^/J27/
-/DB_AllowSpouseRider\>/    s/^/J28/
-/DB_SpouseRiderMinAmt\>/   s/^/J29/
-/DB_SpouseRiderMaxAmt\>/   s/^/J30/
-/DB_SpouseRiderMinIssAge\>/s/^/J31/
-/DB_SpouseRiderMaxIssAge\>/s/^/J32/
-/DB_SpouseRiderGuarTable\>/s/^/J33/
-/DB_SpouseRiderTable\>/    s/^/J34/
-/DB_AllowChildRider\>/     s/^/J35/
-/DB_ChildRiderMinAmt\>/    s/^/J36/
-/DB_ChildRiderMaxAmt\>/    s/^/J37/
-/DB_ChildRiderTable\>/     s/^/J38/
+/DB_AllowTerm\>/                 s/^/J01/
+/DB_GuarTermTable\>/             s/^/J02/
+/DB_TermTable\>/                 s/^/J03/
+/DB_TermMinIssAge\>/             s/^/J04/
+/DB_TermMaxIssAge\>/             s/^/J05/
+/DB_TermIsNotRider\>/            s/^/J06/
+/DB_TermCanLapse\>/              s/^/J07/
+/DB_TermForcedConvAge\>/         s/^/J08/
+/DB_TermForcedConvDur\>/         s/^/J09/
+/DB_MaxTermProportion\>/         s/^/J10/
+/DB_TermCoiRate\>/               s/^/J11/
+/DB_TermPremRate\>/              s/^/J12/
+/DB_AllowWp\>/                   s/^/J13/
+/DB_WpTable\>/                   s/^/J14/
+/DB_WpMinIssAge\>/               s/^/J15/
+/DB_WpMaxIssAge\>/               s/^/J16/
+/DB_WpLimit\>/                   s/^/J17/
+/DB_WpCoiRate\>/                 s/^/J18/
+/DB_WpPremRate\>/                s/^/J19/
+/DB_WpChargeMethod\>/            s/^/J20/
+/DB_AllowAdb\>/                  s/^/J21/
+/DB_AdbTable\>/                  s/^/J22/
+/DB_AdbMinIssAge\>/              s/^/J23/
+/DB_AdbMaxIssAge\>/              s/^/J24/
+/DB_AdbLimit\>/                  s/^/J25/
+/DB_AdbCoiRate\>/                s/^/J26/
+/DB_AdbPremRate\>/               s/^/J27/
+/DB_AllowSpouseRider\>/          s/^/J28/
+/DB_SpouseRiderMinAmt\>/         s/^/J29/
+/DB_SpouseRiderMaxAmt\>/         s/^/J30/
+/DB_SpouseRiderMinIssAge\>/      s/^/J31/
+/DB_SpouseRiderMaxIssAge\>/      s/^/J32/
+/DB_SpouseRiderGuarTable\>/      s/^/J33/
+/DB_SpouseRiderTable\>/          s/^/J34/
+/DB_AllowChildRider\>/           s/^/J35/
+/DB_ChildRiderMinAmt\>/          s/^/J36/
+/DB_ChildRiderMaxAmt\>/          s/^/J37/
+/DB_ChildRiderTable\>/           s/^/J38/
 # DB_Topic_Withdrawals
-/DB_AllowWd\>/             s/^/K01/
-/DB_WdFee\>/               s/^/K02/
-/DB_WdFeeRate\>/           s/^/K03/
-/DB_FreeWdProportion\>/    s/^/K04/
-/DB_MinWd\>/               s/^/K05/
-/DB_MaxWdGenAcctValMult\>/ s/^/K06/
-/DB_MaxWdSepAcctValMult\>/ s/^/K07/
-/DB_MaxWdDed\>/            s/^/K08/
-/DB_WdDecrSpecAmtDboLvl\>/ s/^/K09/
-/DB_WdDecrSpecAmtDboInc\>/ s/^/K10/
-/DB_WdDecrSpecAmtDboRop\>/ s/^/K11/
-/DB_FirstWdMonth\>/        s/^/K12/
+/DB_AllowWd\>/                   s/^/K01/
+/DB_WdFee\>/                     s/^/K02/
+/DB_WdFeeRate\>/                 s/^/K03/
+/DB_FreeWdProportion\>/          s/^/K04/
+/DB_MinWd\>/                     s/^/K05/
+/DB_MaxWdGenAcctValMult\>/       s/^/K06/
+/DB_MaxWdSepAcctValMult\>/       s/^/K07/
+/DB_MaxWdDed\>/                  s/^/K08/
+/DB_WdDecrSpecAmtDboLvl\>/       s/^/K09/
+/DB_WdDecrSpecAmtDboInc\>/       s/^/K10/
+/DB_WdDecrSpecAmtDboRop\>/       s/^/K11/
+/DB_FirstWdMonth\>/              s/^/K12/
 # DB_Topic_Loans
-/DB_AllowLoan\>/           s/^/L01/
-/DB_AllowPrefLoan\>/       s/^/L02/
-/DB_AllowFixedLoan\>/      s/^/L03/
-/DB_AllowVlr\>/            s/^/L04/
-/DB_FixedLoanRate\>/       s/^/L05/
-/DB_MaxVlrRate\>/          s/^/L06/
-/DB_MinVlrRate\>/          s/^/L07/
-/DB_MaxLoanAcctValMult\>/  s/^/L08/
-/DB_MaxLoanDed\>/          s/^/L09/
-/DB_FirstPrefLoanYear\>/   s/^/L10/
-/DB_PrefLoanRateDecr\>/    s/^/L11/
-/DB_GuarPrefLoanSpread\>/  s/^/L12/
-/DB_GuarRegLoanSpread\>/   s/^/L13/
-/DB_CurrPrefLoanSpread\>/  s/^/L14/
-/DB_CurrRegLoanSpread\>/   s/^/L15/
-/DB_FirstLoanMonth\>/      s/^/L16/
+/DB_AllowLoan\>/                 s/^/L01/
+/DB_AllowPrefLoan\>/             s/^/L02/
+/DB_AllowFixedLoan\>/            s/^/L03/
+/DB_AllowVlr\>/                  s/^/L04/
+/DB_FixedLoanRate\>/             s/^/L05/
+/DB_MaxVlrRate\>/                s/^/L06/
+/DB_MinVlrRate\>/                s/^/L07/
+/DB_MaxLoanAcctValMult\>/        s/^/L08/
+/DB_MaxLoanDed\>/                s/^/L09/
+/DB_FirstPrefLoanYear\>/         s/^/L10/
+/DB_PrefLoanRateDecr\>/          s/^/L11/
+/DB_GuarPrefLoanSpread\>/        s/^/L12/
+/DB_GuarRegLoanSpread\>/         s/^/L13/
+/DB_CurrPrefLoanSpread\>/        s/^/L14/
+/DB_CurrRegLoanSpread\>/         s/^/L15/
+/DB_FirstLoanMonth\>/            s/^/L16/
 # DB_Topic_Premiums
-/DB_MinPremType\>/         s/^/M01/
-/DB_MinPremTable\>/        s/^/M02/
-/DB_MinPremIntSpread\>/    s/^/M03/
-/DB_SplitMinPrem\>/        s/^/M04/
-/DB_UnsplitSplitMinPrem\>/ s/^/M05/
-/DB_ErNotionallyPaysTerm\>/s/^/M06/
-/DB_TgtPremType\>/         s/^/M07/
-/DB_TgtPremTable\>/        s/^/M08/
-/DB_TgtPremFixedAtIssue\>/ s/^/M09/
-/DB_TgtPremIgnoreSubstd\>/ s/^/M10/
-/DB_MinPmt\>/              s/^/M11/
-/DB_IsSinglePremium\>/     s/^/M12/
+/DB_MinPremType\>/               s/^/M01/
+/DB_MinPremTable\>/              s/^/M02/
+/DB_MinPremIntSpread\>/          s/^/M03/
+/DB_SplitMinPrem\>/              s/^/M04/
+/DB_UnsplitSplitMinPrem\>/       s/^/M05/
+/DB_ErNotionallyPaysTerm\>/      s/^/M06/
+/DB_TgtPremType\>/               s/^/M07/
+/DB_TgtPremTable\>/              s/^/M08/
+/DB_TgtPremFixedAtIssue\>/       s/^/M09/
+/DB_TgtPremIgnoreSubstd\>/       s/^/M10/
+/DB_MinPmt\>/                    s/^/M11/
+/DB_IsSinglePremium\>/           s/^/M12/
 # DB_Topic_SecondaryGuarantees
-/DB_NoLapseMinDur\>/       s/^/N01/
-/DB_NoLapseMinAge\>/       s/^/N02/
-/DB_NoLapseUnratedOnly\>/  s/^/N03/
-/DB_NoLapseDboLvlOnly\>/   s/^/N04/
-/DB_NoLapseAlwaysActive\>/ s/^/N05/
-/DB_AllowHoneymoon\>/      s/^/N06/
+/DB_NoLapseMinDur\>/             s/^/N01/
+/DB_NoLapseMinAge\>/             s/^/N02/
+/DB_NoLapseUnratedOnly\>/        s/^/N03/
+/DB_NoLapseDboLvlOnly\>/         s/^/N04/
+/DB_NoLapseAlwaysActive\>/       s/^/N05/
+/DB_AllowHoneymoon\>/            s/^/N06/
 # DB_Topic_Allocations
-/DB_DeductionMethod\>/     s/^/O01/
-/DB_DeductionAcct\>/       s/^/O02/
-/DB_DistributionMethod\>/  s/^/O03/
-/DB_DistributionAcct\>/    s/^/O04/
-/DB_EePremMethod\>/        s/^/O05/
-/DB_EePremAcct\>/          s/^/O06/
-/DB_ErPremMethod\>/        s/^/O07/
-/DB_ErPremAcct\>/          s/^/O08/
+/DB_DeductionMethod\>/           s/^/O01/
+/DB_DeductionAcct\>/             s/^/O02/
+/DB_DistributionMethod\>/        s/^/O03/
+/DB_DistributionAcct\>/          s/^/O04/
+/DB_EePremMethod\>/              s/^/O05/
+/DB_EePremAcct\>/                s/^/O06/
+/DB_ErPremMethod\>/              s/^/O07/
+/DB_ErPremAcct\>/                s/^/O08/
 # DB_Topic_Compensation
-/DB_CalculateComp\>/       s/^/P01/
-/DB_CompTarget\>/          s/^/P02/
-/DB_CompExcess\>/          s/^/P03/
-/DB_CompChargeback\>/      s/^/P04/
-/DB_AssetComp\>/           s/^/P05/
-/DB_AllowExtraAssetComp\>/ s/^/P06/
-/DB_AllowExtraPremComp\>/  s/^/P07/
+/DB_CalculateComp\>/             s/^/P01/
+/DB_CompTarget\>/                s/^/P02/
+/DB_CompExcess\>/                s/^/P03/
+/DB_CompChargeback\>/            s/^/P04/
+/DB_AssetComp\>/                 s/^/P05/
+/DB_AllowExtraAssetComp\>/       s/^/P06/
+/DB_AllowExtraPremComp\>/        s/^/P07/
 # DB_Topic_ExperienceRating
-/DB_AllowExpRating\>/      s/^/Q01/
-/DB_ExpRatStdDevMult\>/    s/^/Q02/
-/DB_ExpRatIbnrMult\>/      s/^/Q03/
-/DB_ExpRatCoiRetention\>/  s/^/Q04/
-/DB_ExpRatRiskCoiMult\>/   s/^/Q05/
-/DB_ExpRatAmortPeriod\>/   s/^/Q06/
+/DB_AllowExpRating\>/            s/^/Q01/
+/DB_ExpRatStdDevMult\>/          s/^/Q02/
+/DB_ExpRatIbnrMult\>/            s/^/Q03/
+/DB_ExpRatCoiRetention\>/        s/^/Q04/
+/DB_ExpRatRiskCoiMult\>/         s/^/Q05/
+/DB_ExpRatAmortPeriod\>/         s/^/Q06/
 # DB_Topic_Miscellanea
-/DB_LedgerType\>/          s/^/R01/
-/DB_Nonillustrated\>/      s/^/R02/
-/DB_NoLongerIssued\>/      s/^/R03/
-/DB_AgeLastOrNearest\>/    s/^/R04/
-/DB_MaturityAge\>/         s/^/R05/
-/DB_CashValueEnhMult\>/    s/^/R06/
-/DB_LapseIgnoresSurrChg\>/ s/^/R07/
-/DB_DefaultProcessOrder\>/ s/^/R08/
-/DB_GroupProxyRateTable\>/ s/^/R09/
-/DB_PartialMortTable\>/    s/^/R10/
-/DB_UsePolicyFormAlt\>/    s/^/R11/
-/DB_AllowGroupQuote\>/     s/^/R12/
+/DB_LedgerType\>/                s/^/R01/
+/DB_Nonillustrated\>/            s/^/R02/
+/DB_NoLongerIssued\>/            s/^/R03/
+/DB_AgeLastOrNearest\>/          s/^/R04/
+/DB_MaturityAge\>/               s/^/R05/
+/DB_CashValueEnhMult\>/          s/^/R06/
+/DB_LapseIgnoresSurrChg\>/       s/^/R07/
+/DB_DefaultProcessOrder\>/       s/^/R08/
+/DB_GroupProxyRateTable\>/       s/^/R09/
+/DB_PartialMortTable\>/          s/^/R10/
+# // LINGO !! expunge
+/DB_UsePolicyFormAlt\>/          s/^/R11/
+/DB_AllowGroupQuote\>/           s/^/R12/
+# DB_Topic_Lingo
+/DB_PolicyForm\>/                s/^/S01/
 # DB_Topic_Weights
-/DB_WeightClass\>/         s/^/S01/
-/DB_WeightGender\>/        s/^/S02/
-/DB_WeightSmoking\>/       s/^/S03/
-/DB_WeightAge\>/           s/^/S04/
-/DB_WeightSpecAmt\>/       s/^/S05/
-/DB_WeightState\>/         s/^/S06/
+/DB_WeightClass\>/               s/^/T01/
+/DB_WeightGender\>/              s/^/T02/
+/DB_WeightSmoking\>/             s/^/T03/
+/DB_WeightAge\>/                 s/^/T04/
+/DB_WeightSpecAmt\>/             s/^/T05/
+/DB_WeightState\>/               s/^/T06/
 # DB_Topic_Expenses
-/DB_FullExpPol\>/          s/^/T01/
-/DB_FullExpPrem\>/         s/^/T02/
-/DB_FullExpDumpin\>/       s/^/T03/
-/DB_FullExpSpecAmt\>/      s/^/T04/
-/DB_VarExpPol\>/           s/^/T05/
-/DB_VarExpPrem\>/          s/^/T06/
-/DB_VarExpDumpin\>/        s/^/T07/
-/DB_VarExpSpecAmt\>/       s/^/T08/
-/DB_ExpSpecAmtLimit\>/     s/^/T09/
-/DB_MedicalProportion\>/   s/^/T10/
-/DB_UwTestCost\>/          s/^/T11/
+/DB_FullExpPol\>/                s/^/U01/
+/DB_FullExpPrem\>/               s/^/U02/
+/DB_FullExpDumpin\>/             s/^/U03/
+/DB_FullExpSpecAmt\>/            s/^/U04/
+/DB_VarExpPol\>/                 s/^/U05/
+/DB_VarExpPrem\>/                s/^/U06/
+/DB_VarExpDumpin\>/              s/^/U07/
+/DB_VarExpSpecAmt\>/             s/^/U08/
+/DB_ExpSpecAmtLimit\>/           s/^/U09/
+/DB_MedicalProportion\>/         s/^/U10/
+/DB_UwTestCost\>/                s/^/U11/
 # DB_Topic_Reserves
-/DB_VxBasicQTable\>/       s/^/U01/
-/DB_VxDeficQTable\>/       s/^/U02/
-/DB_VxTaxQTable\>/         s/^/U03/
-/DB_StatVxInt\>/           s/^/U04/
-/DB_TaxVxInt\>/            s/^/U05/
-/DB_StatVxQ\>/             s/^/U06/
-/DB_TaxVxQ\>/              s/^/U07/
-/DB_DeficVxQ\>/            s/^/U08/
-/DB_SnflQ\>/               s/^/U09/
+/DB_VxBasicQTable\>/             s/^/V01/
+/DB_VxDeficQTable\>/             s/^/V02/
+/DB_VxTaxQTable\>/               s/^/V03/
+/DB_StatVxInt\>/                 s/^/V04/
+/DB_TaxVxInt\>/                  s/^/V05/
+/DB_StatVxQ\>/                   s/^/V06/
+/DB_TaxVxQ\>/                    s/^/V07/
+/DB_DeficVxQ\>/                  s/^/V08/
+/DB_SnflQ\>/                     s/^/V09/
 # DB_Topic_OtherAssumptions
-/DB_LapseRate\>/           s/^/V01/
-/DB_ReqSurpNaar\>/         s/^/V02/
-/DB_ReqSurpVx\>/           s/^/V03/
-/DB_LicFitRate\>/          s/^/V04/
-/DB_LicDacTaxRate\>/       s/^/V05/
-/DB_GdbVxMethod\>/         s/^/V06/
-/DB_PrimaryHurdle\>/       s/^/V07/
-/DB_SecondaryHurdle\>/     s/^/V08/
+/DB_LapseRate\>/                 s/^/W01/
+/DB_ReqSurpNaar\>/               s/^/W02/
+/DB_ReqSurpVx\>/                 s/^/W03/
+/DB_LicFitRate\>/                s/^/W04/
+/DB_LicDacTaxRate\>/             s/^/W05/
+/DB_GdbVxMethod\>/               s/^/W06/
+/DB_PrimaryHurdle\>/             s/^/W07/
+/DB_SecondaryHurdle\>/           s/^/W08/
diff --git a/dbdict.cpp b/dbdict.cpp
index e8b0a5b..377c123 100644
--- a/dbdict.cpp
+++ b/dbdict.cpp
@@ -31,13 +31,14 @@
 #include "data_directory.hpp"
 #include "dbnames.hpp"
 #include "global_settings.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "ieee754.hpp"                  // infinity<>()
 #include "mc_enum_type_enums.hpp"
 #include "miscellany.hpp"
 #include "my_proem.hpp"                 // ::write_proem()
 #include "oecumenic_enumerations.hpp"
 #include "premium_tax.hpp"              // 
premium_tax_rates_for_life_insurance()
+#include "sample.hpp"                   // superior::lingo
 #include "xml_lmi.hpp"
 #include "xml_serialize.hpp"
 
@@ -117,342 +118,514 @@ database_entity& DBDictionary::datum(std::string const& 
name)
 
 void DBDictionary::ascribe_members()
 {
-    ascribe("MinIssAge"           , &DBDictionary::MinIssAge           );
-    ascribe("MaxIssAge"           , &DBDictionary::MaxIssAge           );
-    ascribe("MaxIncrAge"          , &DBDictionary::MaxIncrAge          );
-    ascribe("AllowFullUw"         , &DBDictionary::AllowFullUw         );
-    ascribe("AllowParamedUw"      , &DBDictionary::AllowParamedUw      );
-    ascribe("AllowNonmedUw"       , &DBDictionary::AllowNonmedUw       );
-    ascribe("AllowSimpUw"         , &DBDictionary::AllowSimpUw         );
-    ascribe("AllowGuarUw"         , &DBDictionary::AllowGuarUw         );
-    ascribe("SmokeOrTobacco"      , &DBDictionary::SmokeOrTobacco      );
-    ascribe("AllowPreferredClass" , &DBDictionary::AllowPreferredClass );
-    ascribe("AllowUltraPrefClass" , &DBDictionary::AllowUltraPrefClass );
-    ascribe("AllowSubstdTable"    , &DBDictionary::AllowSubstdTable    );
-    ascribe("AllowFlatExtras"     , &DBDictionary::AllowFlatExtras     );
-    ascribe("AllowRatedWp"        , &DBDictionary::AllowRatedWp        );
-    ascribe("AllowRatedAdb"       , &DBDictionary::AllowRatedAdb       );
-    ascribe("AllowRatedTerm"      , &DBDictionary::AllowRatedTerm      );
-    ascribe("AllowRetirees"       , &DBDictionary::AllowRetirees       );
-    ascribe("AllowUnisex"         , &DBDictionary::AllowUnisex         );
-    ascribe("AllowSexDistinct"    , &DBDictionary::AllowSexDistinct    );
-    ascribe("AllowUnismoke"       , &DBDictionary::AllowUnismoke       );
-    ascribe("AllowSmokeDistinct"  , &DBDictionary::AllowSmokeDistinct  );
-    ascribe("StateApproved"       , &DBDictionary::StateApproved       );
-    ascribe("AllowStateXX"        , &DBDictionary::AllowStateXX        );
-    ascribe("AllowForeign"        , &DBDictionary::AllowForeign        );
-    ascribe("GroupIndivSelection" , &DBDictionary::GroupIndivSelection );
-    ascribe("TxCallsGuarUwSubstd" , &DBDictionary::TxCallsGuarUwSubstd );
-    ascribe("Allowable"           , &DBDictionary::Allowable           );
-    ascribe("AllowCvat"           , &DBDictionary::AllowCvat           );
-    ascribe("AllowGpt"            , &DBDictionary::AllowGpt            );
-    ascribe("AllowNo7702"         , &DBDictionary::AllowNo7702         );
-    ascribe("Irc7702Obreption"    , &DBDictionary::Irc7702Obreption    );
-    ascribe("CorridorWhence"      , &DBDictionary::CorridorWhence      );
-    ascribe("Irc7702NspWhence"    , &DBDictionary::Irc7702NspWhence    );
-    ascribe("SevenPayWhence"      , &DBDictionary::SevenPayWhence      );
-    ascribe("Irc7702QWhence"      , &DBDictionary::Irc7702QWhence      );
-    ascribe("CorridorTable"       , &DBDictionary::CorridorTable       );
-    ascribe("Irc7702NspTable"     , &DBDictionary::Irc7702NspTable     );
-    ascribe("SevenPayTable"       , &DBDictionary::SevenPayTable       );
-    ascribe("Irc7702QTable"       , &DBDictionary::Irc7702QTable       );
-    ascribe("Irc7702QAxisGender"  , &DBDictionary::Irc7702QAxisGender  );
-    ascribe("Irc7702QAxisSmoking" , &DBDictionary::Irc7702QAxisSmoking );
-    ascribe("RatingsAffect7702"   , &DBDictionary::RatingsAffect7702   );
-    ascribe("CvatMatChangeDefn"   , &DBDictionary::CvatMatChangeDefn   );
-    ascribe("GptMatChangeDefn"    , &DBDictionary::GptMatChangeDefn    );
-    ascribe("Irc7702BftIsSpecAmt" , &DBDictionary::Irc7702BftIsSpecAmt );
-    ascribe("RiskyInitial7702Db"  , &DBDictionary::RiskyInitial7702Db  );
-    ascribe("Irc7702Endowment"    , &DBDictionary::Irc7702Endowment    );
-    ascribe("Effective7702DboRop" , &DBDictionary::Effective7702DboRop );
-    ascribe("TermIsQABOrDb7702"   , &DBDictionary::TermIsQABOrDb7702   );
-    ascribe("TermIsQABOrDb7702A"  , &DBDictionary::TermIsQABOrDb7702A  );
-    ascribe("GioIsQAB"            , &DBDictionary::GioIsQAB            );
-    ascribe("AdbIsQAB"            , &DBDictionary::AdbIsQAB            );
-    ascribe("SpouseRiderIsQAB"    , &DBDictionary::SpouseRiderIsQAB    );
-    ascribe("ChildRiderIsQAB"     , &DBDictionary::ChildRiderIsQAB     );
-    ascribe("WpIsQAB"             , &DBDictionary::WpIsQAB             );
-    ascribe("CsoEra"              , &DBDictionary::CsoEra              );
-    ascribe("CsoMisprint"         , &DBDictionary::CsoMisprint         );
-    ascribe("GuarCoiWhence"       , &DBDictionary::GuarCoiWhence       );
-    ascribe("GuarCoiTable"        , &DBDictionary::GuarCoiTable        );
-    ascribe("GuarCoiIsAnnual"     , &DBDictionary::GuarCoiIsAnnual     );
-    ascribe("GuarCoiMultiplier"   , &DBDictionary::GuarCoiMultiplier   );
-    ascribe("CurrCoiTable"        , &DBDictionary::CurrCoiTable        );
-    ascribe("CurrCoiIsAnnual"     , &DBDictionary::CurrCoiIsAnnual     );
-    ascribe("MinInputCoiMult"     , &DBDictionary::MinInputCoiMult     );
-    ascribe("CurrCoiMultiplier"   , &DBDictionary::CurrCoiMultiplier   );
-    ascribe("UnusualCoiBanding"   , &DBDictionary::UnusualCoiBanding   );
-    ascribe("CurrCoiTable0Limit"  , &DBDictionary::CurrCoiTable0Limit  );
-    ascribe("CurrCoiTable1"       , &DBDictionary::CurrCoiTable1       );
-    ascribe("CurrCoiTable1Limit"  , &DBDictionary::CurrCoiTable1Limit  );
-    ascribe("CurrCoiTable2"       , &DBDictionary::CurrCoiTable2       );
-    ascribe("MdptCoiTable"        , &DBDictionary::MdptCoiTable        );
-    ascribe("MdptCoiIsAnnual"     , &DBDictionary::MdptCoiIsAnnual     );
-    ascribe("CoiNyMinTable"       , &DBDictionary::CoiNyMinTable       );
-    ascribe("UseNyCoiFloor"       , &DBDictionary::UseNyCoiFloor       );
-    ascribe("MaxMonthlyCoiRate"   , &DBDictionary::MaxMonthlyCoiRate   );
-    ascribe("GuarCoiCeiling"      , &DBDictionary::GuarCoiCeiling      );
-    ascribe("CoiGuarIsMin"        , &DBDictionary::CoiGuarIsMin        );
-    ascribe("SubstdTableMult"     , &DBDictionary::SubstdTableMult     );
-    ascribe("SubstdTableMultTable", &DBDictionary::SubstdTableMultTable);
-    ascribe("CoiUpper12Method"    , &DBDictionary::CoiUpper12Method    );
-    ascribe("CoiInforceReentry"   , &DBDictionary::CoiInforceReentry   );
-    ascribe("CoiResetMinDate"     , &DBDictionary::CoiResetMinDate     );
-    ascribe("CoiResetMaxDate"     , &DBDictionary::CoiResetMaxDate     );
-    ascribe("AllowMortBlendSex"   , &DBDictionary::AllowMortBlendSex   );
-    ascribe("AllowMortBlendSmoke" , &DBDictionary::AllowMortBlendSmoke );
-    ascribe("GuarInt"             , &DBDictionary::GuarInt             );
-    ascribe("NaarDiscount"        , &DBDictionary::NaarDiscount        );
-    ascribe("GuarIntSpread"       , &DBDictionary::GuarIntSpread       );
-    ascribe("GuarMandE"           , &DBDictionary::GuarMandE           );
-    ascribe("CurrIntSpread"       , &DBDictionary::CurrIntSpread       );
-    ascribe("CurrMandE"           , &DBDictionary::CurrMandE           );
-    ascribe("GenAcctIntBonus"     , &DBDictionary::GenAcctIntBonus     );
-    ascribe("BonusInt"            , &DBDictionary::BonusInt            );
-    ascribe("IntFloor"            , &DBDictionary::IntFloor            );
-    ascribe("AllowGenAcct"        , &DBDictionary::AllowGenAcct        );
-    ascribe("AllowSepAcct"        , &DBDictionary::AllowSepAcct        );
-    ascribe("AllowGenAcctEarnRate", &DBDictionary::AllowGenAcctEarnRate);
-    ascribe("AllowSepAcctNetRate" , &DBDictionary::AllowSepAcctNetRate );
-    ascribe("MaxGenAcctRate"      , &DBDictionary::MaxGenAcctRate      );
-    ascribe("MaxSepAcctRate"      , &DBDictionary::MaxSepAcctRate      );
-    ascribe("SepAcctSpreadMethod" , &DBDictionary::SepAcctSpreadMethod );
-    ascribe("IntSpreadMode"       , &DBDictionary::IntSpreadMode       );
-    ascribe("DynamicMandE"        , &DBDictionary::DynamicMandE        );
-    ascribe("AllowAmortPremLoad"  , &DBDictionary::AllowAmortPremLoad  );
-    ascribe("LoadAmortFundCharge" , &DBDictionary::LoadAmortFundCharge );
-    ascribe("AllowImfOverride"    , &DBDictionary::AllowImfOverride    );
-    ascribe("AssetChargeType"     , &DBDictionary::AssetChargeType     );
-    ascribe("StableValFundCharge" , &DBDictionary::StableValFundCharge );
-    ascribe("GuarFundAdminChg"    , &DBDictionary::GuarFundAdminChg    );
-    ascribe("CurrFundAdminChg"    , &DBDictionary::CurrFundAdminChg    );
-    ascribe("FundCharge"          , &DBDictionary::FundCharge          );
-    ascribe("GuarMonthlyPolFee"   , &DBDictionary::GuarMonthlyPolFee   );
-    ascribe("GuarAnnualPolFee"    , &DBDictionary::GuarAnnualPolFee    );
-    ascribe("GuarPremLoadTgt"     , &DBDictionary::GuarPremLoadTgt     );
-    ascribe("GuarPremLoadExc"     , &DBDictionary::GuarPremLoadExc     );
-    ascribe("GuarPremLoadTgtRfd"  , &DBDictionary::GuarPremLoadTgtRfd  );
-    ascribe("GuarPremLoadExcRfd"  , &DBDictionary::GuarPremLoadExcRfd  );
-    ascribe("GuarSpecAmtLoad"     , &DBDictionary::GuarSpecAmtLoad     );
-    ascribe("GuarSpecAmtLoadTable", &DBDictionary::GuarSpecAmtLoadTable);
-    ascribe("GuarAcctValLoad"     , &DBDictionary::GuarAcctValLoad     );
-    ascribe("CurrMonthlyPolFee"   , &DBDictionary::CurrMonthlyPolFee   );
-    ascribe("CurrAnnualPolFee"    , &DBDictionary::CurrAnnualPolFee    );
-    ascribe("CurrPremLoadTgt"     , &DBDictionary::CurrPremLoadTgt     );
-    ascribe("CurrPremLoadExc"     , &DBDictionary::CurrPremLoadExc     );
-    ascribe("CurrPremLoadTgtRfd"  , &DBDictionary::CurrPremLoadTgtRfd  );
-    ascribe("CurrPremLoadExcRfd"  , &DBDictionary::CurrPremLoadExcRfd  );
-    ascribe("CurrSpecAmtLoad"     , &DBDictionary::CurrSpecAmtLoad     );
-    ascribe("CurrSpecAmtLoadTable", &DBDictionary::CurrSpecAmtLoadTable);
-    ascribe("CurrAcctValLoad"     , &DBDictionary::CurrAcctValLoad     );
-    ascribe("TgtPremMonthlyPolFee", &DBDictionary::TgtPremMonthlyPolFee);
-    ascribe("LoadRfdProportion"   , &DBDictionary::LoadRfdProportion   );
-    ascribe("SpecAmtLoadLimit"    , &DBDictionary::SpecAmtLoadLimit    );
-    ascribe("DynamicSepAcctLoad"  , &DBDictionary::DynamicSepAcctLoad  );
-    ascribe("DynSepAcctLoadLimit" , &DBDictionary::DynSepAcctLoadLimit );
-    ascribe("DacTaxFundCharge"    , &DBDictionary::DacTaxFundCharge    );
-    ascribe("DacTaxPremLoad"      , &DBDictionary::DacTaxPremLoad      );
-    ascribe("PremTaxFundCharge"   , &DBDictionary::PremTaxFundCharge   );
-    ascribe("PremTaxLoad"         , &DBDictionary::PremTaxLoad         );
-    ascribe("WaivePremTaxInt1035" , &DBDictionary::WaivePremTaxInt1035 );
-    ascribe("PremTaxRetalLimit"   , &DBDictionary::PremTaxRetalLimit   );
-    ascribe("PremTaxTierGroup"    , &DBDictionary::PremTaxTierGroup    );
-    ascribe("PremTaxTierPeriod"   , &DBDictionary::PremTaxTierPeriod   );
-    ascribe("PremTaxTierNonDecr"  , &DBDictionary::PremTaxTierNonDecr  );
-    ascribe("PremTaxAmortPeriod"  , &DBDictionary::PremTaxAmortPeriod  );
-    ascribe("PremTaxAmortIntRate" , &DBDictionary::PremTaxAmortIntRate );
-    ascribe("PremTaxRate"         , &DBDictionary::PremTaxRate         );
-    ascribe("PremTaxState"        , &DBDictionary::PremTaxState        );
-    ascribe("SurrChgOnIncr"       , &DBDictionary::SurrChgOnIncr       );
-    ascribe("SurrChgOnDecr"       , &DBDictionary::SurrChgOnDecr       );
-    ascribe("Has1035ExchCharge"   , &DBDictionary::Has1035ExchCharge   );
-    ascribe("SnflQTable"          , &DBDictionary::SnflQTable          );
-    ascribe("CoiSnflIsGuar"       , &DBDictionary::CoiSnflIsGuar       );
-    ascribe("SurrChgByFormula"    , &DBDictionary::SurrChgByFormula    );
-    ascribe("SurrChgPeriod"       , &DBDictionary::SurrChgPeriod       );
-    ascribe("SurrChgZeroDur"      , &DBDictionary::SurrChgZeroDur      );
-    ascribe("SurrChgNlpMult"      , &DBDictionary::SurrChgNlpMult      );
-    ascribe("SurrChgNlpMax"       , &DBDictionary::SurrChgNlpMax       );
-    ascribe("SurrChgEaMax"        , &DBDictionary::SurrChgEaMax        );
-    ascribe("SurrChgAmort"        , &DBDictionary::SurrChgAmort        );
-    ascribe("AllowSpecAmtIncr"    , &DBDictionary::AllowSpecAmtIncr    );
-    ascribe("MinSpecAmtIncr"      , &DBDictionary::MinSpecAmtIncr      );
-    ascribe("EnforceNaarLimit"    , &DBDictionary::EnforceNaarLimit    );
-    ascribe("MinSpecAmt"          , &DBDictionary::MinSpecAmt          );
-    ascribe("MinIssSpecAmt"       , &DBDictionary::MinIssSpecAmt       );
-    ascribe("MinIssBaseSpecAmt"   , &DBDictionary::MinIssBaseSpecAmt   );
-    ascribe("MinRenlSpecAmt"      , &DBDictionary::MinRenlSpecAmt      );
-    ascribe("MinRenlBaseSpecAmt"  , &DBDictionary::MinRenlBaseSpecAmt  );
-    ascribe("MaxIssSpecAmt"       , &DBDictionary::MaxIssSpecAmt       );
-    ascribe("MaxRenlSpecAmt"      , &DBDictionary::MaxRenlSpecAmt      );
-    ascribe("AllowDboLvl"         , &DBDictionary::AllowDboLvl         );
-    ascribe("AllowDboInc"         , &DBDictionary::AllowDboInc         );
-    ascribe("AllowDboRop"         , &DBDictionary::AllowDboRop         );
-    ascribe("AllowDboMdb"         , &DBDictionary::AllowDboMdb         );
-    ascribe("DboLvlChangeToWhat"  , &DBDictionary::DboLvlChangeToWhat  );
-    ascribe("DboLvlChangeMethod"  , &DBDictionary::DboLvlChangeMethod  );
-    ascribe("DboIncChangeToWhat"  , &DBDictionary::DboIncChangeToWhat  );
-    ascribe("DboIncChangeMethod"  , &DBDictionary::DboIncChangeMethod  );
-    ascribe("DboRopChangeToWhat"  , &DBDictionary::DboRopChangeToWhat  );
-    ascribe("DboRopChangeMethod"  , &DBDictionary::DboRopChangeMethod  );
-    ascribe("DboMdbChangeToWhat"  , &DBDictionary::DboMdbChangeToWhat  );
-    ascribe("DboMdbChangeMethod"  , &DBDictionary::DboMdbChangeMethod  );
-    ascribe("AllowChangeToDbo2"   , &DBDictionary::AllowChangeToDbo2   );
-    ascribe("DboChgCanIncrSpecAmt", &DBDictionary::DboChgCanIncrSpecAmt);
-    ascribe("DboChgCanDecrSpecAmt", &DBDictionary::DboChgCanDecrSpecAmt);
-    ascribe("AllowExtEndt"        , &DBDictionary::AllowExtEndt        );
-    ascribe("AllowTerm"           , &DBDictionary::AllowTerm           );
-    ascribe("GuarTermTable"       , &DBDictionary::GuarTermTable       );
-    ascribe("TermTable"           , &DBDictionary::TermTable           );
-    ascribe("TermMinIssAge"       , &DBDictionary::TermMinIssAge       );
-    ascribe("TermMaxIssAge"       , &DBDictionary::TermMaxIssAge       );
-    ascribe("TermIsNotRider"      , &DBDictionary::TermIsNotRider      );
-    ascribe("TermCanLapse"        , &DBDictionary::TermCanLapse        );
-    ascribe("TermForcedConvAge"   , &DBDictionary::TermForcedConvAge   );
-    ascribe("TermForcedConvDur"   , &DBDictionary::TermForcedConvDur   );
-    ascribe("MaxTermProportion"   , &DBDictionary::MaxTermProportion   );
-    ascribe("TermCoiRate"         , &DBDictionary::TermCoiRate         );
-    ascribe("TermPremRate"        , &DBDictionary::TermPremRate        );
-    ascribe("AllowWp"             , &DBDictionary::AllowWp             );
-    ascribe("WpTable"             , &DBDictionary::WpTable             );
-    ascribe("WpMinIssAge"         , &DBDictionary::WpMinIssAge         );
-    ascribe("WpMaxIssAge"         , &DBDictionary::WpMaxIssAge         );
-    ascribe("WpLimit"             , &DBDictionary::WpLimit             );
-    ascribe("WpCoiRate"           , &DBDictionary::WpCoiRate           );
-    ascribe("WpPremRate"          , &DBDictionary::WpPremRate          );
-    ascribe("WpChargeMethod"      , &DBDictionary::WpChargeMethod      );
-    ascribe("AllowAdb"            , &DBDictionary::AllowAdb            );
-    ascribe("AdbTable"            , &DBDictionary::AdbTable            );
-    ascribe("AdbMinIssAge"        , &DBDictionary::AdbMinIssAge        );
-    ascribe("AdbMaxIssAge"        , &DBDictionary::AdbMaxIssAge        );
-    ascribe("AdbLimit"            , &DBDictionary::AdbLimit            );
-    ascribe("AdbCoiRate"          , &DBDictionary::AdbCoiRate          );
-    ascribe("AdbPremRate"         , &DBDictionary::AdbPremRate         );
-    ascribe("AllowSpouseRider"    , &DBDictionary::AllowSpouseRider    );
-    ascribe("SpouseRiderMinAmt"   , &DBDictionary::SpouseRiderMinAmt   );
-    ascribe("SpouseRiderMaxAmt"   , &DBDictionary::SpouseRiderMaxAmt   );
-    ascribe("SpouseRiderMinIssAge", &DBDictionary::SpouseRiderMinIssAge);
-    ascribe("SpouseRiderMaxIssAge", &DBDictionary::SpouseRiderMaxIssAge);
-    ascribe("SpouseRiderGuarTable", &DBDictionary::SpouseRiderGuarTable);
-    ascribe("SpouseRiderTable"    , &DBDictionary::SpouseRiderTable    );
-    ascribe("AllowChildRider"     , &DBDictionary::AllowChildRider     );
-    ascribe("ChildRiderMinAmt"    , &DBDictionary::ChildRiderMinAmt    );
-    ascribe("ChildRiderMaxAmt"    , &DBDictionary::ChildRiderMaxAmt    );
-    ascribe("ChildRiderTable"     , &DBDictionary::ChildRiderTable     );
-    ascribe("AllowWd"             , &DBDictionary::AllowWd             );
-    ascribe("WdFee"               , &DBDictionary::WdFee               );
-    ascribe("WdFeeRate"           , &DBDictionary::WdFeeRate           );
-    ascribe("FreeWdProportion"    , &DBDictionary::FreeWdProportion    );
-    ascribe("MinWd"               , &DBDictionary::MinWd               );
-    ascribe("MaxWdGenAcctValMult" , &DBDictionary::MaxWdGenAcctValMult );
-    ascribe("MaxWdSepAcctValMult" , &DBDictionary::MaxWdSepAcctValMult );
-    ascribe("MaxWdDed"            , &DBDictionary::MaxWdDed            );
-    ascribe("WdDecrSpecAmtDboLvl" , &DBDictionary::WdDecrSpecAmtDboLvl );
-    ascribe("WdDecrSpecAmtDboInc" , &DBDictionary::WdDecrSpecAmtDboInc );
-    ascribe("WdDecrSpecAmtDboRop" , &DBDictionary::WdDecrSpecAmtDboRop );
-    ascribe("FirstWdMonth"        , &DBDictionary::FirstWdMonth        );
-    ascribe("AllowLoan"           , &DBDictionary::AllowLoan           );
-    ascribe("AllowPrefLoan"       , &DBDictionary::AllowPrefLoan       );
-    ascribe("AllowFixedLoan"      , &DBDictionary::AllowFixedLoan      );
-    ascribe("AllowVlr"            , &DBDictionary::AllowVlr            );
-    ascribe("FixedLoanRate"       , &DBDictionary::FixedLoanRate       );
-    ascribe("MaxVlrRate"          , &DBDictionary::MaxVlrRate          );
-    ascribe("MinVlrRate"          , &DBDictionary::MinVlrRate          );
-    ascribe("MaxLoanAcctValMult"  , &DBDictionary::MaxLoanAcctValMult  );
-    ascribe("MaxLoanDed"          , &DBDictionary::MaxLoanDed          );
-    ascribe("FirstPrefLoanYear"   , &DBDictionary::FirstPrefLoanYear   );
-    ascribe("PrefLoanRateDecr"    , &DBDictionary::PrefLoanRateDecr    );
-    ascribe("GuarPrefLoanSpread"  , &DBDictionary::GuarPrefLoanSpread  );
-    ascribe("GuarRegLoanSpread"   , &DBDictionary::GuarRegLoanSpread   );
-    ascribe("CurrPrefLoanSpread"  , &DBDictionary::CurrPrefLoanSpread  );
-    ascribe("CurrRegLoanSpread"   , &DBDictionary::CurrRegLoanSpread   );
-    ascribe("FirstLoanMonth"      , &DBDictionary::FirstLoanMonth      );
-    ascribe("MinPremType"         , &DBDictionary::MinPremType         );
-    ascribe("MinPremTable"        , &DBDictionary::MinPremTable        );
-    ascribe("MinPremIntSpread"    , &DBDictionary::MinPremIntSpread    );
-    ascribe("SplitMinPrem"        , &DBDictionary::SplitMinPrem        );
-    ascribe("UnsplitSplitMinPrem" , &DBDictionary::UnsplitSplitMinPrem );
-    ascribe("ErNotionallyPaysTerm", &DBDictionary::ErNotionallyPaysTerm);
-    ascribe("TgtPremType"         , &DBDictionary::TgtPremType         );
-    ascribe("TgtPremTable"        , &DBDictionary::TgtPremTable        );
-    ascribe("TgtPremFixedAtIssue" , &DBDictionary::TgtPremFixedAtIssue );
-    ascribe("TgtPremIgnoreSubstd" , &DBDictionary::TgtPremIgnoreSubstd );
-    ascribe("MinPmt"              , &DBDictionary::MinPmt              );
-    ascribe("IsSinglePremium"     , &DBDictionary::IsSinglePremium     );
-    ascribe("NoLapseMinDur"       , &DBDictionary::NoLapseMinDur       );
-    ascribe("NoLapseMinAge"       , &DBDictionary::NoLapseMinAge       );
-    ascribe("NoLapseUnratedOnly"  , &DBDictionary::NoLapseUnratedOnly  );
-    ascribe("NoLapseDboLvlOnly"   , &DBDictionary::NoLapseDboLvlOnly   );
-    ascribe("NoLapseAlwaysActive" , &DBDictionary::NoLapseAlwaysActive );
-    ascribe("AllowHoneymoon"      , &DBDictionary::AllowHoneymoon      );
-    ascribe("DeductionMethod"     , &DBDictionary::DeductionMethod     );
-    ascribe("DeductionAcct"       , &DBDictionary::DeductionAcct       );
-    ascribe("DistributionMethod"  , &DBDictionary::DistributionMethod  );
-    ascribe("DistributionAcct"    , &DBDictionary::DistributionAcct    );
-    ascribe("EePremMethod"        , &DBDictionary::EePremMethod        );
-    ascribe("EePremAcct"          , &DBDictionary::EePremAcct          );
-    ascribe("ErPremMethod"        , &DBDictionary::ErPremMethod        );
-    ascribe("ErPremAcct"          , &DBDictionary::ErPremAcct          );
-    ascribe("CalculateComp"       , &DBDictionary::CalculateComp       );
-    ascribe("CompTarget"          , &DBDictionary::CompTarget          );
-    ascribe("CompExcess"          , &DBDictionary::CompExcess          );
-    ascribe("CompChargeback"      , &DBDictionary::CompChargeback      );
-    ascribe("AssetComp"           , &DBDictionary::AssetComp           );
-    ascribe("AllowExtraAssetComp" , &DBDictionary::AllowExtraAssetComp );
-    ascribe("AllowExtraPremComp"  , &DBDictionary::AllowExtraPremComp  );
-    ascribe("AllowExpRating"      , &DBDictionary::AllowExpRating      );
-    ascribe("ExpRatStdDevMult"    , &DBDictionary::ExpRatStdDevMult    );
-    ascribe("ExpRatIbnrMult"      , &DBDictionary::ExpRatIbnrMult      );
-    ascribe("ExpRatCoiRetention"  , &DBDictionary::ExpRatCoiRetention  );
-    ascribe("ExpRatRiskCoiMult"   , &DBDictionary::ExpRatRiskCoiMult   );
-    ascribe("ExpRatAmortPeriod"   , &DBDictionary::ExpRatAmortPeriod   );
-    ascribe("LedgerType"          , &DBDictionary::LedgerType          );
-    ascribe("Nonillustrated"      , &DBDictionary::Nonillustrated      );
-    ascribe("NoLongerIssued"      , &DBDictionary::NoLongerIssued      );
-    ascribe("AgeLastOrNearest"    , &DBDictionary::AgeLastOrNearest    );
-    ascribe("MaturityAge"         , &DBDictionary::MaturityAge         );
-    ascribe("CashValueEnhMult"    , &DBDictionary::CashValueEnhMult    );
-    ascribe("LapseIgnoresSurrChg" , &DBDictionary::LapseIgnoresSurrChg );
-    ascribe("DefaultProcessOrder" , &DBDictionary::DefaultProcessOrder );
-    ascribe("GroupProxyRateTable" , &DBDictionary::GroupProxyRateTable );
-    ascribe("PartialMortTable"    , &DBDictionary::PartialMortTable    );
-    ascribe("UsePolicyFormAlt"    , &DBDictionary::UsePolicyFormAlt    );
-    ascribe("AllowGroupQuote"     , &DBDictionary::AllowGroupQuote     );
-    ascribe("WeightClass"         , &DBDictionary::WeightClass         );
-    ascribe("WeightGender"        , &DBDictionary::WeightGender        );
-    ascribe("WeightSmoking"       , &DBDictionary::WeightSmoking       );
-    ascribe("WeightAge"           , &DBDictionary::WeightAge           );
-    ascribe("WeightSpecAmt"       , &DBDictionary::WeightSpecAmt       );
-    ascribe("WeightState"         , &DBDictionary::WeightState         );
-    ascribe("FullExpPol"          , &DBDictionary::FullExpPol          );
-    ascribe("FullExpPrem"         , &DBDictionary::FullExpPrem         );
-    ascribe("FullExpDumpin"       , &DBDictionary::FullExpDumpin       );
-    ascribe("FullExpSpecAmt"      , &DBDictionary::FullExpSpecAmt      );
-    ascribe("VarExpPol"           , &DBDictionary::VarExpPol           );
-    ascribe("VarExpPrem"          , &DBDictionary::VarExpPrem          );
-    ascribe("VarExpDumpin"        , &DBDictionary::VarExpDumpin        );
-    ascribe("VarExpSpecAmt"       , &DBDictionary::VarExpSpecAmt       );
-    ascribe("ExpSpecAmtLimit"     , &DBDictionary::ExpSpecAmtLimit     );
-    ascribe("MedicalProportion"   , &DBDictionary::MedicalProportion   );
-    ascribe("UwTestCost"          , &DBDictionary::UwTestCost          );
-    ascribe("VxBasicQTable"       , &DBDictionary::VxBasicQTable       );
-    ascribe("VxDeficQTable"       , &DBDictionary::VxDeficQTable       );
-    ascribe("VxTaxQTable"         , &DBDictionary::VxTaxQTable         );
-    ascribe("StatVxInt"           , &DBDictionary::StatVxInt           );
-    ascribe("TaxVxInt"            , &DBDictionary::TaxVxInt            );
-    ascribe("StatVxQ"             , &DBDictionary::StatVxQ             );
-    ascribe("TaxVxQ"              , &DBDictionary::TaxVxQ              );
-    ascribe("DeficVxQ"            , &DBDictionary::DeficVxQ            );
-    ascribe("SnflQ"               , &DBDictionary::SnflQ               );
-    ascribe("LapseRate"           , &DBDictionary::LapseRate           );
-    ascribe("ReqSurpNaar"         , &DBDictionary::ReqSurpNaar         );
-    ascribe("ReqSurpVx"           , &DBDictionary::ReqSurpVx           );
-    ascribe("LicFitRate"          , &DBDictionary::LicFitRate          );
-    ascribe("LicDacTaxRate"       , &DBDictionary::LicDacTaxRate       );
-    ascribe("GdbVxMethod"         , &DBDictionary::GdbVxMethod         );
-    ascribe("PrimaryHurdle"       , &DBDictionary::PrimaryHurdle       );
-    ascribe("SecondaryHurdle"     , &DBDictionary::SecondaryHurdle     );
+    ascribe("MinIssAge"                 , &DBDictionary::MinIssAge             
    );
+    ascribe("MaxIssAge"                 , &DBDictionary::MaxIssAge             
    );
+    ascribe("MaxIncrAge"                , &DBDictionary::MaxIncrAge            
    );
+    ascribe("AllowFullUw"               , &DBDictionary::AllowFullUw           
    );
+    ascribe("AllowParamedUw"            , &DBDictionary::AllowParamedUw        
    );
+    ascribe("AllowNonmedUw"             , &DBDictionary::AllowNonmedUw         
    );
+    ascribe("AllowSimpUw"               , &DBDictionary::AllowSimpUw           
    );
+    ascribe("AllowGuarUw"               , &DBDictionary::AllowGuarUw           
    );
+    ascribe("SmokeOrTobacco"            , &DBDictionary::SmokeOrTobacco        
    );
+    ascribe("AllowPreferredClass"       , &DBDictionary::AllowPreferredClass   
    );
+    ascribe("AllowUltraPrefClass"       , &DBDictionary::AllowUltraPrefClass   
    );
+    ascribe("AllowSubstdTable"          , &DBDictionary::AllowSubstdTable      
    );
+    ascribe("AllowFlatExtras"           , &DBDictionary::AllowFlatExtras       
    );
+    ascribe("AllowRatedWp"              , &DBDictionary::AllowRatedWp          
    );
+    ascribe("AllowRatedAdb"             , &DBDictionary::AllowRatedAdb         
    );
+    ascribe("AllowRatedTerm"            , &DBDictionary::AllowRatedTerm        
    );
+    ascribe("AllowRetirees"             , &DBDictionary::AllowRetirees         
    );
+    ascribe("AllowUnisex"               , &DBDictionary::AllowUnisex           
    );
+    ascribe("AllowSexDistinct"          , &DBDictionary::AllowSexDistinct      
    );
+    ascribe("AllowUnismoke"             , &DBDictionary::AllowUnismoke         
    );
+    ascribe("AllowSmokeDistinct"        , &DBDictionary::AllowSmokeDistinct    
    );
+    ascribe("StateApproved"             , &DBDictionary::StateApproved         
    );
+    ascribe("AllowStateXX"              , &DBDictionary::AllowStateXX          
    );
+    ascribe("AllowForeign"              , &DBDictionary::AllowForeign          
    );
+    ascribe("GroupIndivSelection"       , &DBDictionary::GroupIndivSelection   
    );
+    ascribe("TxCallsGuarUwSubstd"       , &DBDictionary::TxCallsGuarUwSubstd   
    );
+    ascribe("Allowable"                 , &DBDictionary::Allowable             
    );
+    ascribe("AllowCvat"                 , &DBDictionary::AllowCvat             
    );
+    ascribe("AllowGpt"                  , &DBDictionary::AllowGpt              
    );
+    ascribe("AllowNo7702"               , &DBDictionary::AllowNo7702           
    );
+    ascribe("Irc7702Obreption"          , &DBDictionary::Irc7702Obreption      
    );
+    ascribe("CorridorWhence"            , &DBDictionary::CorridorWhence        
    );
+    ascribe("Irc7702NspWhence"          , &DBDictionary::Irc7702NspWhence      
    );
+    ascribe("SevenPayWhence"            , &DBDictionary::SevenPayWhence        
    );
+    ascribe("Irc7702QWhence"            , &DBDictionary::Irc7702QWhence        
    );
+    ascribe("CorridorTable"             , &DBDictionary::CorridorTable         
    );
+    ascribe("Irc7702NspTable"           , &DBDictionary::Irc7702NspTable       
    );
+    ascribe("SevenPayTable"             , &DBDictionary::SevenPayTable         
    );
+    ascribe("Irc7702QTable"             , &DBDictionary::Irc7702QTable         
    );
+    ascribe("Irc7702QAxisGender"        , &DBDictionary::Irc7702QAxisGender    
    );
+    ascribe("Irc7702QAxisSmoking"       , &DBDictionary::Irc7702QAxisSmoking   
    );
+    ascribe("RatingsAffect7702"         , &DBDictionary::RatingsAffect7702     
    );
+    ascribe("CvatMatChangeDefn"         , &DBDictionary::CvatMatChangeDefn     
    );
+    ascribe("GptMatChangeDefn"          , &DBDictionary::GptMatChangeDefn      
    );
+    ascribe("Irc7702BftIsSpecAmt"       , &DBDictionary::Irc7702BftIsSpecAmt   
    );
+    ascribe("RiskyInitial7702Db"        , &DBDictionary::RiskyInitial7702Db    
    );
+    ascribe("Irc7702Endowment"          , &DBDictionary::Irc7702Endowment      
    );
+    ascribe("Effective7702DboRop"       , &DBDictionary::Effective7702DboRop   
    );
+    ascribe("TermIsQABOrDb7702"         , &DBDictionary::TermIsQABOrDb7702     
    );
+    ascribe("TermIsQABOrDb7702A"        , &DBDictionary::TermIsQABOrDb7702A    
    );
+    ascribe("GioIsQAB"                  , &DBDictionary::GioIsQAB              
    );
+    ascribe("AdbIsQAB"                  , &DBDictionary::AdbIsQAB              
    );
+    ascribe("SpouseRiderIsQAB"          , &DBDictionary::SpouseRiderIsQAB      
    );
+    ascribe("ChildRiderIsQAB"           , &DBDictionary::ChildRiderIsQAB       
    );
+    ascribe("WpIsQAB"                   , &DBDictionary::WpIsQAB               
    );
+    ascribe("CsoEra"                    , &DBDictionary::CsoEra                
    );
+    ascribe("CsoMisprint"               , &DBDictionary::CsoMisprint           
    );
+    ascribe("GuarCoiWhence"             , &DBDictionary::GuarCoiWhence         
    );
+    ascribe("GuarCoiTable"              , &DBDictionary::GuarCoiTable          
    );
+    ascribe("GuarCoiIsAnnual"           , &DBDictionary::GuarCoiIsAnnual       
    );
+    ascribe("GuarCoiMultiplier"         , &DBDictionary::GuarCoiMultiplier     
    );
+    ascribe("CurrCoiTable"              , &DBDictionary::CurrCoiTable          
    );
+    ascribe("CurrCoiIsAnnual"           , &DBDictionary::CurrCoiIsAnnual       
    );
+    ascribe("MinInputCoiMult"           , &DBDictionary::MinInputCoiMult       
    );
+    ascribe("CurrCoiMultiplier"         , &DBDictionary::CurrCoiMultiplier     
    );
+    ascribe("UnusualCoiBanding"         , &DBDictionary::UnusualCoiBanding     
    );
+    ascribe("CurrCoiTable0Limit"        , &DBDictionary::CurrCoiTable0Limit    
    );
+    ascribe("CurrCoiTable1"             , &DBDictionary::CurrCoiTable1         
    );
+    ascribe("CurrCoiTable1Limit"        , &DBDictionary::CurrCoiTable1Limit    
    );
+    ascribe("CurrCoiTable2"             , &DBDictionary::CurrCoiTable2         
    );
+    ascribe("MdptCoiTable"              , &DBDictionary::MdptCoiTable          
    );
+    ascribe("MdptCoiIsAnnual"           , &DBDictionary::MdptCoiIsAnnual       
    );
+    ascribe("CoiNyMinTable"             , &DBDictionary::CoiNyMinTable         
    );
+    ascribe("UseNyCoiFloor"             , &DBDictionary::UseNyCoiFloor         
    );
+    ascribe("MaxMonthlyCoiRate"         , &DBDictionary::MaxMonthlyCoiRate     
    );
+    ascribe("GuarCoiCeiling"            , &DBDictionary::GuarCoiCeiling        
    );
+    ascribe("CoiGuarIsMin"              , &DBDictionary::CoiGuarIsMin          
    );
+    ascribe("SubstdTableMult"           , &DBDictionary::SubstdTableMult       
    );
+    ascribe("SubstdTableMultTable"      , &DBDictionary::SubstdTableMultTable  
    );
+    ascribe("CoiUpper12Method"          , &DBDictionary::CoiUpper12Method      
    );
+    ascribe("CoiInforceReentry"         , &DBDictionary::CoiInforceReentry     
    );
+    ascribe("CoiResetMinDate"           , &DBDictionary::CoiResetMinDate       
    );
+    ascribe("CoiResetMaxDate"           , &DBDictionary::CoiResetMaxDate       
    );
+    ascribe("AllowMortBlendSex"         , &DBDictionary::AllowMortBlendSex     
    );
+    ascribe("AllowMortBlendSmoke"       , &DBDictionary::AllowMortBlendSmoke   
    );
+    ascribe("GuarInt"                   , &DBDictionary::GuarInt               
    );
+    ascribe("NaarDiscount"              , &DBDictionary::NaarDiscount          
    );
+    ascribe("GuarIntSpread"             , &DBDictionary::GuarIntSpread         
    );
+    ascribe("GuarMandE"                 , &DBDictionary::GuarMandE             
    );
+    ascribe("CurrIntSpread"             , &DBDictionary::CurrIntSpread         
    );
+    ascribe("CurrMandE"                 , &DBDictionary::CurrMandE             
    );
+    ascribe("GenAcctIntBonus"           , &DBDictionary::GenAcctIntBonus       
    );
+    ascribe("BonusInt"                  , &DBDictionary::BonusInt              
    );
+    ascribe("IntFloor"                  , &DBDictionary::IntFloor              
    );
+    ascribe("AllowGenAcct"              , &DBDictionary::AllowGenAcct          
    );
+    ascribe("AllowSepAcct"              , &DBDictionary::AllowSepAcct          
    );
+    ascribe("AllowGenAcctEarnRate"      , &DBDictionary::AllowGenAcctEarnRate  
    );
+    ascribe("AllowSepAcctNetRate"       , &DBDictionary::AllowSepAcctNetRate   
    );
+    ascribe("MaxGenAcctRate"            , &DBDictionary::MaxGenAcctRate        
    );
+    ascribe("MaxSepAcctRate"            , &DBDictionary::MaxSepAcctRate        
    );
+    ascribe("SepAcctSpreadMethod"       , &DBDictionary::SepAcctSpreadMethod   
    );
+    ascribe("IntSpreadMode"             , &DBDictionary::IntSpreadMode         
    );
+    ascribe("DynamicMandE"              , &DBDictionary::DynamicMandE          
    );
+    ascribe("AllowAmortPremLoad"        , &DBDictionary::AllowAmortPremLoad    
    );
+    ascribe("LoadAmortFundCharge"       , &DBDictionary::LoadAmortFundCharge   
    );
+    ascribe("AllowImfOverride"          , &DBDictionary::AllowImfOverride      
    );
+    ascribe("AssetChargeType"           , &DBDictionary::AssetChargeType       
    );
+    ascribe("StableValFundCharge"       , &DBDictionary::StableValFundCharge   
    );
+    ascribe("GuarFundAdminChg"          , &DBDictionary::GuarFundAdminChg      
    );
+    ascribe("CurrFundAdminChg"          , &DBDictionary::CurrFundAdminChg      
    );
+    ascribe("FundCharge"                , &DBDictionary::FundCharge            
    );
+    ascribe("GuarMonthlyPolFee"         , &DBDictionary::GuarMonthlyPolFee     
    );
+    ascribe("GuarAnnualPolFee"          , &DBDictionary::GuarAnnualPolFee      
    );
+    ascribe("GuarPremLoadTgt"           , &DBDictionary::GuarPremLoadTgt       
    );
+    ascribe("GuarPremLoadExc"           , &DBDictionary::GuarPremLoadExc       
    );
+    ascribe("GuarPremLoadTgtRfd"        , &DBDictionary::GuarPremLoadTgtRfd    
    );
+    ascribe("GuarPremLoadExcRfd"        , &DBDictionary::GuarPremLoadExcRfd    
    );
+    ascribe("GuarSpecAmtLoad"           , &DBDictionary::GuarSpecAmtLoad       
    );
+    ascribe("GuarSpecAmtLoadTable"      , &DBDictionary::GuarSpecAmtLoadTable  
    );
+    ascribe("GuarAcctValLoad"           , &DBDictionary::GuarAcctValLoad       
    );
+    ascribe("CurrMonthlyPolFee"         , &DBDictionary::CurrMonthlyPolFee     
    );
+    ascribe("CurrAnnualPolFee"          , &DBDictionary::CurrAnnualPolFee      
    );
+    ascribe("CurrPremLoadTgt"           , &DBDictionary::CurrPremLoadTgt       
    );
+    ascribe("CurrPremLoadExc"           , &DBDictionary::CurrPremLoadExc       
    );
+    ascribe("CurrPremLoadTgtRfd"        , &DBDictionary::CurrPremLoadTgtRfd    
    );
+    ascribe("CurrPremLoadExcRfd"        , &DBDictionary::CurrPremLoadExcRfd    
    );
+    ascribe("CurrSpecAmtLoad"           , &DBDictionary::CurrSpecAmtLoad       
    );
+    ascribe("CurrSpecAmtLoadTable"      , &DBDictionary::CurrSpecAmtLoadTable  
    );
+    ascribe("CurrAcctValLoad"           , &DBDictionary::CurrAcctValLoad       
    );
+    ascribe("TgtPremMonthlyPolFee"      , &DBDictionary::TgtPremMonthlyPolFee  
    );
+    ascribe("LoadRfdProportion"         , &DBDictionary::LoadRfdProportion     
    );
+    ascribe("SpecAmtLoadLimit"          , &DBDictionary::SpecAmtLoadLimit      
    );
+    ascribe("DynamicSepAcctLoad"        , &DBDictionary::DynamicSepAcctLoad    
    );
+    ascribe("DynSepAcctLoadLimit"       , &DBDictionary::DynSepAcctLoadLimit   
    );
+    ascribe("DacTaxFundCharge"          , &DBDictionary::DacTaxFundCharge      
    );
+    ascribe("DacTaxPremLoad"            , &DBDictionary::DacTaxPremLoad        
    );
+    ascribe("PremTaxFundCharge"         , &DBDictionary::PremTaxFundCharge     
    );
+    ascribe("PremTaxLoad"               , &DBDictionary::PremTaxLoad           
    );
+    ascribe("WaivePremTaxInt1035"       , &DBDictionary::WaivePremTaxInt1035   
    );
+    ascribe("PremTaxRetalLimit"         , &DBDictionary::PremTaxRetalLimit     
    );
+    ascribe("PremTaxTierGroup"          , &DBDictionary::PremTaxTierGroup      
    );
+    ascribe("PremTaxTierPeriod"         , &DBDictionary::PremTaxTierPeriod     
    );
+    ascribe("PremTaxTierNonDecr"        , &DBDictionary::PremTaxTierNonDecr    
    );
+    ascribe("PremTaxAmortPeriod"        , &DBDictionary::PremTaxAmortPeriod    
    );
+    ascribe("PremTaxAmortIntRate"       , &DBDictionary::PremTaxAmortIntRate   
    );
+    ascribe("PremTaxRate"               , &DBDictionary::PremTaxRate           
    );
+    ascribe("PremTaxState"              , &DBDictionary::PremTaxState          
    );
+    ascribe("SurrChgOnIncr"             , &DBDictionary::SurrChgOnIncr         
    );
+    ascribe("SurrChgOnDecr"             , &DBDictionary::SurrChgOnDecr         
    );
+    ascribe("Has1035ExchCharge"         , &DBDictionary::Has1035ExchCharge     
    );
+    ascribe("SnflQTable"                , &DBDictionary::SnflQTable            
    );
+    ascribe("CoiSnflIsGuar"             , &DBDictionary::CoiSnflIsGuar         
    );
+    ascribe("SurrChgByFormula"          , &DBDictionary::SurrChgByFormula      
    );
+    ascribe("SurrChgPeriod"             , &DBDictionary::SurrChgPeriod         
    );
+    ascribe("SurrChgZeroDur"            , &DBDictionary::SurrChgZeroDur        
    );
+    ascribe("SurrChgNlpMult"            , &DBDictionary::SurrChgNlpMult        
    );
+    ascribe("SurrChgNlpMax"             , &DBDictionary::SurrChgNlpMax         
    );
+    ascribe("SurrChgEaMax"              , &DBDictionary::SurrChgEaMax          
    );
+    ascribe("SurrChgAmort"              , &DBDictionary::SurrChgAmort          
    );
+    ascribe("AllowSpecAmtIncr"          , &DBDictionary::AllowSpecAmtIncr      
    );
+    ascribe("MinSpecAmtIncr"            , &DBDictionary::MinSpecAmtIncr        
    );
+    ascribe("EnforceNaarLimit"          , &DBDictionary::EnforceNaarLimit      
    );
+    ascribe("MinSpecAmt"                , &DBDictionary::MinSpecAmt            
    );
+    ascribe("MinIssSpecAmt"             , &DBDictionary::MinIssSpecAmt         
    );
+    ascribe("MinIssBaseSpecAmt"         , &DBDictionary::MinIssBaseSpecAmt     
    );
+    ascribe("MinRenlSpecAmt"            , &DBDictionary::MinRenlSpecAmt        
    );
+    ascribe("MinRenlBaseSpecAmt"        , &DBDictionary::MinRenlBaseSpecAmt    
    );
+    ascribe("MaxIssSpecAmt"             , &DBDictionary::MaxIssSpecAmt         
    );
+    ascribe("MaxRenlSpecAmt"            , &DBDictionary::MaxRenlSpecAmt        
    );
+    ascribe("AllowDboLvl"               , &DBDictionary::AllowDboLvl           
    );
+    ascribe("AllowDboInc"               , &DBDictionary::AllowDboInc           
    );
+    ascribe("AllowDboRop"               , &DBDictionary::AllowDboRop           
    );
+    ascribe("AllowDboMdb"               , &DBDictionary::AllowDboMdb           
    );
+    ascribe("DboLvlChangeToWhat"        , &DBDictionary::DboLvlChangeToWhat    
    );
+    ascribe("DboLvlChangeMethod"        , &DBDictionary::DboLvlChangeMethod    
    );
+    ascribe("DboIncChangeToWhat"        , &DBDictionary::DboIncChangeToWhat    
    );
+    ascribe("DboIncChangeMethod"        , &DBDictionary::DboIncChangeMethod    
    );
+    ascribe("DboRopChangeToWhat"        , &DBDictionary::DboRopChangeToWhat    
    );
+    ascribe("DboRopChangeMethod"        , &DBDictionary::DboRopChangeMethod    
    );
+    ascribe("DboMdbChangeToWhat"        , &DBDictionary::DboMdbChangeToWhat    
    );
+    ascribe("DboMdbChangeMethod"        , &DBDictionary::DboMdbChangeMethod    
    );
+    ascribe("AllowChangeToDbo2"         , &DBDictionary::AllowChangeToDbo2     
    );
+    ascribe("DboChgCanIncrSpecAmt"      , &DBDictionary::DboChgCanIncrSpecAmt  
    );
+    ascribe("DboChgCanDecrSpecAmt"      , &DBDictionary::DboChgCanDecrSpecAmt  
    );
+    ascribe("AllowExtEndt"              , &DBDictionary::AllowExtEndt          
    );
+    ascribe("AllowTerm"                 , &DBDictionary::AllowTerm             
    );
+    ascribe("GuarTermTable"             , &DBDictionary::GuarTermTable         
    );
+    ascribe("TermTable"                 , &DBDictionary::TermTable             
    );
+    ascribe("TermMinIssAge"             , &DBDictionary::TermMinIssAge         
    );
+    ascribe("TermMaxIssAge"             , &DBDictionary::TermMaxIssAge         
    );
+    ascribe("TermIsNotRider"            , &DBDictionary::TermIsNotRider        
    );
+    ascribe("TermCanLapse"              , &DBDictionary::TermCanLapse          
    );
+    ascribe("TermForcedConvAge"         , &DBDictionary::TermForcedConvAge     
    );
+    ascribe("TermForcedConvDur"         , &DBDictionary::TermForcedConvDur     
    );
+    ascribe("MaxTermProportion"         , &DBDictionary::MaxTermProportion     
    );
+    ascribe("TermCoiRate"               , &DBDictionary::TermCoiRate           
    );
+    ascribe("TermPremRate"              , &DBDictionary::TermPremRate          
    );
+    ascribe("AllowWp"                   , &DBDictionary::AllowWp               
    );
+    ascribe("WpTable"                   , &DBDictionary::WpTable               
    );
+    ascribe("WpMinIssAge"               , &DBDictionary::WpMinIssAge           
    );
+    ascribe("WpMaxIssAge"               , &DBDictionary::WpMaxIssAge           
    );
+    ascribe("WpLimit"                   , &DBDictionary::WpLimit               
    );
+    ascribe("WpCoiRate"                 , &DBDictionary::WpCoiRate             
    );
+    ascribe("WpPremRate"                , &DBDictionary::WpPremRate            
    );
+    ascribe("WpChargeMethod"            , &DBDictionary::WpChargeMethod        
    );
+    ascribe("AllowAdb"                  , &DBDictionary::AllowAdb              
    );
+    ascribe("AdbTable"                  , &DBDictionary::AdbTable              
    );
+    ascribe("AdbMinIssAge"              , &DBDictionary::AdbMinIssAge          
    );
+    ascribe("AdbMaxIssAge"              , &DBDictionary::AdbMaxIssAge          
    );
+    ascribe("AdbLimit"                  , &DBDictionary::AdbLimit              
    );
+    ascribe("AdbCoiRate"                , &DBDictionary::AdbCoiRate            
    );
+    ascribe("AdbPremRate"               , &DBDictionary::AdbPremRate           
    );
+    ascribe("AllowSpouseRider"          , &DBDictionary::AllowSpouseRider      
    );
+    ascribe("SpouseRiderMinAmt"         , &DBDictionary::SpouseRiderMinAmt     
    );
+    ascribe("SpouseRiderMaxAmt"         , &DBDictionary::SpouseRiderMaxAmt     
    );
+    ascribe("SpouseRiderMinIssAge"      , &DBDictionary::SpouseRiderMinIssAge  
    );
+    ascribe("SpouseRiderMaxIssAge"      , &DBDictionary::SpouseRiderMaxIssAge  
    );
+    ascribe("SpouseRiderGuarTable"      , &DBDictionary::SpouseRiderGuarTable  
    );
+    ascribe("SpouseRiderTable"          , &DBDictionary::SpouseRiderTable      
    );
+    ascribe("AllowChildRider"           , &DBDictionary::AllowChildRider       
    );
+    ascribe("ChildRiderMinAmt"          , &DBDictionary::ChildRiderMinAmt      
    );
+    ascribe("ChildRiderMaxAmt"          , &DBDictionary::ChildRiderMaxAmt      
    );
+    ascribe("ChildRiderTable"           , &DBDictionary::ChildRiderTable       
    );
+    ascribe("AllowWd"                   , &DBDictionary::AllowWd               
    );
+    ascribe("WdFee"                     , &DBDictionary::WdFee                 
    );
+    ascribe("WdFeeRate"                 , &DBDictionary::WdFeeRate             
    );
+    ascribe("FreeWdProportion"          , &DBDictionary::FreeWdProportion      
    );
+    ascribe("MinWd"                     , &DBDictionary::MinWd                 
    );
+    ascribe("MaxWdGenAcctValMult"       , &DBDictionary::MaxWdGenAcctValMult   
    );
+    ascribe("MaxWdSepAcctValMult"       , &DBDictionary::MaxWdSepAcctValMult   
    );
+    ascribe("MaxWdDed"                  , &DBDictionary::MaxWdDed              
    );
+    ascribe("WdDecrSpecAmtDboLvl"       , &DBDictionary::WdDecrSpecAmtDboLvl   
    );
+    ascribe("WdDecrSpecAmtDboInc"       , &DBDictionary::WdDecrSpecAmtDboInc   
    );
+    ascribe("WdDecrSpecAmtDboRop"       , &DBDictionary::WdDecrSpecAmtDboRop   
    );
+    ascribe("FirstWdMonth"              , &DBDictionary::FirstWdMonth          
    );
+    ascribe("AllowLoan"                 , &DBDictionary::AllowLoan             
    );
+    ascribe("AllowPrefLoan"             , &DBDictionary::AllowPrefLoan         
    );
+    ascribe("AllowFixedLoan"            , &DBDictionary::AllowFixedLoan        
    );
+    ascribe("AllowVlr"                  , &DBDictionary::AllowVlr              
    );
+    ascribe("FixedLoanRate"             , &DBDictionary::FixedLoanRate         
    );
+    ascribe("MaxVlrRate"                , &DBDictionary::MaxVlrRate            
    );
+    ascribe("MinVlrRate"                , &DBDictionary::MinVlrRate            
    );
+    ascribe("MaxLoanAcctValMult"        , &DBDictionary::MaxLoanAcctValMult    
    );
+    ascribe("MaxLoanDed"                , &DBDictionary::MaxLoanDed            
    );
+    ascribe("FirstPrefLoanYear"         , &DBDictionary::FirstPrefLoanYear     
    );
+    ascribe("PrefLoanRateDecr"          , &DBDictionary::PrefLoanRateDecr      
    );
+    ascribe("GuarPrefLoanSpread"        , &DBDictionary::GuarPrefLoanSpread    
    );
+    ascribe("GuarRegLoanSpread"         , &DBDictionary::GuarRegLoanSpread     
    );
+    ascribe("CurrPrefLoanSpread"        , &DBDictionary::CurrPrefLoanSpread    
    );
+    ascribe("CurrRegLoanSpread"         , &DBDictionary::CurrRegLoanSpread     
    );
+    ascribe("FirstLoanMonth"            , &DBDictionary::FirstLoanMonth        
    );
+    ascribe("MinPremType"               , &DBDictionary::MinPremType           
    );
+    ascribe("MinPremTable"              , &DBDictionary::MinPremTable          
    );
+    ascribe("MinPremIntSpread"          , &DBDictionary::MinPremIntSpread      
    );
+    ascribe("SplitMinPrem"              , &DBDictionary::SplitMinPrem          
    );
+    ascribe("UnsplitSplitMinPrem"       , &DBDictionary::UnsplitSplitMinPrem   
    );
+    ascribe("ErNotionallyPaysTerm"      , &DBDictionary::ErNotionallyPaysTerm  
    );
+    ascribe("TgtPremType"               , &DBDictionary::TgtPremType           
    );
+    ascribe("TgtPremTable"              , &DBDictionary::TgtPremTable          
    );
+    ascribe("TgtPremFixedAtIssue"       , &DBDictionary::TgtPremFixedAtIssue   
    );
+    ascribe("TgtPremIgnoreSubstd"       , &DBDictionary::TgtPremIgnoreSubstd   
    );
+    ascribe("MinPmt"                    , &DBDictionary::MinPmt                
    );
+    ascribe("IsSinglePremium"           , &DBDictionary::IsSinglePremium       
    );
+    ascribe("NoLapseMinDur"             , &DBDictionary::NoLapseMinDur         
    );
+    ascribe("NoLapseMinAge"             , &DBDictionary::NoLapseMinAge         
    );
+    ascribe("NoLapseUnratedOnly"        , &DBDictionary::NoLapseUnratedOnly    
    );
+    ascribe("NoLapseDboLvlOnly"         , &DBDictionary::NoLapseDboLvlOnly     
    );
+    ascribe("NoLapseAlwaysActive"       , &DBDictionary::NoLapseAlwaysActive   
    );
+    ascribe("AllowHoneymoon"            , &DBDictionary::AllowHoneymoon        
    );
+    ascribe("DeductionMethod"           , &DBDictionary::DeductionMethod       
    );
+    ascribe("DeductionAcct"             , &DBDictionary::DeductionAcct         
    );
+    ascribe("DistributionMethod"        , &DBDictionary::DistributionMethod    
    );
+    ascribe("DistributionAcct"          , &DBDictionary::DistributionAcct      
    );
+    ascribe("EePremMethod"              , &DBDictionary::EePremMethod          
    );
+    ascribe("EePremAcct"                , &DBDictionary::EePremAcct            
    );
+    ascribe("ErPremMethod"              , &DBDictionary::ErPremMethod          
    );
+    ascribe("ErPremAcct"                , &DBDictionary::ErPremAcct            
    );
+    ascribe("CalculateComp"             , &DBDictionary::CalculateComp         
    );
+    ascribe("CompTarget"                , &DBDictionary::CompTarget            
    );
+    ascribe("CompExcess"                , &DBDictionary::CompExcess            
    );
+    ascribe("CompChargeback"            , &DBDictionary::CompChargeback        
    );
+    ascribe("AssetComp"                 , &DBDictionary::AssetComp             
    );
+    ascribe("AllowExtraAssetComp"       , &DBDictionary::AllowExtraAssetComp   
    );
+    ascribe("AllowExtraPremComp"        , &DBDictionary::AllowExtraPremComp    
    );
+    ascribe("AllowExpRating"            , &DBDictionary::AllowExpRating        
    );
+    ascribe("ExpRatStdDevMult"          , &DBDictionary::ExpRatStdDevMult      
    );
+    ascribe("ExpRatIbnrMult"            , &DBDictionary::ExpRatIbnrMult        
    );
+    ascribe("ExpRatCoiRetention"        , &DBDictionary::ExpRatCoiRetention    
    );
+    ascribe("ExpRatRiskCoiMult"         , &DBDictionary::ExpRatRiskCoiMult     
    );
+    ascribe("ExpRatAmortPeriod"         , &DBDictionary::ExpRatAmortPeriod     
    );
+    ascribe("LedgerType"                , &DBDictionary::LedgerType            
    );
+    ascribe("Nonillustrated"            , &DBDictionary::Nonillustrated        
    );
+    ascribe("NoLongerIssued"            , &DBDictionary::NoLongerIssued        
    );
+    ascribe("AgeLastOrNearest"          , &DBDictionary::AgeLastOrNearest      
    );
+    ascribe("MaturityAge"               , &DBDictionary::MaturityAge           
    );
+    ascribe("CashValueEnhMult"          , &DBDictionary::CashValueEnhMult      
    );
+    ascribe("LapseIgnoresSurrChg"       , &DBDictionary::LapseIgnoresSurrChg   
    );
+    ascribe("DefaultProcessOrder"       , &DBDictionary::DefaultProcessOrder   
    );
+    ascribe("GroupProxyRateTable"       , &DBDictionary::GroupProxyRateTable   
    );
+    ascribe("PartialMortTable"          , &DBDictionary::PartialMortTable      
    );
+    ascribe("UsePolicyFormAlt"          , &DBDictionary::UsePolicyFormAlt      
    ); // LINGO !! expunge
+    ascribe("AllowGroupQuote"           , &DBDictionary::AllowGroupQuote       
    );
+    ascribe("PolicyForm"                , &DBDictionary::PolicyForm            
    );
+    ascribe("PolicyFormAlternative"     , &DBDictionary::PolicyFormAlternative 
    ); // LINGO !! expunge
+    ascribe("PolicyMktgName"            , &DBDictionary::PolicyMktgName        
    );
+    ascribe("PolicyLegalName"           , &DBDictionary::PolicyLegalName       
    );
+    ascribe("InsCoShortName"            , &DBDictionary::InsCoShortName        
    );
+    ascribe("InsCoName"                 , &DBDictionary::InsCoName             
    );
+    ascribe("InsCoAddr"                 , &DBDictionary::InsCoAddr             
    );
+    ascribe("InsCoStreet"               , &DBDictionary::InsCoStreet           
    );
+    ascribe("InsCoPhone"                , &DBDictionary::InsCoPhone            
    );
+    ascribe("MainUnderwriter"           , &DBDictionary::MainUnderwriter       
    );
+    ascribe("MainUnderwriterAddress"    , 
&DBDictionary::MainUnderwriterAddress    );
+    ascribe("CoUnderwriter"             , &DBDictionary::CoUnderwriter         
    );
+    ascribe("CoUnderwriterAddress"      , &DBDictionary::CoUnderwriterAddress  
    );
+    ascribe("AvName"                    , &DBDictionary::AvName                
    );
+    ascribe("CsvName"                   , &DBDictionary::CsvName               
    );
+    ascribe("CsvHeaderName"             , &DBDictionary::CsvHeaderName         
    );
+    ascribe("NoLapseProvisionName"      , &DBDictionary::NoLapseProvisionName  
    );
+    ascribe("ContractName"              , &DBDictionary::ContractName          
    );
+    ascribe("DboName"                   , &DBDictionary::DboName               
    );
+    ascribe("DboNameLevel"              , &DBDictionary::DboNameLevel          
    );
+    ascribe("DboNameIncreasing"         , &DBDictionary::DboNameIncreasing     
    );
+    ascribe("DboNameReturnOfPremium"    , 
&DBDictionary::DboNameReturnOfPremium    );
+    ascribe("DboNameMinDeathBenefit"    , 
&DBDictionary::DboNameMinDeathBenefit    );
+    ascribe("GenAcctName"               , &DBDictionary::GenAcctName           
    );
+    ascribe("GenAcctNameElaborated"     , &DBDictionary::GenAcctNameElaborated 
    );
+    ascribe("SepAcctName"               , &DBDictionary::SepAcctName           
    );
+    ascribe("SpecAmtName"               , &DBDictionary::SpecAmtName           
    );
+    ascribe("SpecAmtNameElaborated"     , &DBDictionary::SpecAmtNameElaborated 
    );
+    ascribe("UwBasisMedical"            , &DBDictionary::UwBasisMedical        
    );
+    ascribe("UwBasisParamedical"        , &DBDictionary::UwBasisParamedical    
    );
+    ascribe("UwBasisNonmedical"         , &DBDictionary::UwBasisNonmedical     
    );
+    ascribe("UwBasisSimplified"         , &DBDictionary::UwBasisSimplified     
    );
+    ascribe("UwBasisGuaranteed"         , &DBDictionary::UwBasisGuaranteed     
    );
+    ascribe("UwClassPreferred"          , &DBDictionary::UwClassPreferred      
    );
+    ascribe("UwClassStandard"           , &DBDictionary::UwClassStandard       
    );
+    ascribe("UwClassRated"              , &DBDictionary::UwClassRated          
    );
+    ascribe("UwClassUltra"              , &DBDictionary::UwClassUltra          
    );
+    ascribe("AccountValueFootnote"      , &DBDictionary::AccountValueFootnote  
    );
+    ascribe("AttainedAgeFootnote"       , &DBDictionary::AttainedAgeFootnote   
    );
+    ascribe("CashSurrValueFootnote"     , &DBDictionary::CashSurrValueFootnote 
    );
+    ascribe("DeathBenefitFootnote"      , &DBDictionary::DeathBenefitFootnote  
    );
+    ascribe("InitialPremiumFootnote"    , 
&DBDictionary::InitialPremiumFootnote    );
+    ascribe("NetPremiumFootnote"        , &DBDictionary::NetPremiumFootnote    
    );
+    ascribe("GrossPremiumFootnote"      , &DBDictionary::GrossPremiumFootnote  
    );
+    ascribe("OutlayFootnote"            , &DBDictionary::OutlayFootnote        
    );
+    ascribe("PolicyYearFootnote"        , &DBDictionary::PolicyYearFootnote    
    );
+    ascribe("ADDTerseName"              , &DBDictionary::ADDTerseName          
    );
+    ascribe("InsurabilityTerseName"     , &DBDictionary::InsurabilityTerseName 
    );
+    ascribe("ChildTerseName"            , &DBDictionary::ChildTerseName        
    );
+    ascribe("SpouseTerseName"           , &DBDictionary::SpouseTerseName       
    );
+    ascribe("TermTerseName"             , &DBDictionary::TermTerseName         
    );
+    ascribe("WaiverTerseName"           , &DBDictionary::WaiverTerseName       
    );
+    ascribe("AccelBftRiderTerseName"    , 
&DBDictionary::AccelBftRiderTerseName    );
+    ascribe("OverloanRiderTerseName"    , 
&DBDictionary::OverloanRiderTerseName    );
+    ascribe("ADDFootnote"               , &DBDictionary::ADDFootnote           
    );
+    ascribe("ChildFootnote"             , &DBDictionary::ChildFootnote         
    );
+    ascribe("SpouseFootnote"            , &DBDictionary::SpouseFootnote        
    );
+    ascribe("TermFootnote"              , &DBDictionary::TermFootnote          
    );
+    ascribe("WaiverFootnote"            , &DBDictionary::WaiverFootnote        
    );
+    ascribe("AccelBftRiderFootnote"     , &DBDictionary::AccelBftRiderFootnote 
    );
+    ascribe("OverloanRiderFootnote"     , &DBDictionary::OverloanRiderFootnote 
    );
+    ascribe("GroupQuoteShortProductName", 
&DBDictionary::GroupQuoteShortProductName);
+    ascribe("GroupQuoteIsNotAnOffer"    , 
&DBDictionary::GroupQuoteIsNotAnOffer    );
+    ascribe("GroupQuoteRidersFooter"    , 
&DBDictionary::GroupQuoteRidersFooter    );
+    ascribe("GroupQuotePolicyFormId"    , 
&DBDictionary::GroupQuotePolicyFormId    );
+    ascribe("GroupQuoteStateVariations" , 
&DBDictionary::GroupQuoteStateVariations );
+    ascribe("GroupQuoteProspectus"      , &DBDictionary::GroupQuoteProspectus  
    );
+    ascribe("GroupQuoteUnderwriter"     , &DBDictionary::GroupQuoteUnderwriter 
    );
+    ascribe("GroupQuoteBrokerDealer"    , 
&DBDictionary::GroupQuoteBrokerDealer    );
+    ascribe("GroupQuoteRubricMandatory" , 
&DBDictionary::GroupQuoteRubricMandatory );
+    ascribe("GroupQuoteRubricVoluntary" , 
&DBDictionary::GroupQuoteRubricVoluntary );
+    ascribe("GroupQuoteRubricFusion"    , 
&DBDictionary::GroupQuoteRubricFusion    );
+    ascribe("GroupQuoteFooterMandatory" , 
&DBDictionary::GroupQuoteFooterMandatory );
+    ascribe("GroupQuoteFooterVoluntary" , 
&DBDictionary::GroupQuoteFooterVoluntary );
+    ascribe("GroupQuoteFooterFusion"    , 
&DBDictionary::GroupQuoteFooterFusion    );
+    ascribe("MinimumPremiumFootnote"    , 
&DBDictionary::MinimumPremiumFootnote    );
+    ascribe("PremAllocationFootnote"    , 
&DBDictionary::PremAllocationFootnote    );
+    ascribe("InterestDisclaimer"        , &DBDictionary::InterestDisclaimer    
    );
+    ascribe("GuarMortalityFootnote"     , &DBDictionary::GuarMortalityFootnote 
    );
+    ascribe("ProductDescription"        , &DBDictionary::ProductDescription    
    );
+    ascribe("StableValueFootnote"       , &DBDictionary::StableValueFootnote   
    );
+    ascribe("NoVanishPremiumFootnote"   , 
&DBDictionary::NoVanishPremiumFootnote   );
+    ascribe("RejectPremiumFootnote"     , &DBDictionary::RejectPremiumFootnote 
    );
+    ascribe("ExpRatingFootnote"         , &DBDictionary::ExpRatingFootnote     
    );
+    ascribe("MortalityBlendFootnote"    , 
&DBDictionary::MortalityBlendFootnote    );
+    ascribe("HypotheticalRatesFootnote" , 
&DBDictionary::HypotheticalRatesFootnote );
+    ascribe("SalesLoadRefundFootnote"   , 
&DBDictionary::SalesLoadRefundFootnote   );
+    ascribe("NoLapseEverFootnote"       , &DBDictionary::NoLapseEverFootnote   
    );
+    ascribe("NoLapseFootnote"           , &DBDictionary::NoLapseFootnote       
    );
+    ascribe("CurrentValuesFootnote"     , &DBDictionary::CurrentValuesFootnote 
    );
+    ascribe("DBOption1Footnote"         , &DBDictionary::DBOption1Footnote     
    );
+    ascribe("DBOption2Footnote"         , &DBDictionary::DBOption2Footnote     
    );
+    ascribe("DBOption3Footnote"         , &DBDictionary::DBOption3Footnote     
    );
+    ascribe("MinDeathBenefitFootnote"   , 
&DBDictionary::MinDeathBenefitFootnote   );
+    ascribe("ExpRatRiskChargeFootnote"  , 
&DBDictionary::ExpRatRiskChargeFootnote  );
+    ascribe("ExchangeChargeFootnote1"   , 
&DBDictionary::ExchangeChargeFootnote1   );
+    ascribe("FlexiblePremiumFootnote"   , 
&DBDictionary::FlexiblePremiumFootnote   );
+    ascribe("GuaranteedValuesFootnote"  , 
&DBDictionary::GuaranteedValuesFootnote  );
+    ascribe("CreditingRateFootnote"     , &DBDictionary::CreditingRateFootnote 
    );
+    ascribe("GrossRateFootnote"         , &DBDictionary::GrossRateFootnote     
    );
+    ascribe("NetRateFootnote"           , &DBDictionary::NetRateFootnote       
    );
+    ascribe("MecFootnote"               , &DBDictionary::MecFootnote           
    );
+    ascribe("GptFootnote"               , &DBDictionary::GptFootnote           
    );
+    ascribe("MidpointValuesFootnote"    , 
&DBDictionary::MidpointValuesFootnote    );
+    ascribe("SinglePremiumFootnote"     , &DBDictionary::SinglePremiumFootnote 
    );
+    ascribe("MonthlyChargesFootnote"    , 
&DBDictionary::MonthlyChargesFootnote    );
+    ascribe("UltCreditingRateFootnote"  , 
&DBDictionary::UltCreditingRateFootnote  );
+    ascribe("UltCreditingRateHeader"    , 
&DBDictionary::UltCreditingRateHeader    );
+    ascribe("MaxNaarFootnote"           , &DBDictionary::MaxNaarFootnote       
    );
+    ascribe("PremTaxSurrChgFootnote"    , 
&DBDictionary::PremTaxSurrChgFootnote    );
+    ascribe("PolicyFeeFootnote"         , &DBDictionary::PolicyFeeFootnote     
    );
+    ascribe("AssetChargeFootnote"       , &DBDictionary::AssetChargeFootnote   
    );
+    ascribe("InvestmentIncomeFootnote"  , 
&DBDictionary::InvestmentIncomeFootnote  );
+    ascribe("IrrDbFootnote"             , &DBDictionary::IrrDbFootnote         
    );
+    ascribe("IrrCsvFootnote"            , &DBDictionary::IrrCsvFootnote        
    );
+    ascribe("MortalityChargesFootnote"  , 
&DBDictionary::MortalityChargesFootnote  );
+    ascribe("LoanAndWithdrawalFootnote" , 
&DBDictionary::LoanAndWithdrawalFootnote );
+    ascribe("LoanFootnote"              , &DBDictionary::LoanFootnote          
    );
+    ascribe("ImprimaturPresale"         , &DBDictionary::ImprimaturPresale     
    );
+    ascribe("ImprimaturPresaleComposite", 
&DBDictionary::ImprimaturPresaleComposite);
+    ascribe("ImprimaturInforce"         , &DBDictionary::ImprimaturInforce     
    );
+    ascribe("ImprimaturInforceComposite", 
&DBDictionary::ImprimaturInforceComposite);
+    ascribe("StateMarketingImprimatur"  , 
&DBDictionary::StateMarketingImprimatur  );
+    ascribe("NonGuaranteedFootnote"     , &DBDictionary::NonGuaranteedFootnote 
    );
+    ascribe("NonGuaranteedFootnote1"    , 
&DBDictionary::NonGuaranteedFootnote1    );
+    ascribe("NonGuaranteedFootnote1Tx"  , 
&DBDictionary::NonGuaranteedFootnote1Tx  );
+    ascribe("FnMonthlyDeductions"       , &DBDictionary::FnMonthlyDeductions   
    );
+    ascribe("SurrenderFootnote"         , &DBDictionary::SurrenderFootnote     
    );
+    ascribe("PortabilityFootnote"       , &DBDictionary::PortabilityFootnote   
    );
+    ascribe("FundRateFootnote"          , &DBDictionary::FundRateFootnote      
    );
+    ascribe("IssuingCompanyFootnote"    , 
&DBDictionary::IssuingCompanyFootnote    );
+    ascribe("SubsidiaryFootnote"        , &DBDictionary::SubsidiaryFootnote    
    );
+    ascribe("PlacementAgentFootnote"    , 
&DBDictionary::PlacementAgentFootnote    );
+    ascribe("MarketingNameFootnote"     , &DBDictionary::MarketingNameFootnote 
    );
+    ascribe("GuarIssueDisclaimerNcSc"   , 
&DBDictionary::GuarIssueDisclaimerNcSc   );
+    ascribe("GuarIssueDisclaimerMd"     , &DBDictionary::GuarIssueDisclaimerMd 
    );
+    ascribe("GuarIssueDisclaimerTx"     , &DBDictionary::GuarIssueDisclaimerTx 
    );
+    ascribe("IllRegCertAgent"           , &DBDictionary::IllRegCertAgent       
    );
+    ascribe("IllRegCertAgentIl"         , &DBDictionary::IllRegCertAgentIl     
    );
+    ascribe("IllRegCertAgentTx"         , &DBDictionary::IllRegCertAgentTx     
    );
+    ascribe("IllRegCertClient"          , &DBDictionary::IllRegCertClient      
    );
+    ascribe("IllRegCertClientIl"        , &DBDictionary::IllRegCertClientIl    
    );
+    ascribe("IllRegCertClientTx"        , &DBDictionary::IllRegCertClientTx    
    );
+    ascribe("FnMaturityAge"             , &DBDictionary::FnMaturityAge         
    );
+    ascribe("FnPartialMortality"        , &DBDictionary::FnPartialMortality    
    );
+    ascribe("FnProspectus"              , &DBDictionary::FnProspectus          
    );
+    ascribe("FnInitialSpecAmt"          , &DBDictionary::FnInitialSpecAmt      
    );
+    ascribe("FnInforceAcctVal"          , &DBDictionary::FnInforceAcctVal      
    );
+    ascribe("FnInforceTaxBasis"         , &DBDictionary::FnInforceTaxBasis     
    );
+    ascribe("Fn1035Charge"              , &DBDictionary::Fn1035Charge          
    );
+    ascribe("FnMecExtraWarning"         , &DBDictionary::FnMecExtraWarning     
    );
+    ascribe("FnNotTaxAdvice"            , &DBDictionary::FnNotTaxAdvice        
    );
+    ascribe("FnNotTaxAdvice2"           , &DBDictionary::FnNotTaxAdvice2       
    );
+    ascribe("FnImf"                     , &DBDictionary::FnImf                 
    );
+    ascribe("FnCensus"                  , &DBDictionary::FnCensus              
    );
+    ascribe("FnDacTax"                  , &DBDictionary::FnDacTax              
    );
+    ascribe("FnDefnLifeIns"             , &DBDictionary::FnDefnLifeIns         
    );
+    ascribe("FnBoyEoy"                  , &DBDictionary::FnBoyEoy              
    );
+    ascribe("FnGeneralAccount"          , &DBDictionary::FnGeneralAccount      
    );
+    ascribe("FnPpMemorandum"            , &DBDictionary::FnPpMemorandum        
    );
+    ascribe("FnPpAccreditedInvestor"    , 
&DBDictionary::FnPpAccreditedInvestor    );
+    ascribe("FnPpLoads"                 , &DBDictionary::FnPpLoads             
    );
+    ascribe("FnProposalUnderwriting"    , 
&DBDictionary::FnProposalUnderwriting    );
+    ascribe("FnGuaranteedPremium"       , &DBDictionary::FnGuaranteedPremium   
    );
+    ascribe("FnOmnibusDisclaimer"       , &DBDictionary::FnOmnibusDisclaimer   
    );
+    ascribe("FnInitialDbo"              , &DBDictionary::FnInitialDbo          
    );
+    ascribe("DefnGuarGenAcctRate"       , &DBDictionary::DefnGuarGenAcctRate   
    );
+    ascribe("DefnAV"                    , &DBDictionary::DefnAV                
    );
+    ascribe("DefnCSV"                   , &DBDictionary::DefnCSV               
    );
+    ascribe("DefnMec"                   , &DBDictionary::DefnMec               
    );
+    ascribe("DefnOutlay"                , &DBDictionary::DefnOutlay            
    );
+    ascribe("DefnSpecAmt"               , &DBDictionary::DefnSpecAmt           
    );
+    ascribe("WeightClass"               , &DBDictionary::WeightClass           
    );
+    ascribe("WeightGender"              , &DBDictionary::WeightGender          
    );
+    ascribe("WeightSmoking"             , &DBDictionary::WeightSmoking         
    );
+    ascribe("WeightAge"                 , &DBDictionary::WeightAge             
    );
+    ascribe("WeightSpecAmt"             , &DBDictionary::WeightSpecAmt         
    );
+    ascribe("WeightState"               , &DBDictionary::WeightState           
    );
+    ascribe("FullExpPol"                , &DBDictionary::FullExpPol            
    );
+    ascribe("FullExpPrem"               , &DBDictionary::FullExpPrem           
    );
+    ascribe("FullExpDumpin"             , &DBDictionary::FullExpDumpin         
    );
+    ascribe("FullExpSpecAmt"            , &DBDictionary::FullExpSpecAmt        
    );
+    ascribe("VarExpPol"                 , &DBDictionary::VarExpPol             
    );
+    ascribe("VarExpPrem"                , &DBDictionary::VarExpPrem            
    );
+    ascribe("VarExpDumpin"              , &DBDictionary::VarExpDumpin          
    );
+    ascribe("VarExpSpecAmt"             , &DBDictionary::VarExpSpecAmt         
    );
+    ascribe("ExpSpecAmtLimit"           , &DBDictionary::ExpSpecAmtLimit       
    );
+    ascribe("MedicalProportion"         , &DBDictionary::MedicalProportion     
    );
+    ascribe("UwTestCost"                , &DBDictionary::UwTestCost            
    );
+    ascribe("VxBasicQTable"             , &DBDictionary::VxBasicQTable         
    );
+    ascribe("VxDeficQTable"             , &DBDictionary::VxDeficQTable         
    );
+    ascribe("VxTaxQTable"               , &DBDictionary::VxTaxQTable           
    );
+    ascribe("StatVxInt"                 , &DBDictionary::StatVxInt             
    );
+    ascribe("TaxVxInt"                  , &DBDictionary::TaxVxInt              
    );
+    ascribe("StatVxQ"                   , &DBDictionary::StatVxQ               
    );
+    ascribe("TaxVxQ"                    , &DBDictionary::TaxVxQ                
    );
+    ascribe("DeficVxQ"                  , &DBDictionary::DeficVxQ              
    );
+    ascribe("SnflQ"                     , &DBDictionary::SnflQ                 
    );
+    ascribe("LapseRate"                 , &DBDictionary::LapseRate             
    );
+    ascribe("ReqSurpNaar"               , &DBDictionary::ReqSurpNaar           
    );
+    ascribe("ReqSurpVx"                 , &DBDictionary::ReqSurpVx             
    );
+    ascribe("LicFitRate"                , &DBDictionary::LicFitRate            
    );
+    ascribe("LicDacTaxRate"             , &DBDictionary::LicDacTaxRate         
    );
+    ascribe("GdbVxMethod"               , &DBDictionary::GdbVxMethod           
    );
+    ascribe("PrimaryHurdle"             , &DBDictionary::PrimaryHurdle         
    );
+    ascribe("SecondaryHurdle"           , &DBDictionary::SecondaryHurdle       
    );
 }
 
 /// Read a database file.
@@ -637,11 +810,14 @@ namespace
 {
 class sample : public DBDictionary {public: sample();};
 
-class sample2finra : public sample {public: sample2finra();};
-class sample2prosp : public sample {public: sample2prosp();};
-class sample2gpp   : public sample {public: sample2gpp  ();};
-class sample2ipp   : public sample {public: sample2ipp  ();};
-class sample2xyz   : public sample {public: sample2xyz  ();};
+class sample2 : public sample {public: sample2();};
+
+class sample2naic  : public sample2 {public: sample2naic ();};
+class sample2finra : public sample2 {public: sample2finra();};
+class sample2prosp : public sample2 {public: sample2prosp();};
+class sample2gpp   : public sample2 {public: sample2gpp  ();};
+class sample2ipp   : public sample2 {public: sample2ipp  ();};
+class sample2xyz   : public sample2 {public: sample2xyz  ();};
 
 sample::sample()
 {
@@ -921,12 +1097,373 @@ sample::sample()
     double T83Gam[3] = {825, 826, 826,}; // f, m, u
     Add({DB_PartialMortTable, e_number_of_axes, dims311, T83Gam});
 
-    // Use alternative policy form name in states beginning with "K".
-    std::vector<double> alt_form(e_max_dim_state);
-    alt_form[mce_s_KS] = true;
-    alt_form[mce_s_KY] = true;
-    Add({DB_UsePolicyFormAlt, premium_tax_dimensions, alt_form});
+    // Use alternative policy form name in states beginning with "K". // LINGO 
!! expunge
+    std::vector<double> alt_form(e_max_dim_state); // LINGO !! expunge
+    alt_form[mce_s_KS] = true; // LINGO !! expunge
+    alt_form[mce_s_KY] = true; // LINGO !! expunge
+    Add({DB_UsePolicyFormAlt, premium_tax_dimensions, alt_form}); // LINGO !! 
expunge
+
     Add({DB_AllowGroupQuote     , true});
+
+    // Policy form differs in states beginning with "K".
+    std::vector<double> policy_form(e_max_dim_state, superior::policy_form);
+    policy_form[mce_s_KS] = superior::policy_form_KS_KY;
+    policy_form[mce_s_KY] = superior::policy_form_KS_KY;
+    Add({DB_PolicyForm, premium_tax_dimensions, policy_form});
+    Add({DB_PolicyFormAlternative      , superior::PolicyFormAlternative}); // 
LINGO !! expunge
+    Add({DB_PolicyMktgName             , superior::PolicyMktgName});
+    Add({DB_PolicyLegalName            , superior::PolicyLegalName});
+    Add({DB_InsCoShortName             , superior::InsCoShortName});
+    Add({DB_InsCoName                  , superior::InsCoName});
+    Add({DB_InsCoAddr                  , superior::InsCoAddr});
+    Add({DB_InsCoStreet                , superior::InsCoStreet});
+    Add({DB_InsCoPhone                 , superior::InsCoPhone});
+    Add({DB_MainUnderwriter            , superior::MainUnderwriter});
+    Add({DB_MainUnderwriterAddress     , superior::MainUnderwriterAddress});
+    Add({DB_CoUnderwriter              , superior::CoUnderwriter});
+    Add({DB_CoUnderwriterAddress       , superior::CoUnderwriterAddress});
+    Add({DB_AvName                     , superior::AvName});
+    Add({DB_CsvName                    , superior::CsvName});
+    Add({DB_CsvHeaderName              , superior::CsvHeaderName});
+    Add({DB_NoLapseProvisionName       , superior::NoLapseProvisionName});
+    Add({DB_ContractName               , superior::ContractName});
+    Add({DB_DboName                    , superior::DboName});
+    Add({DB_DboNameLevel               , superior::DboNameLevel});
+    Add({DB_DboNameIncreasing          , superior::DboNameIncreasing});
+    Add({DB_DboNameReturnOfPremium     , superior::DboNameReturnOfPremium});
+    Add({DB_DboNameMinDeathBenefit     , superior::DboNameMinDeathBenefit});
+    Add({DB_GenAcctName                , superior::GenAcctName});
+    Add({DB_GenAcctNameElaborated      , superior::GenAcctNameElaborated});
+    Add({DB_SepAcctName                , superior::SepAcctName});
+    Add({DB_SpecAmtName                , superior::SpecAmtName});
+    Add({DB_SpecAmtNameElaborated      , superior::SpecAmtNameElaborated});
+    Add({DB_UwBasisMedical             , superior::UwBasisMedical});
+    Add({DB_UwBasisParamedical         , superior::UwBasisParamedical});
+    Add({DB_UwBasisNonmedical          , superior::UwBasisNonmedical});
+    Add({DB_UwBasisSimplified          , superior::UwBasisSimplified});
+    Add({DB_UwBasisGuaranteed          , superior::UwBasisGuaranteed});
+    Add({DB_UwClassPreferred           , superior::UwClassPreferred});
+    Add({DB_UwClassStandard            , superior::UwClassStandard});
+    Add({DB_UwClassRated               , superior::UwClassRated});
+    Add({DB_UwClassUltra               , superior::UwClassUltra});
+    Add({DB_AccountValueFootnote       , superior::AccountValueFootnote});
+    Add({DB_AttainedAgeFootnote        , superior::AttainedAgeFootnote});
+    Add({DB_CashSurrValueFootnote      , superior::CashSurrValueFootnote});
+    Add({DB_DeathBenefitFootnote       , superior::DeathBenefitFootnote});
+    Add({DB_InitialPremiumFootnote     , superior::InitialPremiumFootnote});
+    Add({DB_NetPremiumFootnote         , superior::NetPremiumFootnote});
+    Add({DB_GrossPremiumFootnote       , superior::GrossPremiumFootnote});
+    Add({DB_OutlayFootnote             , superior::OutlayFootnote});
+    Add({DB_PolicyYearFootnote         , superior::PolicyYearFootnote});
+    Add({DB_ADDTerseName               , superior::ADDTerseName});
+    Add({DB_InsurabilityTerseName      , superior::InsurabilityTerseName});
+    Add({DB_ChildTerseName             , superior::ChildTerseName});
+    Add({DB_SpouseTerseName            , superior::SpouseTerseName});
+    Add({DB_TermTerseName              , superior::TermTerseName});
+    Add({DB_WaiverTerseName            , superior::WaiverTerseName});
+    Add({DB_AccelBftRiderTerseName     , superior::AccelBftRiderTerseName});
+    Add({DB_OverloanRiderTerseName     , superior::OverloanRiderTerseName});
+    Add({DB_ADDFootnote                , superior::ADDFootnote});
+    Add({DB_ChildFootnote              , superior::ChildFootnote});
+    Add({DB_SpouseFootnote             , superior::SpouseFootnote});
+    Add({DB_TermFootnote               , superior::TermFootnote});
+    Add({DB_WaiverFootnote             , superior::WaiverFootnote});
+    Add({DB_AccelBftRiderFootnote      , superior::AccelBftRiderFootnote});
+    Add({DB_OverloanRiderFootnote      , superior::OverloanRiderFootnote});
+    Add({DB_GroupQuoteShortProductName , 
superior::GroupQuoteShortProductName});
+    Add({DB_GroupQuoteIsNotAnOffer     , superior::GroupQuoteIsNotAnOffer});
+    Add({DB_GroupQuoteRidersFooter     , superior::GroupQuoteRidersFooter});
+    Add({DB_GroupQuotePolicyFormId     , superior::GroupQuotePolicyFormId});
+    Add({DB_GroupQuoteStateVariations  , superior::GroupQuoteStateVariations});
+    Add({DB_GroupQuoteProspectus       , superior::GroupQuoteProspectus});
+    Add({DB_GroupQuoteUnderwriter      , superior::GroupQuoteUnderwriter});
+    Add({DB_GroupQuoteBrokerDealer     , superior::GroupQuoteBrokerDealer});
+    Add({DB_GroupQuoteRubricMandatory  , superior::GroupQuoteRubricMandatory});
+    Add({DB_GroupQuoteRubricVoluntary  , superior::GroupQuoteRubricVoluntary});
+    Add({DB_GroupQuoteRubricFusion     , superior::GroupQuoteRubricFusion});
+    Add({DB_GroupQuoteFooterMandatory  , superior::GroupQuoteFooterMandatory});
+    Add({DB_GroupQuoteFooterVoluntary  , superior::GroupQuoteFooterVoluntary});
+    Add({DB_GroupQuoteFooterFusion     , superior::GroupQuoteFooterFusion});
+    Add({DB_MinimumPremiumFootnote     , superior::MinimumPremiumFootnote});
+    Add({DB_PremAllocationFootnote     , superior::PremAllocationFootnote});
+    Add({DB_InterestDisclaimer         , superior::InterestDisclaimer});
+    Add({DB_GuarMortalityFootnote      , superior::GuarMortalityFootnote});
+    Add({DB_ProductDescription         , superior::ProductDescription});
+    Add({DB_StableValueFootnote        , superior::StableValueFootnote});
+    Add({DB_NoVanishPremiumFootnote    , superior::NoVanishPremiumFootnote});
+    Add({DB_RejectPremiumFootnote      , superior::RejectPremiumFootnote});
+    Add({DB_ExpRatingFootnote          , superior::ExpRatingFootnote});
+    Add({DB_MortalityBlendFootnote     , superior::MortalityBlendFootnote});
+    Add({DB_HypotheticalRatesFootnote  , superior::HypotheticalRatesFootnote});
+    Add({DB_SalesLoadRefundFootnote    , superior::SalesLoadRefundFootnote});
+    Add({DB_NoLapseEverFootnote        , superior::NoLapseEverFootnote});
+    Add({DB_NoLapseFootnote            , superior::NoLapseFootnote});
+    Add({DB_CurrentValuesFootnote      , superior::CurrentValuesFootnote});
+    Add({DB_DBOption1Footnote          , superior::DBOption1Footnote});
+    Add({DB_DBOption2Footnote          , superior::DBOption2Footnote});
+    Add({DB_DBOption3Footnote          , superior::DBOption3Footnote});
+    Add({DB_MinDeathBenefitFootnote    , superior::MinDeathBenefitFootnote});
+    Add({DB_ExpRatRiskChargeFootnote   , superior::ExpRatRiskChargeFootnote});
+    Add({DB_ExchangeChargeFootnote1    , superior::ExchangeChargeFootnote1});
+    Add({DB_FlexiblePremiumFootnote    , superior::FlexiblePremiumFootnote});
+    Add({DB_GuaranteedValuesFootnote   , superior::GuaranteedValuesFootnote});
+    Add({DB_CreditingRateFootnote      , superior::CreditingRateFootnote});
+    Add({DB_GrossRateFootnote          , superior::GrossRateFootnote});
+    Add({DB_NetRateFootnote            , superior::NetRateFootnote});
+    Add({DB_MecFootnote                , superior::MecFootnote});
+    Add({DB_GptFootnote                , superior::GptFootnote});
+    Add({DB_MidpointValuesFootnote     , superior::MidpointValuesFootnote});
+    Add({DB_SinglePremiumFootnote      , superior::SinglePremiumFootnote});
+    Add({DB_MonthlyChargesFootnote     , superior::MonthlyChargesFootnote});
+    Add({DB_UltCreditingRateFootnote   , superior::UltCreditingRateFootnote});
+    Add({DB_UltCreditingRateHeader     , superior::UltCreditingRateHeader});
+    Add({DB_MaxNaarFootnote            , superior::MaxNaarFootnote});
+    Add({DB_PremTaxSurrChgFootnote     , superior::PremTaxSurrChgFootnote});
+    Add({DB_PolicyFeeFootnote          , superior::PolicyFeeFootnote});
+    Add({DB_AssetChargeFootnote        , superior::AssetChargeFootnote});
+    Add({DB_InvestmentIncomeFootnote   , superior::InvestmentIncomeFootnote});
+    Add({DB_IrrDbFootnote              , superior::IrrDbFootnote});
+    Add({DB_IrrCsvFootnote             , superior::IrrCsvFootnote});
+    Add({DB_MortalityChargesFootnote   , superior::MortalityChargesFootnote});
+    Add({DB_LoanAndWithdrawalFootnote  , superior::LoanAndWithdrawalFootnote});
+    Add({DB_LoanFootnote               , superior::LoanFootnote});
+    Add({DB_ImprimaturPresale          , superior::ImprimaturPresale});
+    Add({DB_ImprimaturPresaleComposite , 
superior::ImprimaturPresaleComposite});
+    Add({DB_ImprimaturInforce          , superior::ImprimaturInforce});
+    Add({DB_ImprimaturInforceComposite , 
superior::ImprimaturInforceComposite});
+    Add({DB_StateMarketingImprimatur   , superior::StateMarketingImprimatur});
+    Add({DB_NonGuaranteedFootnote      , superior::NonGuaranteedFootnote});
+    Add({DB_NonGuaranteedFootnote1     , superior::NonGuaranteedFootnote1});
+    Add({DB_NonGuaranteedFootnote1Tx   , superior::NonGuaranteedFootnote1Tx});
+    Add({DB_FnMonthlyDeductions        , superior::FnMonthlyDeductions});
+    Add({DB_SurrenderFootnote          , superior::SurrenderFootnote});
+    Add({DB_PortabilityFootnote        , superior::PortabilityFootnote});
+    Add({DB_FundRateFootnote           , superior::FundRateFootnote});
+    Add({DB_IssuingCompanyFootnote     , superior::IssuingCompanyFootnote});
+    Add({DB_SubsidiaryFootnote         , superior::SubsidiaryFootnote});
+    Add({DB_PlacementAgentFootnote     , superior::PlacementAgentFootnote});
+    Add({DB_MarketingNameFootnote      , superior::MarketingNameFootnote});
+    Add({DB_GuarIssueDisclaimerNcSc    , superior::GuarIssueDisclaimerNcSc});
+    Add({DB_GuarIssueDisclaimerMd      , superior::GuarIssueDisclaimerMd});
+    Add({DB_GuarIssueDisclaimerTx      , superior::GuarIssueDisclaimerTx});
+    Add({DB_IllRegCertAgent            , superior::IllRegCertAgent});
+    Add({DB_IllRegCertAgentIl          , superior::IllRegCertAgentIl});
+    Add({DB_IllRegCertAgentTx          , superior::IllRegCertAgentTx});
+    Add({DB_IllRegCertClient           , superior::IllRegCertClient});
+    Add({DB_IllRegCertClientIl         , superior::IllRegCertClientIl});
+    Add({DB_IllRegCertClientTx         , superior::IllRegCertClientTx});
+    Add({DB_FnMaturityAge              , superior::FnMaturityAge});
+    Add({DB_FnPartialMortality         , superior::FnPartialMortality});
+    Add({DB_FnProspectus               , superior::FnProspectus});
+    Add({DB_FnInitialSpecAmt           , superior::FnInitialSpecAmt});
+    Add({DB_FnInforceAcctVal           , superior::FnInforceAcctVal});
+    Add({DB_FnInforceTaxBasis          , superior::FnInforceTaxBasis});
+    Add({DB_Fn1035Charge               , superior::Fn1035Charge});
+    Add({DB_FnMecExtraWarning          , superior::FnMecExtraWarning});
+    Add({DB_FnNotTaxAdvice             , superior::FnNotTaxAdvice});
+    Add({DB_FnNotTaxAdvice2            , superior::FnNotTaxAdvice2});
+    Add({DB_FnImf                      , superior::FnImf});
+    Add({DB_FnCensus                   , superior::FnCensus});
+    Add({DB_FnDacTax                   , superior::FnDacTax});
+    Add({DB_FnDefnLifeIns              , superior::FnDefnLifeIns});
+    Add({DB_FnBoyEoy                   , superior::FnBoyEoy});
+    Add({DB_FnGeneralAccount           , superior::FnGeneralAccount});
+    Add({DB_FnPpMemorandum             , superior::FnPpMemorandum});
+    Add({DB_FnPpAccreditedInvestor     , superior::FnPpAccreditedInvestor});
+    Add({DB_FnPpLoads                  , superior::FnPpLoads});
+    Add({DB_FnProposalUnderwriting     , superior::FnProposalUnderwriting});
+    Add({DB_FnGuaranteedPremium        , superior::FnGuaranteedPremium});
+    Add({DB_FnOmnibusDisclaimer        , superior::FnOmnibusDisclaimer});
+    Add({DB_FnInitialDbo               , superior::FnInitialDbo});
+    Add({DB_DefnGuarGenAcctRate        , superior::DefnGuarGenAcctRate});
+    Add({DB_DefnAV                     , superior::DefnAV});
+    Add({DB_DefnCSV                    , superior::DefnCSV});
+    Add({DB_DefnMec                    , superior::DefnMec});
+    Add({DB_DefnOutlay                 , superior::DefnOutlay});
+    Add({DB_DefnSpecAmt                , superior::DefnSpecAmt});
+}
+
+sample2::sample2()
+{
+    // LINGO !! Eventually, perhaps these all can be initialized
+    // to a corresponding "_term" value using some terse syntax.
+    Add({DB_PolicyForm                 , superior::policy_form_term});
+    Add({DB_PolicyFormAlternative      , 
superior::PolicyFormAlternative_term}); // LINGO !! expunge
+    Add({DB_PolicyMktgName             , superior::PolicyMktgName_term});
+    Add({DB_PolicyLegalName            , superior::PolicyLegalName_term});
+    Add({DB_InsCoShortName             , superior::InsCoShortName_term});
+    Add({DB_InsCoName                  , superior::InsCoName_term});
+    Add({DB_InsCoAddr                  , superior::InsCoAddr_term});
+    Add({DB_InsCoStreet                , superior::InsCoStreet_term});
+    Add({DB_InsCoPhone                 , superior::InsCoPhone_term});
+    Add({DB_MainUnderwriter            , superior::MainUnderwriter_term});
+    Add({DB_MainUnderwriterAddress     , 
superior::MainUnderwriterAddress_term});
+    Add({DB_CoUnderwriter              , superior::CoUnderwriter_term});
+    Add({DB_CoUnderwriterAddress       , superior::CoUnderwriterAddress_term});
+    Add({DB_AvName                     , superior::AvName_term});
+    Add({DB_CsvName                    , superior::CsvName_term});
+    Add({DB_CsvHeaderName              , superior::CsvHeaderName_term});
+    Add({DB_NoLapseProvisionName       , superior::NoLapseProvisionName_term});
+    Add({DB_ContractName               , superior::ContractName_term});
+    Add({DB_DboName                    , superior::DboName_term});
+    Add({DB_DboNameLevel               , superior::DboNameLevel_term});
+    Add({DB_DboNameIncreasing          , superior::DboNameIncreasing_term});
+    Add({DB_DboNameReturnOfPremium     , 
superior::DboNameReturnOfPremium_term});
+    Add({DB_DboNameMinDeathBenefit     , 
superior::DboNameMinDeathBenefit_term});
+    Add({DB_GenAcctName                , superior::GenAcctName_term});
+    Add({DB_GenAcctNameElaborated      , 
superior::GenAcctNameElaborated_term});
+    Add({DB_SepAcctName                , superior::SepAcctName_term});
+    Add({DB_SpecAmtName                , superior::SpecAmtName_term});
+    Add({DB_SpecAmtNameElaborated      , 
superior::SpecAmtNameElaborated_term});
+    Add({DB_UwBasisMedical             , superior::UwBasisMedical_term});
+    Add({DB_UwBasisParamedical         , superior::UwBasisParamedical_term});
+    Add({DB_UwBasisNonmedical          , superior::UwBasisNonmedical_term});
+    Add({DB_UwBasisSimplified          , superior::UwBasisSimplified_term});
+    Add({DB_UwBasisGuaranteed          , superior::UwBasisGuaranteed_term});
+    Add({DB_UwClassPreferred           , superior::UwClassPreferred_term});
+    Add({DB_UwClassStandard            , superior::UwClassStandard_term});
+    Add({DB_UwClassRated               , superior::UwClassRated_term});
+    Add({DB_UwClassUltra               , superior::UwClassUltra_term});
+    Add({DB_AccountValueFootnote       , superior::AccountValueFootnote_term});
+    Add({DB_AttainedAgeFootnote        , superior::AttainedAgeFootnote_term});
+    Add({DB_CashSurrValueFootnote      , 
superior::CashSurrValueFootnote_term});
+    Add({DB_DeathBenefitFootnote       , superior::DeathBenefitFootnote_term});
+    Add({DB_InitialPremiumFootnote     , 
superior::InitialPremiumFootnote_term});
+    Add({DB_NetPremiumFootnote         , superior::NetPremiumFootnote_term});
+    Add({DB_GrossPremiumFootnote       , superior::GrossPremiumFootnote_term});
+    Add({DB_OutlayFootnote             , superior::OutlayFootnote_term});
+    Add({DB_PolicyYearFootnote         , superior::PolicyYearFootnote_term});
+    Add({DB_ADDTerseName               , superior::ADDTerseName_term});
+    Add({DB_InsurabilityTerseName      , 
superior::InsurabilityTerseName_term});
+    Add({DB_ChildTerseName             , superior::ChildTerseName_term});
+    Add({DB_SpouseTerseName            , superior::SpouseTerseName_term});
+    Add({DB_TermTerseName              , superior::TermTerseName_term});
+    Add({DB_WaiverTerseName            , superior::WaiverTerseName_term});
+    Add({DB_AccelBftRiderTerseName     , 
superior::AccelBftRiderTerseName_term});
+    Add({DB_OverloanRiderTerseName     , 
superior::OverloanRiderTerseName_term});
+    Add({DB_ADDFootnote                , superior::ADDFootnote_term});
+    Add({DB_ChildFootnote              , superior::ChildFootnote_term});
+    Add({DB_SpouseFootnote             , superior::SpouseFootnote_term});
+    Add({DB_TermFootnote               , superior::TermFootnote_term});
+    Add({DB_WaiverFootnote             , superior::WaiverFootnote_term});
+    Add({DB_AccelBftRiderFootnote      , 
superior::AccelBftRiderFootnote_term});
+    Add({DB_OverloanRiderFootnote      , 
superior::OverloanRiderFootnote_term});
+    Add({DB_GroupQuoteShortProductName , 
superior::GroupQuoteShortProductName_term});
+    Add({DB_GroupQuoteIsNotAnOffer     , 
superior::GroupQuoteIsNotAnOffer_term});
+    Add({DB_GroupQuoteRidersFooter     , 
superior::GroupQuoteRidersFooter_term});
+    Add({DB_GroupQuotePolicyFormId     , 
superior::GroupQuotePolicyFormId_term});
+    Add({DB_GroupQuoteStateVariations  , 
superior::GroupQuoteStateVariations_term});
+    Add({DB_GroupQuoteProspectus       , superior::GroupQuoteProspectus_term});
+    Add({DB_GroupQuoteUnderwriter      , 
superior::GroupQuoteUnderwriter_term});
+    Add({DB_GroupQuoteBrokerDealer     , 
superior::GroupQuoteBrokerDealer_term});
+    Add({DB_GroupQuoteRubricMandatory  , 
superior::GroupQuoteRubricMandatory_term});
+    Add({DB_GroupQuoteRubricVoluntary  , 
superior::GroupQuoteRubricVoluntary_term});
+    Add({DB_GroupQuoteRubricFusion     , 
superior::GroupQuoteRubricFusion_term});
+    Add({DB_GroupQuoteFooterMandatory  , 
superior::GroupQuoteFooterMandatory_term});
+    Add({DB_GroupQuoteFooterVoluntary  , 
superior::GroupQuoteFooterVoluntary_term});
+    Add({DB_GroupQuoteFooterFusion     , 
superior::GroupQuoteFooterFusion_term});
+    Add({DB_MinimumPremiumFootnote     , 
superior::MinimumPremiumFootnote_term});
+    Add({DB_PremAllocationFootnote     , 
superior::PremAllocationFootnote_term});
+    Add({DB_InterestDisclaimer         , superior::InterestDisclaimer_term});
+    Add({DB_GuarMortalityFootnote      , 
superior::GuarMortalityFootnote_term});
+    Add({DB_ProductDescription         , superior::ProductDescription_term});
+    Add({DB_StableValueFootnote        , superior::StableValueFootnote_term});
+    Add({DB_NoVanishPremiumFootnote    , 
superior::NoVanishPremiumFootnote_term});
+    Add({DB_RejectPremiumFootnote      , 
superior::RejectPremiumFootnote_term});
+    Add({DB_ExpRatingFootnote          , superior::ExpRatingFootnote_term});
+    Add({DB_MortalityBlendFootnote     , 
superior::MortalityBlendFootnote_term});
+    Add({DB_HypotheticalRatesFootnote  , 
superior::HypotheticalRatesFootnote_term});
+    Add({DB_SalesLoadRefundFootnote    , 
superior::SalesLoadRefundFootnote_term});
+    Add({DB_NoLapseEverFootnote        , superior::NoLapseEverFootnote_term});
+    Add({DB_NoLapseFootnote            , superior::NoLapseFootnote_term});
+    Add({DB_CurrentValuesFootnote      , 
superior::CurrentValuesFootnote_term});
+    Add({DB_DBOption1Footnote          , superior::DBOption1Footnote_term});
+    Add({DB_DBOption2Footnote          , superior::DBOption2Footnote_term});
+    Add({DB_DBOption3Footnote          , superior::DBOption3Footnote_term});
+    Add({DB_MinDeathBenefitFootnote    , 
superior::MinDeathBenefitFootnote_term});
+    Add({DB_ExpRatRiskChargeFootnote   , 
superior::ExpRatRiskChargeFootnote_term});
+    Add({DB_ExchangeChargeFootnote1    , 
superior::ExchangeChargeFootnote1_term});
+    Add({DB_FlexiblePremiumFootnote    , 
superior::FlexiblePremiumFootnote_term});
+    Add({DB_GuaranteedValuesFootnote   , 
superior::GuaranteedValuesFootnote_term});
+    Add({DB_CreditingRateFootnote      , 
superior::CreditingRateFootnote_term});
+    Add({DB_GrossRateFootnote          , superior::GrossRateFootnote_term});
+    Add({DB_NetRateFootnote            , superior::NetRateFootnote_term});
+    Add({DB_MecFootnote                , superior::MecFootnote_term});
+    Add({DB_GptFootnote                , superior::GptFootnote_term});
+    Add({DB_MidpointValuesFootnote     , 
superior::MidpointValuesFootnote_term});
+    Add({DB_SinglePremiumFootnote      , 
superior::SinglePremiumFootnote_term});
+    Add({DB_MonthlyChargesFootnote     , 
superior::MonthlyChargesFootnote_term});
+    Add({DB_UltCreditingRateFootnote   , 
superior::UltCreditingRateFootnote_term});
+    Add({DB_UltCreditingRateHeader     , 
superior::UltCreditingRateHeader_term});
+    Add({DB_MaxNaarFootnote            , superior::MaxNaarFootnote_term});
+    Add({DB_PremTaxSurrChgFootnote     , 
superior::PremTaxSurrChgFootnote_term});
+    Add({DB_PolicyFeeFootnote          , superior::PolicyFeeFootnote_term});
+    Add({DB_AssetChargeFootnote        , superior::AssetChargeFootnote_term});
+    Add({DB_InvestmentIncomeFootnote   , 
superior::InvestmentIncomeFootnote_term});
+    Add({DB_IrrDbFootnote              , superior::IrrDbFootnote_term});
+    Add({DB_IrrCsvFootnote             , superior::IrrCsvFootnote_term});
+    Add({DB_MortalityChargesFootnote   , 
superior::MortalityChargesFootnote_term});
+    Add({DB_LoanAndWithdrawalFootnote  , 
superior::LoanAndWithdrawalFootnote_term});
+    Add({DB_LoanFootnote               , superior::LoanFootnote_term});
+    Add({DB_ImprimaturPresale          , superior::ImprimaturPresale_term});
+    Add({DB_ImprimaturPresaleComposite , 
superior::ImprimaturPresaleComposite_term});
+    Add({DB_ImprimaturInforce          , superior::ImprimaturInforce_term});
+    Add({DB_ImprimaturInforceComposite , 
superior::ImprimaturInforceComposite_term});
+    Add({DB_StateMarketingImprimatur   , 
superior::StateMarketingImprimatur_term});
+    Add({DB_NonGuaranteedFootnote      , 
superior::NonGuaranteedFootnote_term});
+    Add({DB_NonGuaranteedFootnote1     , 
superior::NonGuaranteedFootnote1_term});
+    Add({DB_NonGuaranteedFootnote1Tx   , 
superior::NonGuaranteedFootnote1Tx_term});
+    Add({DB_FnMonthlyDeductions        , superior::FnMonthlyDeductions_term});
+    Add({DB_SurrenderFootnote          , superior::SurrenderFootnote_term});
+    Add({DB_PortabilityFootnote        , superior::PortabilityFootnote_term});
+    Add({DB_FundRateFootnote           , superior::FundRateFootnote_term});
+    Add({DB_IssuingCompanyFootnote     , 
superior::IssuingCompanyFootnote_term});
+    Add({DB_SubsidiaryFootnote         , superior::SubsidiaryFootnote_term});
+    Add({DB_PlacementAgentFootnote     , 
superior::PlacementAgentFootnote_term});
+    Add({DB_MarketingNameFootnote      , 
superior::MarketingNameFootnote_term});
+    Add({DB_GuarIssueDisclaimerNcSc    , 
superior::GuarIssueDisclaimerNcSc_term});
+    Add({DB_GuarIssueDisclaimerMd      , 
superior::GuarIssueDisclaimerMd_term});
+    Add({DB_GuarIssueDisclaimerTx      , 
superior::GuarIssueDisclaimerTx_term});
+    Add({DB_IllRegCertAgent            , superior::IllRegCertAgent_term});
+    Add({DB_IllRegCertAgentIl          , superior::IllRegCertAgentIl_term});
+    Add({DB_IllRegCertAgentTx          , superior::IllRegCertAgentTx_term});
+    Add({DB_IllRegCertClient           , superior::IllRegCertClient_term});
+    Add({DB_IllRegCertClientIl         , superior::IllRegCertClientIl_term});
+    Add({DB_IllRegCertClientTx         , superior::IllRegCertClientTx_term});
+    Add({DB_FnMaturityAge              , superior::FnMaturityAge_term});
+    Add({DB_FnPartialMortality         , superior::FnPartialMortality_term});
+    Add({DB_FnProspectus               , superior::FnProspectus_term});
+    Add({DB_FnInitialSpecAmt           , superior::FnInitialSpecAmt_term});
+    Add({DB_FnInforceAcctVal           , superior::FnInforceAcctVal_term});
+    Add({DB_FnInforceTaxBasis          , superior::FnInforceTaxBasis_term});
+    Add({DB_Fn1035Charge               , superior::Fn1035Charge_term});
+    Add({DB_FnMecExtraWarning          , superior::FnMecExtraWarning_term});
+    Add({DB_FnNotTaxAdvice             , superior::FnNotTaxAdvice_term});
+    Add({DB_FnNotTaxAdvice2            , superior::FnNotTaxAdvice2_term});
+    Add({DB_FnImf                      , superior::FnImf_term});
+    Add({DB_FnCensus                   , superior::FnCensus_term});
+    Add({DB_FnDacTax                   , superior::FnDacTax_term});
+    Add({DB_FnDefnLifeIns              , superior::FnDefnLifeIns_term});
+    Add({DB_FnBoyEoy                   , superior::FnBoyEoy_term});
+    Add({DB_FnGeneralAccount           , superior::FnGeneralAccount_term});
+    Add({DB_FnPpMemorandum             , superior::FnPpMemorandum_term});
+    Add({DB_FnPpAccreditedInvestor     , 
superior::FnPpAccreditedInvestor_term});
+    Add({DB_FnPpLoads                  , superior::FnPpLoads_term});
+    Add({DB_FnProposalUnderwriting     , 
superior::FnProposalUnderwriting_term});
+    Add({DB_FnGuaranteedPremium        , superior::FnGuaranteedPremium_term});
+    Add({DB_FnOmnibusDisclaimer        , superior::FnOmnibusDisclaimer_term});
+    Add({DB_FnInitialDbo               , superior::FnInitialDbo_term});
+    Add({DB_DefnGuarGenAcctRate        , superior::DefnGuarGenAcctRate_term});
+    Add({DB_DefnAV                     , superior::DefnAV_term});
+    Add({DB_DefnCSV                    , superior::DefnCSV_term});
+    Add({DB_DefnMec                    , superior::DefnMec_term});
+    Add({DB_DefnOutlay                 , superior::DefnOutlay_term});
+    Add({DB_DefnSpecAmt                , superior::DefnSpecAmt_term});
+}
+
+sample2naic::sample2naic()
+{
+    Add({DB_LedgerType          , mce_ill_reg});
 }
 
 sample2finra::sample2finra()
@@ -946,7 +1483,11 @@ sample2gpp::sample2gpp()
 
 sample2ipp::sample2ipp()
 {
-    Add({DB_LedgerType          , mce_individual_private_placement});
+    Add({DB_LedgerType               , mce_individual_private_placement});
+    Add({DB_IrrDbFootnote            , superior::Poe0});
+    Add({DB_IrrCsvFootnote           , superior::Poe1});
+    Add({DB_MortalityChargesFootnote , superior::Poe2});
+    Add({DB_PolicyYearFootnote       , superior::Poe3});
 }
 
 sample2xyz::sample2xyz()
@@ -978,12 +1519,15 @@ sample2xyz::sample2xyz()
     Add({DB_FixedLoanRate, e_number_of_axes, dims_1111113, loanrate});
     double cv_enh[3] = {0.10, 0.05, 0.00};
     Add({DB_CashValueEnhMult, e_number_of_axes, dims_1111113, cv_enh});
+    Add({DB_FnMaturityAge              , superior::FnMaturityAge});
+    Add({DB_FnPartialMortality         , superior::FnPartialMortality});
 }
 } // Unnamed namespace.
 
 void DBDictionary::write_database_files()
 {
     sample      ().WriteDB(AddDataDir("sample.database"));
+    sample2naic ().WriteDB(AddDataDir("sample2naic.database"));
     sample2finra().WriteDB(AddDataDir("sample2finra.database"));
     sample2prosp().WriteDB(AddDataDir("sample2prosp.database"));
     sample2gpp  ().WriteDB(AddDataDir("sample2gpp.database"));
diff --git a/dbdict.hpp b/dbdict.hpp
index cb0a885..86057fa 100644
--- a/dbdict.hpp
+++ b/dbdict.hpp
@@ -96,349 +96,521 @@ class LMI_SO DBDictionary
     //   <dbnames.hpp sed -e '/        ,DB_/!d;s/        ,DB_//' >eraseme1
     // and compare the resulting temporary files.
 
-    database_entity MinIssAge           ;
-    database_entity MaxIssAge           ;
-    database_entity MaxIncrAge          ;
-    database_entity AllowFullUw         ;
-    database_entity AllowParamedUw      ;
-    database_entity AllowNonmedUw       ;
-    database_entity AllowSimpUw         ;
-    database_entity AllowGuarUw         ;
-    database_entity SmokeOrTobacco      ;
-    database_entity AllowPreferredClass ;
-    database_entity AllowUltraPrefClass ;
-    database_entity AllowSubstdTable    ;
-    database_entity AllowFlatExtras     ;
-    database_entity AllowRatedWp        ;
-    database_entity AllowRatedAdb       ;
-    database_entity AllowRatedTerm      ;
-    database_entity AllowRetirees       ;
-    database_entity AllowUnisex         ;
-    database_entity AllowSexDistinct    ;
-    database_entity AllowUnismoke       ;
-    database_entity AllowSmokeDistinct  ;
-    database_entity StateApproved       ;
-    database_entity AllowStateXX        ;
-    database_entity AllowForeign        ;
-    database_entity GroupIndivSelection ;
-    database_entity TxCallsGuarUwSubstd ;
-    database_entity Allowable           ;
-    database_entity AllowCvat           ;
-    database_entity AllowGpt            ;
-    database_entity AllowNo7702         ;
-    database_entity Irc7702Obreption    ;
-    database_entity CorridorWhence      ;
-    database_entity Irc7702NspWhence    ;
-    database_entity SevenPayWhence      ;
-    database_entity Irc7702QWhence      ;
-    database_entity CorridorTable       ;
-    database_entity Irc7702NspTable     ;
-    database_entity SevenPayTable       ;
-    database_entity Irc7702QTable       ;
-    database_entity Irc7702QAxisGender  ;
-    database_entity Irc7702QAxisSmoking ;
-    database_entity RatingsAffect7702   ;
-    database_entity CvatMatChangeDefn   ;
-    database_entity GptMatChangeDefn    ;
-    database_entity Irc7702BftIsSpecAmt ;
-    database_entity RiskyInitial7702Db  ;
-    database_entity Irc7702Endowment    ;
-    database_entity Effective7702DboRop ;
-    database_entity TermIsQABOrDb7702   ;
-    database_entity TermIsQABOrDb7702A  ;
-    database_entity GioIsQAB            ;
-    database_entity AdbIsQAB            ;
-    database_entity SpouseRiderIsQAB    ;
-    database_entity ChildRiderIsQAB     ;
-    database_entity WpIsQAB             ;
-    database_entity CsoEra              ;
-    database_entity CsoMisprint         ;
-    database_entity GuarCoiWhence       ;
-    database_entity GuarCoiTable        ;
-    database_entity GuarCoiIsAnnual     ;
-    database_entity GuarCoiMultiplier   ;
-    database_entity CurrCoiTable        ;
-    database_entity CurrCoiIsAnnual     ;
-    database_entity MinInputCoiMult     ;
-    database_entity CurrCoiMultiplier   ;
-    database_entity UnusualCoiBanding   ;
-    database_entity CurrCoiTable0Limit  ;
-    database_entity CurrCoiTable1       ;
-    database_entity CurrCoiTable1Limit  ;
-    database_entity CurrCoiTable2       ;
-    database_entity MdptCoiTable        ;
-    database_entity MdptCoiIsAnnual     ;
-    database_entity CoiNyMinTable       ;
-    database_entity UseNyCoiFloor       ;
-    database_entity MaxMonthlyCoiRate   ;
-    database_entity GuarCoiCeiling      ;
-    database_entity CoiGuarIsMin        ;
-    database_entity SubstdTableMult     ;
-    database_entity SubstdTableMultTable;
-    database_entity CoiUpper12Method    ;
-    database_entity CoiInforceReentry   ;
-    database_entity CoiResetMinDate     ;
-    database_entity CoiResetMaxDate     ;
-    database_entity AllowMortBlendSex   ;
-    database_entity AllowMortBlendSmoke ;
-    database_entity GuarInt             ;
-    database_entity NaarDiscount        ;
-    database_entity GuarIntSpread       ;
-    database_entity GuarMandE           ;
-    database_entity CurrIntSpread       ;
-    database_entity CurrMandE           ;
-    database_entity GenAcctIntBonus     ;
-    database_entity BonusInt            ;
-    database_entity IntFloor            ;
-    database_entity AllowGenAcct        ;
-    database_entity AllowSepAcct        ;
-    database_entity AllowGenAcctEarnRate;
-    database_entity AllowSepAcctNetRate ;
-    database_entity MaxGenAcctRate      ;
-    database_entity MaxSepAcctRate      ;
-    database_entity SepAcctSpreadMethod ;
-    database_entity IntSpreadMode       ;
-    database_entity DynamicMandE        ;
-    database_entity AllowAmortPremLoad  ;
-    database_entity LoadAmortFundCharge ;
-    database_entity AllowImfOverride    ;
-    database_entity AssetChargeType     ;
-    database_entity StableValFundCharge ;
-    database_entity GuarFundAdminChg    ;
-    database_entity CurrFundAdminChg    ;
-    database_entity FundCharge          ;
-    database_entity GuarMonthlyPolFee   ;
-    database_entity GuarAnnualPolFee    ;
-    database_entity GuarPremLoadTgt     ;
-    database_entity GuarPremLoadExc     ;
-    database_entity GuarPremLoadTgtRfd  ;
-    database_entity GuarPremLoadExcRfd  ;
-    database_entity GuarSpecAmtLoad     ;
-    database_entity GuarSpecAmtLoadTable;
-    database_entity GuarAcctValLoad     ;
-    database_entity CurrMonthlyPolFee   ;
-    database_entity CurrAnnualPolFee    ;
-    database_entity CurrPremLoadTgt     ;
-    database_entity CurrPremLoadExc     ;
-    database_entity CurrPremLoadTgtRfd  ;
-    database_entity CurrPremLoadExcRfd  ;
-    database_entity CurrSpecAmtLoad     ;
-    database_entity CurrSpecAmtLoadTable;
-    database_entity CurrAcctValLoad     ;
-    database_entity TgtPremMonthlyPolFee;
-    database_entity LoadRfdProportion   ;
-    database_entity SpecAmtLoadLimit    ;
-    database_entity DynamicSepAcctLoad  ;
-    database_entity DynSepAcctLoadLimit ;
-    database_entity DacTaxFundCharge    ;
-    database_entity DacTaxPremLoad      ;
-    database_entity PremTaxFundCharge   ;
-    database_entity PremTaxLoad         ;
-    database_entity WaivePremTaxInt1035 ;
-    database_entity PremTaxRetalLimit   ;
-    database_entity PremTaxTierGroup    ;
-    database_entity PremTaxTierPeriod   ;
-    database_entity PremTaxTierNonDecr  ;
-    database_entity PremTaxAmortPeriod  ;
-    database_entity PremTaxAmortIntRate ;
-    database_entity PremTaxRate         ;
-    database_entity PremTaxState        ;
-    database_entity SurrChgOnIncr       ;
-    database_entity SurrChgOnDecr       ;
-    database_entity Has1035ExchCharge   ;
-    database_entity SnflQTable          ;
-    database_entity CoiSnflIsGuar       ;
-    database_entity SurrChgByFormula    ;
-    database_entity SurrChgPeriod       ;
-    database_entity SurrChgZeroDur      ;
-    database_entity SurrChgNlpMult      ;
-    database_entity SurrChgNlpMax       ;
-    database_entity SurrChgEaMax        ;
-    database_entity SurrChgAmort        ;
-    database_entity AllowSpecAmtIncr    ;
-    database_entity MinSpecAmtIncr      ;
-    database_entity EnforceNaarLimit    ;
-    database_entity MinSpecAmt          ;
-    database_entity MinIssSpecAmt       ;
-    database_entity MinIssBaseSpecAmt   ;
-    database_entity MinRenlSpecAmt      ;
-    database_entity MinRenlBaseSpecAmt  ;
-    database_entity MaxIssSpecAmt       ;
-    database_entity MaxRenlSpecAmt      ;
-    database_entity AllowDboLvl         ;
-    database_entity AllowDboInc         ;
-    database_entity AllowDboRop         ;
-    database_entity AllowDboMdb         ;
-    database_entity DboLvlChangeToWhat  ;
-    database_entity DboLvlChangeMethod  ;
-    database_entity DboIncChangeToWhat  ;
-    database_entity DboIncChangeMethod  ;
-    database_entity DboRopChangeToWhat  ;
-    database_entity DboRopChangeMethod  ;
-    database_entity DboMdbChangeToWhat  ;
-    database_entity DboMdbChangeMethod  ;
-    database_entity AllowChangeToDbo2   ;
-    database_entity DboChgCanIncrSpecAmt;
-    database_entity DboChgCanDecrSpecAmt;
-    database_entity AllowExtEndt        ;
-    database_entity AllowTerm           ;
-    database_entity GuarTermTable       ;
-    database_entity TermTable           ;
-    database_entity TermMinIssAge       ;
-    database_entity TermMaxIssAge       ;
-    database_entity TermIsNotRider      ;
-    database_entity TermCanLapse        ;
-    database_entity TermForcedConvAge   ;
-    database_entity TermForcedConvDur   ;
-    database_entity MaxTermProportion   ;
-    database_entity TermCoiRate         ;
-    database_entity TermPremRate        ;
-    database_entity AllowWp             ;
-    database_entity WpTable             ;
-    database_entity WpMinIssAge         ;
-    database_entity WpMaxIssAge         ;
-    database_entity WpLimit             ;
-    database_entity WpCoiRate           ;
-    database_entity WpPremRate          ;
-    database_entity WpChargeMethod      ;
-    database_entity AllowAdb            ;
-    database_entity AdbTable            ;
-    database_entity AdbMinIssAge        ;
-    database_entity AdbMaxIssAge        ;
-    database_entity AdbLimit            ;
-    database_entity AdbCoiRate          ;
-    database_entity AdbPremRate         ;
-    database_entity AllowSpouseRider    ;
-    database_entity SpouseRiderMinAmt   ;
-    database_entity SpouseRiderMaxAmt   ;
-    database_entity SpouseRiderMinIssAge;
-    database_entity SpouseRiderMaxIssAge;
-    database_entity SpouseRiderGuarTable;
-    database_entity SpouseRiderTable    ;
-    database_entity AllowChildRider     ;
-    database_entity ChildRiderMinAmt    ;
-    database_entity ChildRiderMaxAmt    ;
-    database_entity ChildRiderTable     ;
-    database_entity AllowWd             ;
-    database_entity WdFee               ;
-    database_entity WdFeeRate           ;
-    database_entity FreeWdProportion    ;
-    database_entity MinWd               ;
-    database_entity MaxWdGenAcctValMult ;
-    database_entity MaxWdSepAcctValMult ;
-    database_entity MaxWdDed            ;
-    database_entity WdDecrSpecAmtDboLvl ;
-    database_entity WdDecrSpecAmtDboInc ;
-    database_entity WdDecrSpecAmtDboRop ;
-    database_entity FirstWdMonth        ;
-    database_entity AllowLoan           ;
-    database_entity AllowPrefLoan       ;
-    database_entity AllowFixedLoan      ;
-    database_entity AllowVlr            ;
-    database_entity FixedLoanRate       ;
-    database_entity MaxVlrRate          ;
-    database_entity MinVlrRate          ;
-    database_entity MaxLoanAcctValMult  ;
-    database_entity MaxLoanDed          ;
-    database_entity FirstPrefLoanYear   ;
-    database_entity PrefLoanRateDecr    ;
-    database_entity GuarPrefLoanSpread  ;
-    database_entity GuarRegLoanSpread   ;
-    database_entity CurrPrefLoanSpread  ;
-    database_entity CurrRegLoanSpread   ;
-    database_entity FirstLoanMonth      ;
-    database_entity MinPremType         ;
-    database_entity MinPremTable        ;
-    database_entity MinPremIntSpread    ;
-    database_entity SplitMinPrem        ;
-    database_entity UnsplitSplitMinPrem ;
-    database_entity ErNotionallyPaysTerm;
-    database_entity TgtPremType         ;
-    database_entity TgtPremTable        ;
-    database_entity TgtPremFixedAtIssue ;
-    database_entity TgtPremIgnoreSubstd ;
-    database_entity MinPmt              ;
-    database_entity IsSinglePremium     ;
-    database_entity NoLapseMinDur       ;
-    database_entity NoLapseMinAge       ;
-    database_entity NoLapseUnratedOnly  ;
-    database_entity NoLapseDboLvlOnly   ;
-    database_entity NoLapseAlwaysActive ;
-    database_entity AllowHoneymoon      ;
-    database_entity DeductionMethod     ;
-    database_entity DeductionAcct       ;
-    database_entity DistributionMethod  ;
-    database_entity DistributionAcct    ;
-    database_entity EePremMethod        ;
-    database_entity EePremAcct          ;
-    database_entity ErPremMethod        ;
-    database_entity ErPremAcct          ;
-    database_entity CalculateComp       ;
-    database_entity CompTarget          ;
-    database_entity CompExcess          ;
-    database_entity CompChargeback      ;
-    database_entity AssetComp           ;
-    database_entity AllowExtraAssetComp ;
-    database_entity AllowExtraPremComp  ;
-    database_entity AllowExpRating      ;
-    database_entity ExpRatStdDevMult    ;
-    database_entity ExpRatIbnrMult      ;
-    database_entity ExpRatCoiRetention  ;
-    database_entity ExpRatRiskCoiMult   ;
-    database_entity ExpRatAmortPeriod   ;
-    database_entity LedgerType          ;
-    database_entity Nonillustrated      ;
-    database_entity NoLongerIssued      ;
-    database_entity AgeLastOrNearest    ;
-    database_entity MaturityAge         ;
-    database_entity CashValueEnhMult    ;
-    database_entity LapseIgnoresSurrChg ;
-    database_entity DefaultProcessOrder ;
-    database_entity GroupProxyRateTable ;
+    database_entity MinIssAge                 ;
+    database_entity MaxIssAge                 ;
+    database_entity MaxIncrAge                ;
+    database_entity AllowFullUw               ;
+    database_entity AllowParamedUw            ;
+    database_entity AllowNonmedUw             ;
+    database_entity AllowSimpUw               ;
+    database_entity AllowGuarUw               ;
+    database_entity SmokeOrTobacco            ;
+    database_entity AllowPreferredClass       ;
+    database_entity AllowUltraPrefClass       ;
+    database_entity AllowSubstdTable          ;
+    database_entity AllowFlatExtras           ;
+    database_entity AllowRatedWp              ;
+    database_entity AllowRatedAdb             ;
+    database_entity AllowRatedTerm            ;
+    database_entity AllowRetirees             ;
+    database_entity AllowUnisex               ;
+    database_entity AllowSexDistinct          ;
+    database_entity AllowUnismoke             ;
+    database_entity AllowSmokeDistinct        ;
+    database_entity StateApproved             ;
+    database_entity AllowStateXX              ;
+    database_entity AllowForeign              ;
+    database_entity GroupIndivSelection       ;
+    database_entity TxCallsGuarUwSubstd       ;
+    database_entity Allowable                 ;
+    database_entity AllowCvat                 ;
+    database_entity AllowGpt                  ;
+    database_entity AllowNo7702               ;
+    database_entity Irc7702Obreption          ;
+    database_entity CorridorWhence            ;
+    database_entity Irc7702NspWhence          ;
+    database_entity SevenPayWhence            ;
+    database_entity Irc7702QWhence            ;
+    database_entity CorridorTable             ;
+    database_entity Irc7702NspTable           ;
+    database_entity SevenPayTable             ;
+    database_entity Irc7702QTable             ;
+    database_entity Irc7702QAxisGender        ;
+    database_entity Irc7702QAxisSmoking       ;
+    database_entity RatingsAffect7702         ;
+    database_entity CvatMatChangeDefn         ;
+    database_entity GptMatChangeDefn          ;
+    database_entity Irc7702BftIsSpecAmt       ;
+    database_entity RiskyInitial7702Db        ;
+    database_entity Irc7702Endowment          ;
+    database_entity Effective7702DboRop       ;
+    database_entity TermIsQABOrDb7702         ;
+    database_entity TermIsQABOrDb7702A        ;
+    database_entity GioIsQAB                  ;
+    database_entity AdbIsQAB                  ;
+    database_entity SpouseRiderIsQAB          ;
+    database_entity ChildRiderIsQAB           ;
+    database_entity WpIsQAB                   ;
+    database_entity CsoEra                    ;
+    database_entity CsoMisprint               ;
+    database_entity GuarCoiWhence             ;
+    database_entity GuarCoiTable              ;
+    database_entity GuarCoiIsAnnual           ;
+    database_entity GuarCoiMultiplier         ;
+    database_entity CurrCoiTable              ;
+    database_entity CurrCoiIsAnnual           ;
+    database_entity MinInputCoiMult           ;
+    database_entity CurrCoiMultiplier         ;
+    database_entity UnusualCoiBanding         ;
+    database_entity CurrCoiTable0Limit        ;
+    database_entity CurrCoiTable1             ;
+    database_entity CurrCoiTable1Limit        ;
+    database_entity CurrCoiTable2             ;
+    database_entity MdptCoiTable              ;
+    database_entity MdptCoiIsAnnual           ;
+    database_entity CoiNyMinTable             ;
+    database_entity UseNyCoiFloor             ;
+    database_entity MaxMonthlyCoiRate         ;
+    database_entity GuarCoiCeiling            ;
+    database_entity CoiGuarIsMin              ;
+    database_entity SubstdTableMult           ;
+    database_entity SubstdTableMultTable      ;
+    database_entity CoiUpper12Method          ;
+    database_entity CoiInforceReentry         ;
+    database_entity CoiResetMinDate           ;
+    database_entity CoiResetMaxDate           ;
+    database_entity AllowMortBlendSex         ;
+    database_entity AllowMortBlendSmoke       ;
+    database_entity GuarInt                   ;
+    database_entity NaarDiscount              ;
+    database_entity GuarIntSpread             ;
+    database_entity GuarMandE                 ;
+    database_entity CurrIntSpread             ;
+    database_entity CurrMandE                 ;
+    database_entity GenAcctIntBonus           ;
+    database_entity BonusInt                  ;
+    database_entity IntFloor                  ;
+    database_entity AllowGenAcct              ;
+    database_entity AllowSepAcct              ;
+    database_entity AllowGenAcctEarnRate      ;
+    database_entity AllowSepAcctNetRate       ;
+    database_entity MaxGenAcctRate            ;
+    database_entity MaxSepAcctRate            ;
+    database_entity SepAcctSpreadMethod       ;
+    database_entity IntSpreadMode             ;
+    database_entity DynamicMandE              ;
+    database_entity AllowAmortPremLoad        ;
+    database_entity LoadAmortFundCharge       ;
+    database_entity AllowImfOverride          ;
+    database_entity AssetChargeType           ;
+    database_entity StableValFundCharge       ;
+    database_entity GuarFundAdminChg          ;
+    database_entity CurrFundAdminChg          ;
+    database_entity FundCharge                ;
+    database_entity GuarMonthlyPolFee         ;
+    database_entity GuarAnnualPolFee          ;
+    database_entity GuarPremLoadTgt           ;
+    database_entity GuarPremLoadExc           ;
+    database_entity GuarPremLoadTgtRfd        ;
+    database_entity GuarPremLoadExcRfd        ;
+    database_entity GuarSpecAmtLoad           ;
+    database_entity GuarSpecAmtLoadTable      ;
+    database_entity GuarAcctValLoad           ;
+    database_entity CurrMonthlyPolFee         ;
+    database_entity CurrAnnualPolFee          ;
+    database_entity CurrPremLoadTgt           ;
+    database_entity CurrPremLoadExc           ;
+    database_entity CurrPremLoadTgtRfd        ;
+    database_entity CurrPremLoadExcRfd        ;
+    database_entity CurrSpecAmtLoad           ;
+    database_entity CurrSpecAmtLoadTable      ;
+    database_entity CurrAcctValLoad           ;
+    database_entity TgtPremMonthlyPolFee      ;
+    database_entity LoadRfdProportion         ;
+    database_entity SpecAmtLoadLimit          ;
+    database_entity DynamicSepAcctLoad        ;
+    database_entity DynSepAcctLoadLimit       ;
+    database_entity DacTaxFundCharge          ;
+    database_entity DacTaxPremLoad            ;
+    database_entity PremTaxFundCharge         ;
+    database_entity PremTaxLoad               ;
+    database_entity WaivePremTaxInt1035       ;
+    database_entity PremTaxRetalLimit         ;
+    database_entity PremTaxTierGroup          ;
+    database_entity PremTaxTierPeriod         ;
+    database_entity PremTaxTierNonDecr        ;
+    database_entity PremTaxAmortPeriod        ;
+    database_entity PremTaxAmortIntRate       ;
+    database_entity PremTaxRate               ;
+    database_entity PremTaxState              ;
+    database_entity SurrChgOnIncr             ;
+    database_entity SurrChgOnDecr             ;
+    database_entity Has1035ExchCharge         ;
+    database_entity SnflQTable                ;
+    database_entity CoiSnflIsGuar             ;
+    database_entity SurrChgByFormula          ;
+    database_entity SurrChgPeriod             ;
+    database_entity SurrChgZeroDur            ;
+    database_entity SurrChgNlpMult            ;
+    database_entity SurrChgNlpMax             ;
+    database_entity SurrChgEaMax              ;
+    database_entity SurrChgAmort              ;
+    database_entity AllowSpecAmtIncr          ;
+    database_entity MinSpecAmtIncr            ;
+    database_entity EnforceNaarLimit          ;
+    database_entity MinSpecAmt                ;
+    database_entity MinIssSpecAmt             ;
+    database_entity MinIssBaseSpecAmt         ;
+    database_entity MinRenlSpecAmt            ;
+    database_entity MinRenlBaseSpecAmt        ;
+    database_entity MaxIssSpecAmt             ;
+    database_entity MaxRenlSpecAmt            ;
+    database_entity AllowDboLvl               ;
+    database_entity AllowDboInc               ;
+    database_entity AllowDboRop               ;
+    database_entity AllowDboMdb               ;
+    database_entity DboLvlChangeToWhat        ;
+    database_entity DboLvlChangeMethod        ;
+    database_entity DboIncChangeToWhat        ;
+    database_entity DboIncChangeMethod        ;
+    database_entity DboRopChangeToWhat        ;
+    database_entity DboRopChangeMethod        ;
+    database_entity DboMdbChangeToWhat        ;
+    database_entity DboMdbChangeMethod        ;
+    database_entity AllowChangeToDbo2         ;
+    database_entity DboChgCanIncrSpecAmt      ;
+    database_entity DboChgCanDecrSpecAmt      ;
+    database_entity AllowExtEndt              ;
+    database_entity AllowTerm                 ;
+    database_entity GuarTermTable             ;
+    database_entity TermTable                 ;
+    database_entity TermMinIssAge             ;
+    database_entity TermMaxIssAge             ;
+    database_entity TermIsNotRider            ;
+    database_entity TermCanLapse              ;
+    database_entity TermForcedConvAge         ;
+    database_entity TermForcedConvDur         ;
+    database_entity MaxTermProportion         ;
+    database_entity TermCoiRate               ;
+    database_entity TermPremRate              ;
+    database_entity AllowWp                   ;
+    database_entity WpTable                   ;
+    database_entity WpMinIssAge               ;
+    database_entity WpMaxIssAge               ;
+    database_entity WpLimit                   ;
+    database_entity WpCoiRate                 ;
+    database_entity WpPremRate                ;
+    database_entity WpChargeMethod            ;
+    database_entity AllowAdb                  ;
+    database_entity AdbTable                  ;
+    database_entity AdbMinIssAge              ;
+    database_entity AdbMaxIssAge              ;
+    database_entity AdbLimit                  ;
+    database_entity AdbCoiRate                ;
+    database_entity AdbPremRate               ;
+    database_entity AllowSpouseRider          ;
+    database_entity SpouseRiderMinAmt         ;
+    database_entity SpouseRiderMaxAmt         ;
+    database_entity SpouseRiderMinIssAge      ;
+    database_entity SpouseRiderMaxIssAge      ;
+    database_entity SpouseRiderGuarTable      ;
+    database_entity SpouseRiderTable          ;
+    database_entity AllowChildRider           ;
+    database_entity ChildRiderMinAmt          ;
+    database_entity ChildRiderMaxAmt          ;
+    database_entity ChildRiderTable           ;
+    database_entity AllowWd                   ;
+    database_entity WdFee                     ;
+    database_entity WdFeeRate                 ;
+    database_entity FreeWdProportion          ;
+    database_entity MinWd                     ;
+    database_entity MaxWdGenAcctValMult       ;
+    database_entity MaxWdSepAcctValMult       ;
+    database_entity MaxWdDed                  ;
+    database_entity WdDecrSpecAmtDboLvl       ;
+    database_entity WdDecrSpecAmtDboInc       ;
+    database_entity WdDecrSpecAmtDboRop       ;
+    database_entity FirstWdMonth              ;
+    database_entity AllowLoan                 ;
+    database_entity AllowPrefLoan             ;
+    database_entity AllowFixedLoan            ;
+    database_entity AllowVlr                  ;
+    database_entity FixedLoanRate             ;
+    database_entity MaxVlrRate                ;
+    database_entity MinVlrRate                ;
+    database_entity MaxLoanAcctValMult        ;
+    database_entity MaxLoanDed                ;
+    database_entity FirstPrefLoanYear         ;
+    database_entity PrefLoanRateDecr          ;
+    database_entity GuarPrefLoanSpread        ;
+    database_entity GuarRegLoanSpread         ;
+    database_entity CurrPrefLoanSpread        ;
+    database_entity CurrRegLoanSpread         ;
+    database_entity FirstLoanMonth            ;
+    database_entity MinPremType               ;
+    database_entity MinPremTable              ;
+    database_entity MinPremIntSpread          ;
+    database_entity SplitMinPrem              ;
+    database_entity UnsplitSplitMinPrem       ;
+    database_entity ErNotionallyPaysTerm      ;
+    database_entity TgtPremType               ;
+    database_entity TgtPremTable              ;
+    database_entity TgtPremFixedAtIssue       ;
+    database_entity TgtPremIgnoreSubstd       ;
+    database_entity MinPmt                    ;
+    database_entity IsSinglePremium           ;
+    database_entity NoLapseMinDur             ;
+    database_entity NoLapseMinAge             ;
+    database_entity NoLapseUnratedOnly        ;
+    database_entity NoLapseDboLvlOnly         ;
+    database_entity NoLapseAlwaysActive       ;
+    database_entity AllowHoneymoon            ;
+    database_entity DeductionMethod           ;
+    database_entity DeductionAcct             ;
+    database_entity DistributionMethod        ;
+    database_entity DistributionAcct          ;
+    database_entity EePremMethod              ;
+    database_entity EePremAcct                ;
+    database_entity ErPremMethod              ;
+    database_entity ErPremAcct                ;
+    database_entity CalculateComp             ;
+    database_entity CompTarget                ;
+    database_entity CompExcess                ;
+    database_entity CompChargeback            ;
+    database_entity AssetComp                 ;
+    database_entity AllowExtraAssetComp       ;
+    database_entity AllowExtraPremComp        ;
+    database_entity AllowExpRating            ;
+    database_entity ExpRatStdDevMult          ;
+    database_entity ExpRatIbnrMult            ;
+    database_entity ExpRatCoiRetention        ;
+    database_entity ExpRatRiskCoiMult         ;
+    database_entity ExpRatAmortPeriod         ;
+    database_entity LedgerType                ;
+    database_entity Nonillustrated            ;
+    database_entity NoLongerIssued            ;
+    database_entity AgeLastOrNearest          ;
+    database_entity MaturityAge               ;
+    database_entity CashValueEnhMult          ;
+    database_entity LapseIgnoresSurrChg       ;
+    database_entity DefaultProcessOrder       ;
+    database_entity GroupProxyRateTable       ;
     // SOMEDAY !! This support request:
     //   https://savannah.nongnu.org/support/?105593
     // would move the choice of partial mortality table to the GUI and
     // make this entity superfluous. 'GroupProxyRateTable' could be
     // treated the same way.
-    database_entity PartialMortTable    ;
-    database_entity UsePolicyFormAlt    ;
-    database_entity AllowGroupQuote     ;
-    database_entity WeightClass         ;
-    database_entity WeightGender        ;
-    database_entity WeightSmoking       ;
-    database_entity WeightAge           ;
-    database_entity WeightSpecAmt       ;
-    database_entity WeightState         ;
-    database_entity FullExpPol          ;
-    database_entity FullExpPrem         ;
-    database_entity FullExpDumpin       ;
-    database_entity FullExpSpecAmt      ;
-    database_entity VarExpPol           ;
-    database_entity VarExpPrem          ;
-    database_entity VarExpDumpin        ;
-    database_entity VarExpSpecAmt       ;
-    database_entity ExpSpecAmtLimit     ;
-    database_entity MedicalProportion   ;
-    database_entity UwTestCost          ;
-    database_entity VxBasicQTable       ;
-    database_entity VxDeficQTable       ;
-    database_entity VxTaxQTable         ;
-    database_entity StatVxInt           ;
-    database_entity TaxVxInt            ;
-    database_entity StatVxQ             ;
-    database_entity TaxVxQ              ;
-    database_entity DeficVxQ            ;
-    database_entity SnflQ               ;
-    database_entity LapseRate           ;
-    database_entity ReqSurpNaar         ;
-    database_entity ReqSurpVx           ;
-    database_entity LicFitRate          ;
-    database_entity LicDacTaxRate       ;
-    database_entity GdbVxMethod         ;
-    database_entity PrimaryHurdle       ;
-    database_entity SecondaryHurdle     ;
+    database_entity PartialMortTable          ;
+    database_entity UsePolicyFormAlt          ; // LINGO !! expunge
+    database_entity AllowGroupQuote           ;
+    database_entity PolicyForm                ;
+    database_entity PolicyFormAlternative     ; // LINGO !! expunge
+    database_entity PolicyMktgName            ;
+    database_entity PolicyLegalName           ;
+    database_entity InsCoShortName            ;
+    database_entity InsCoName                 ;
+    database_entity InsCoAddr                 ;
+    database_entity InsCoStreet               ;
+    database_entity InsCoPhone                ;
+    database_entity MainUnderwriter           ;
+    database_entity MainUnderwriterAddress    ;
+    database_entity CoUnderwriter             ;
+    database_entity CoUnderwriterAddress      ;
+    database_entity AvName                    ;
+    database_entity CsvName                   ;
+    database_entity CsvHeaderName             ;
+    database_entity NoLapseProvisionName      ;
+    database_entity ContractName              ;
+    database_entity DboName                   ;
+    database_entity DboNameLevel              ;
+    database_entity DboNameIncreasing         ;
+    database_entity DboNameReturnOfPremium    ;
+    database_entity DboNameMinDeathBenefit    ;
+    database_entity GenAcctName               ;
+    database_entity GenAcctNameElaborated     ;
+    database_entity SepAcctName               ;
+    database_entity SpecAmtName               ;
+    database_entity SpecAmtNameElaborated     ;
+    database_entity UwBasisMedical            ;
+    database_entity UwBasisParamedical        ;
+    database_entity UwBasisNonmedical         ;
+    database_entity UwBasisSimplified         ;
+    database_entity UwBasisGuaranteed         ;
+    database_entity UwClassPreferred          ;
+    database_entity UwClassStandard           ;
+    database_entity UwClassRated              ;
+    database_entity UwClassUltra              ;
+    database_entity AccountValueFootnote      ;
+    database_entity AttainedAgeFootnote       ;
+    database_entity CashSurrValueFootnote     ;
+    database_entity DeathBenefitFootnote      ;
+    database_entity InitialPremiumFootnote    ;
+    database_entity NetPremiumFootnote        ;
+    database_entity GrossPremiumFootnote      ;
+    database_entity OutlayFootnote            ;
+    database_entity PolicyYearFootnote        ;
+    database_entity ADDTerseName              ;
+    database_entity InsurabilityTerseName     ;
+    database_entity ChildTerseName            ;
+    database_entity SpouseTerseName           ;
+    database_entity TermTerseName             ;
+    database_entity WaiverTerseName           ;
+    database_entity AccelBftRiderTerseName    ;
+    database_entity OverloanRiderTerseName    ;
+    database_entity ADDFootnote               ;
+    database_entity ChildFootnote             ;
+    database_entity SpouseFootnote            ;
+    database_entity TermFootnote              ;
+    database_entity WaiverFootnote            ;
+    database_entity AccelBftRiderFootnote     ;
+    database_entity OverloanRiderFootnote     ;
+    database_entity GroupQuoteShortProductName;
+    database_entity GroupQuoteIsNotAnOffer    ;
+    database_entity GroupQuoteRidersFooter    ;
+    database_entity GroupQuotePolicyFormId    ;
+    database_entity GroupQuoteStateVariations ;
+    database_entity GroupQuoteProspectus      ;
+    database_entity GroupQuoteUnderwriter     ;
+    database_entity GroupQuoteBrokerDealer    ;
+    database_entity GroupQuoteRubricMandatory ;
+    database_entity GroupQuoteRubricVoluntary ;
+    database_entity GroupQuoteRubricFusion    ;
+    database_entity GroupQuoteFooterMandatory ;
+    database_entity GroupQuoteFooterVoluntary ;
+    database_entity GroupQuoteFooterFusion    ;
+    database_entity MinimumPremiumFootnote    ;
+    database_entity PremAllocationFootnote    ;
+    database_entity InterestDisclaimer        ;
+    database_entity GuarMortalityFootnote     ;
+    database_entity ProductDescription        ;
+    database_entity StableValueFootnote       ;
+    database_entity NoVanishPremiumFootnote   ;
+    database_entity RejectPremiumFootnote     ;
+    database_entity ExpRatingFootnote         ;
+    database_entity MortalityBlendFootnote    ;
+    database_entity HypotheticalRatesFootnote ;
+    database_entity SalesLoadRefundFootnote   ;
+    database_entity NoLapseEverFootnote       ;
+    database_entity NoLapseFootnote           ;
+    database_entity CurrentValuesFootnote     ;
+    database_entity DBOption1Footnote         ;
+    database_entity DBOption2Footnote         ;
+    database_entity DBOption3Footnote         ;
+    database_entity MinDeathBenefitFootnote   ;
+    database_entity ExpRatRiskChargeFootnote  ;
+    database_entity ExchangeChargeFootnote1   ;
+    database_entity FlexiblePremiumFootnote   ;
+    database_entity GuaranteedValuesFootnote  ;
+    database_entity CreditingRateFootnote     ;
+    database_entity GrossRateFootnote         ;
+    database_entity NetRateFootnote           ;
+    database_entity MecFootnote               ;
+    database_entity GptFootnote               ;
+    database_entity MidpointValuesFootnote    ;
+    database_entity SinglePremiumFootnote     ;
+    database_entity MonthlyChargesFootnote    ;
+    database_entity UltCreditingRateFootnote  ;
+    database_entity UltCreditingRateHeader    ;
+    database_entity MaxNaarFootnote           ;
+    database_entity PremTaxSurrChgFootnote    ;
+    database_entity PolicyFeeFootnote         ;
+    database_entity AssetChargeFootnote       ;
+    database_entity InvestmentIncomeFootnote  ;
+    database_entity IrrDbFootnote             ;
+    database_entity IrrCsvFootnote            ;
+    database_entity MortalityChargesFootnote  ;
+    database_entity LoanAndWithdrawalFootnote ;
+    database_entity LoanFootnote              ;
+    database_entity ImprimaturPresale         ;
+    database_entity ImprimaturPresaleComposite;
+    database_entity ImprimaturInforce         ;
+    database_entity ImprimaturInforceComposite;
+    database_entity StateMarketingImprimatur  ;
+    database_entity NonGuaranteedFootnote     ;
+    database_entity NonGuaranteedFootnote1    ;
+    database_entity NonGuaranteedFootnote1Tx  ;
+    database_entity FnMonthlyDeductions       ;
+    database_entity SurrenderFootnote         ;
+    database_entity PortabilityFootnote       ;
+    database_entity FundRateFootnote          ;
+    database_entity IssuingCompanyFootnote    ;
+    database_entity SubsidiaryFootnote        ;
+    database_entity PlacementAgentFootnote    ;
+    database_entity MarketingNameFootnote     ;
+    database_entity GuarIssueDisclaimerNcSc   ;
+    database_entity GuarIssueDisclaimerMd     ;
+    database_entity GuarIssueDisclaimerTx     ;
+    database_entity IllRegCertAgent           ;
+    database_entity IllRegCertAgentIl         ;
+    database_entity IllRegCertAgentTx         ;
+    database_entity IllRegCertClient          ;
+    database_entity IllRegCertClientIl        ;
+    database_entity IllRegCertClientTx        ;
+    database_entity FnMaturityAge             ;
+    database_entity FnPartialMortality        ;
+    database_entity FnProspectus              ;
+    database_entity FnInitialSpecAmt          ;
+    database_entity FnInforceAcctVal          ;
+    database_entity FnInforceTaxBasis         ;
+    database_entity Fn1035Charge              ;
+    database_entity FnMecExtraWarning         ;
+    database_entity FnNotTaxAdvice            ;
+    database_entity FnNotTaxAdvice2           ;
+    database_entity FnImf                     ;
+    database_entity FnCensus                  ;
+    database_entity FnDacTax                  ;
+    database_entity FnDefnLifeIns             ;
+    database_entity FnBoyEoy                  ;
+    database_entity FnGeneralAccount          ;
+    database_entity FnPpMemorandum            ;
+    database_entity FnPpAccreditedInvestor    ;
+    database_entity FnPpLoads                 ;
+    database_entity FnProposalUnderwriting    ;
+    database_entity FnGuaranteedPremium       ;
+    database_entity FnOmnibusDisclaimer       ;
+    database_entity FnInitialDbo              ;
+    database_entity DefnGuarGenAcctRate       ;
+    database_entity DefnAV                    ;
+    database_entity DefnCSV                   ;
+    database_entity DefnMec                   ;
+    database_entity DefnOutlay                ;
+    database_entity DefnSpecAmt               ;
+    database_entity WeightClass               ;
+    database_entity WeightGender              ;
+    database_entity WeightSmoking             ;
+    database_entity WeightAge                 ;
+    database_entity WeightSpecAmt             ;
+    database_entity WeightState               ;
+    database_entity FullExpPol                ;
+    database_entity FullExpPrem               ;
+    database_entity FullExpDumpin             ;
+    database_entity FullExpSpecAmt            ;
+    database_entity VarExpPol                 ;
+    database_entity VarExpPrem                ;
+    database_entity VarExpDumpin              ;
+    database_entity VarExpSpecAmt             ;
+    database_entity ExpSpecAmtLimit           ;
+    database_entity MedicalProportion         ;
+    database_entity UwTestCost                ;
+    database_entity VxBasicQTable             ;
+    database_entity VxDeficQTable             ;
+    database_entity VxTaxQTable               ;
+    database_entity StatVxInt                 ;
+    database_entity TaxVxInt                  ;
+    database_entity StatVxQ                   ;
+    database_entity TaxVxQ                    ;
+    database_entity DeficVxQ                  ;
+    database_entity SnflQ                     ;
+    database_entity LapseRate                 ;
+    database_entity ReqSurpNaar               ;
+    database_entity ReqSurpVx                 ;
+    database_entity LicFitRate                ;
+    database_entity LicDacTaxRate             ;
+    database_entity GdbVxMethod               ;
+    database_entity PrimaryHurdle             ;
+    database_entity SecondaryHurdle           ;
 };
 
-void LMI_SO print_databases();
+LMI_SO void print_databases();
 
 #endif // dbdict_hpp
diff --git a/dbnames.hpp b/dbnames.hpp
index f0f0a5a..c3be878 100644
--- a/dbnames.hpp
+++ b/dbnames.hpp
@@ -524,9 +524,184 @@ enum e_database_key
 
         ,DB_GroupProxyRateTable
         ,DB_PartialMortTable
-        ,DB_UsePolicyFormAlt
+        ,DB_UsePolicyFormAlt // LINGO !! expunge
         ,DB_AllowGroupQuote
 
+    ,DB_Topic_Lingo
+
+        ,DB_PolicyForm
+        ,DB_PolicyFormAlternative // LINGO !! expunge
+        ,DB_PolicyMktgName
+        ,DB_PolicyLegalName
+        ,DB_InsCoShortName
+        ,DB_InsCoName
+        ,DB_InsCoAddr
+        ,DB_InsCoStreet
+        ,DB_InsCoPhone
+        ,DB_MainUnderwriter
+        ,DB_MainUnderwriterAddress
+        ,DB_CoUnderwriter
+        ,DB_CoUnderwriterAddress
+        ,DB_AvName
+        ,DB_CsvName
+        ,DB_CsvHeaderName
+        ,DB_NoLapseProvisionName
+        ,DB_ContractName
+        ,DB_DboName
+        ,DB_DboNameLevel
+        ,DB_DboNameIncreasing
+        ,DB_DboNameReturnOfPremium
+        ,DB_DboNameMinDeathBenefit
+        ,DB_GenAcctName
+        ,DB_GenAcctNameElaborated
+        ,DB_SepAcctName
+        ,DB_SpecAmtName
+        ,DB_SpecAmtNameElaborated
+        ,DB_UwBasisMedical
+        ,DB_UwBasisParamedical
+        ,DB_UwBasisNonmedical
+        ,DB_UwBasisSimplified
+        ,DB_UwBasisGuaranteed
+        ,DB_UwClassPreferred
+        ,DB_UwClassStandard
+        ,DB_UwClassRated
+        ,DB_UwClassUltra
+        ,DB_AccountValueFootnote
+        ,DB_AttainedAgeFootnote
+        ,DB_CashSurrValueFootnote
+        ,DB_DeathBenefitFootnote
+        ,DB_InitialPremiumFootnote
+        ,DB_NetPremiumFootnote
+        ,DB_GrossPremiumFootnote
+        ,DB_OutlayFootnote
+        ,DB_PolicyYearFootnote
+        ,DB_ADDTerseName
+        ,DB_InsurabilityTerseName
+        ,DB_ChildTerseName
+        ,DB_SpouseTerseName
+        ,DB_TermTerseName
+        ,DB_WaiverTerseName
+        ,DB_AccelBftRiderTerseName
+        ,DB_OverloanRiderTerseName
+        ,DB_ADDFootnote
+        ,DB_ChildFootnote
+        ,DB_SpouseFootnote
+        ,DB_TermFootnote
+        ,DB_WaiverFootnote
+        ,DB_AccelBftRiderFootnote
+        ,DB_OverloanRiderFootnote
+        ,DB_GroupQuoteShortProductName
+        ,DB_GroupQuoteIsNotAnOffer
+        ,DB_GroupQuoteRidersFooter
+        ,DB_GroupQuotePolicyFormId
+        ,DB_GroupQuoteStateVariations
+        ,DB_GroupQuoteProspectus
+        ,DB_GroupQuoteUnderwriter
+        ,DB_GroupQuoteBrokerDealer
+        ,DB_GroupQuoteRubricMandatory
+        ,DB_GroupQuoteRubricVoluntary
+        ,DB_GroupQuoteRubricFusion
+        ,DB_GroupQuoteFooterMandatory
+        ,DB_GroupQuoteFooterVoluntary
+        ,DB_GroupQuoteFooterFusion
+        ,DB_MinimumPremiumFootnote
+        ,DB_PremAllocationFootnote
+        ,DB_InterestDisclaimer
+        ,DB_GuarMortalityFootnote
+        ,DB_ProductDescription
+        ,DB_StableValueFootnote
+        ,DB_NoVanishPremiumFootnote
+        ,DB_RejectPremiumFootnote
+        ,DB_ExpRatingFootnote
+        ,DB_MortalityBlendFootnote
+        ,DB_HypotheticalRatesFootnote
+        ,DB_SalesLoadRefundFootnote
+        ,DB_NoLapseEverFootnote
+        ,DB_NoLapseFootnote
+        ,DB_CurrentValuesFootnote
+        ,DB_DBOption1Footnote
+        ,DB_DBOption2Footnote
+        ,DB_DBOption3Footnote
+        ,DB_MinDeathBenefitFootnote
+        ,DB_ExpRatRiskChargeFootnote
+        ,DB_ExchangeChargeFootnote1
+        ,DB_FlexiblePremiumFootnote
+        ,DB_GuaranteedValuesFootnote
+        ,DB_CreditingRateFootnote
+        ,DB_GrossRateFootnote
+        ,DB_NetRateFootnote
+        ,DB_MecFootnote
+        ,DB_GptFootnote
+        ,DB_MidpointValuesFootnote
+        ,DB_SinglePremiumFootnote
+        ,DB_MonthlyChargesFootnote
+        ,DB_UltCreditingRateFootnote
+        ,DB_UltCreditingRateHeader
+        ,DB_MaxNaarFootnote
+        ,DB_PremTaxSurrChgFootnote
+        ,DB_PolicyFeeFootnote
+        ,DB_AssetChargeFootnote
+        ,DB_InvestmentIncomeFootnote
+        ,DB_IrrDbFootnote
+        ,DB_IrrCsvFootnote
+        ,DB_MortalityChargesFootnote
+        ,DB_LoanAndWithdrawalFootnote
+        ,DB_LoanFootnote
+        ,DB_ImprimaturPresale
+        ,DB_ImprimaturPresaleComposite
+        ,DB_ImprimaturInforce
+        ,DB_ImprimaturInforceComposite
+        ,DB_StateMarketingImprimatur
+        ,DB_NonGuaranteedFootnote
+        ,DB_NonGuaranteedFootnote1
+        ,DB_NonGuaranteedFootnote1Tx
+        ,DB_FnMonthlyDeductions
+        ,DB_SurrenderFootnote
+        ,DB_PortabilityFootnote
+        ,DB_FundRateFootnote
+        ,DB_IssuingCompanyFootnote
+        ,DB_SubsidiaryFootnote
+        ,DB_PlacementAgentFootnote
+        ,DB_MarketingNameFootnote
+        ,DB_GuarIssueDisclaimerNcSc
+        ,DB_GuarIssueDisclaimerMd
+        ,DB_GuarIssueDisclaimerTx
+        ,DB_IllRegCertAgent
+        ,DB_IllRegCertAgentIl
+        ,DB_IllRegCertAgentTx
+        ,DB_IllRegCertClient
+        ,DB_IllRegCertClientIl
+        ,DB_IllRegCertClientTx
+        ,DB_FnMaturityAge
+        ,DB_FnPartialMortality
+        ,DB_FnProspectus
+        ,DB_FnInitialSpecAmt
+        ,DB_FnInforceAcctVal
+        ,DB_FnInforceTaxBasis
+        ,DB_Fn1035Charge
+        ,DB_FnMecExtraWarning
+        ,DB_FnNotTaxAdvice
+        ,DB_FnNotTaxAdvice2
+        ,DB_FnImf
+        ,DB_FnCensus
+        ,DB_FnDacTax
+        ,DB_FnDefnLifeIns
+        ,DB_FnBoyEoy
+        ,DB_FnGeneralAccount
+        ,DB_FnPpMemorandum
+        ,DB_FnPpAccreditedInvestor
+        ,DB_FnPpLoads
+        ,DB_FnProposalUnderwriting
+        ,DB_FnGuaranteedPremium
+        ,DB_FnOmnibusDisclaimer
+        ,DB_FnInitialDbo
+        ,DB_DefnGuarGenAcctRate
+        ,DB_DefnAV
+        ,DB_DefnCSV
+        ,DB_DefnMec
+        ,DB_DefnOutlay
+        ,DB_DefnSpecAmt
+
     ,DB_Topic_Weights
 
         ,DB_WeightClass
@@ -589,9 +764,9 @@ struct db_names
     char const*         LongName;
 };
 
-std::vector<db_names> const& LMI_SO GetDBNames();
+LMI_SO std::vector<db_names> const& GetDBNames();
 
-int         LMI_SO db_key_from_name(std::string const&);
-std::string LMI_SO db_name_from_key(int);
+LMI_SO int         db_key_from_name(std::string const&);
+LMI_SO std::string db_name_from_key(int);
 
 #endif // dbnames_hpp
diff --git a/dbnames.xpp b/dbnames.xpp
index aa113ab..41b3075 100644
--- a/dbnames.xpp
+++ b/dbnames.xpp
@@ -354,8 +354,181 @@
 {DB_DefaultProcessOrder,DB_Topic_Miscellanea,"DefaultProcessOrder","Default 
processing order: 0=life by life, 1=month by month [not yet implemented]",}, \
 {DB_GroupProxyRateTable,DB_Topic_Miscellanea,"GroupProxyRateTable","Group-term 
proxy rate (index in mortality table database)",}, \
 {DB_PartialMortTable,DB_Topic_Miscellanea,"PartialMortTable","Partial 
mortality table (index in mortality table database)",}, \
-{DB_UsePolicyFormAlt,DB_Topic_Miscellanea,"UsePolicyFormAlt","Use alternative 
policy-form name: 0=no, 1=yes",}, \
+{DB_UsePolicyFormAlt,DB_Topic_Miscellanea,"UsePolicyFormAlt","Use alternative 
policy-form name: 0=no, 1=yes // LINGO !! expunge",}, \
 {DB_AllowGroupQuote,DB_Topic_Miscellanea,"AllowGroupQuote","Allow group 
premium quotes: 0=no, 1=yes",}, \
+{DB_Topic_Lingo,DB_FIRST,"Lingo","Text to be dropped into report templates: 
index into lingo file",}, \
+{DB_PolicyForm,DB_Topic_Lingo,"PolicyForm","Policy form",}, \
+{DB_PolicyFormAlternative,DB_Topic_Lingo,"PolicyFormAlternative","LINGO !! 
expunge",}, \
+{DB_PolicyMktgName,DB_Topic_Lingo,"PolicyMktgName","PolicyMktgName [narrative 
descriptions desired]",}, \
+{DB_PolicyLegalName,DB_Topic_Lingo,"PolicyLegalName","PolicyLegalName",}, \
+{DB_InsCoShortName,DB_Topic_Lingo,"InsCoShortName","InsCoShortName",}, \
+{DB_InsCoName,DB_Topic_Lingo,"InsCoName","InsCoName",}, \
+{DB_InsCoAddr,DB_Topic_Lingo,"InsCoAddr","InsCoAddr",}, \
+{DB_InsCoStreet,DB_Topic_Lingo,"InsCoStreet","InsCoStreet",}, \
+{DB_InsCoPhone,DB_Topic_Lingo,"InsCoPhone","InsCoPhone",}, \
+{DB_MainUnderwriter,DB_Topic_Lingo,"MainUnderwriter","MainUnderwriter",}, \
+{DB_MainUnderwriterAddress,DB_Topic_Lingo,"MainUnderwriterAddress","MainUnderwriterAddress",},
 \
+{DB_CoUnderwriter,DB_Topic_Lingo,"CoUnderwriter","CoUnderwriter",}, \
+{DB_CoUnderwriterAddress,DB_Topic_Lingo,"CoUnderwriterAddress","CoUnderwriterAddress",},
 \
+{DB_AvName,DB_Topic_Lingo,"AvName","AvName",}, \
+{DB_CsvName,DB_Topic_Lingo,"CsvName","CsvName",}, \
+{DB_CsvHeaderName,DB_Topic_Lingo,"CsvHeaderName","CsvHeaderName",}, \
+{DB_NoLapseProvisionName,DB_Topic_Lingo,"NoLapseProvisionName","NoLapseProvisionName",},
 \
+{DB_ContractName,DB_Topic_Lingo,"ContractName","ContractName",}, \
+{DB_DboName,DB_Topic_Lingo,"DboName","DboName",}, \
+{DB_DboNameLevel,DB_Topic_Lingo,"DboNameLevel","DboNameLevel",}, \
+{DB_DboNameIncreasing,DB_Topic_Lingo,"DboNameIncreasing","DboNameIncreasing",},
 \
+{DB_DboNameReturnOfPremium,DB_Topic_Lingo,"DboNameReturnOfPremium","DboNameReturnOfPremium",},
 \
+{DB_DboNameMinDeathBenefit,DB_Topic_Lingo,"DboNameMinDeathBenefit","DboNameMinDeathBenefit",},
 \
+{DB_GenAcctName,DB_Topic_Lingo,"GenAcctName","GenAcctName",}, \
+{DB_GenAcctNameElaborated,DB_Topic_Lingo,"GenAcctNameElaborated","GenAcctNameElaborated",},
 \
+{DB_SepAcctName,DB_Topic_Lingo,"SepAcctName","SepAcctName",}, \
+{DB_SpecAmtName,DB_Topic_Lingo,"SpecAmtName","SpecAmtName",}, \
+{DB_SpecAmtNameElaborated,DB_Topic_Lingo,"SpecAmtNameElaborated","SpecAmtNameElaborated",},
 \
+{DB_UwBasisMedical,DB_Topic_Lingo,"UwBasisMedical","UwBasisMedical",}, \
+{DB_UwBasisParamedical,DB_Topic_Lingo,"UwBasisParamedical","UwBasisParamedical",},
 \
+{DB_UwBasisNonmedical,DB_Topic_Lingo,"UwBasisNonmedical","UwBasisNonmedical",},
 \
+{DB_UwBasisSimplified,DB_Topic_Lingo,"UwBasisSimplified","UwBasisSimplified",},
 \
+{DB_UwBasisGuaranteed,DB_Topic_Lingo,"UwBasisGuaranteed","UwBasisGuaranteed",},
 \
+{DB_UwClassPreferred,DB_Topic_Lingo,"UwClassPreferred","UwClassPreferred",}, \
+{DB_UwClassStandard,DB_Topic_Lingo,"UwClassStandard","UwClassStandard",}, \
+{DB_UwClassRated,DB_Topic_Lingo,"UwClassRated","UwClassRated",}, \
+{DB_UwClassUltra,DB_Topic_Lingo,"UwClassUltra","UwClassUltra",}, \
+{DB_AccountValueFootnote,DB_Topic_Lingo,"AccountValueFootnote","AccountValueFootnote",},
 \
+{DB_AttainedAgeFootnote,DB_Topic_Lingo,"AttainedAgeFootnote","AttainedAgeFootnote",},
 \
+{DB_CashSurrValueFootnote,DB_Topic_Lingo,"CashSurrValueFootnote","CashSurrValueFootnote",},
 \
+{DB_DeathBenefitFootnote,DB_Topic_Lingo,"DeathBenefitFootnote","DeathBenefitFootnote",},
 \
+{DB_InitialPremiumFootnote,DB_Topic_Lingo,"InitialPremiumFootnote","InitialPremiumFootnote",},
 \
+{DB_NetPremiumFootnote,DB_Topic_Lingo,"NetPremiumFootnote","NetPremiumFootnote",},
 \
+{DB_GrossPremiumFootnote,DB_Topic_Lingo,"GrossPremiumFootnote","GrossPremiumFootnote",},
 \
+{DB_OutlayFootnote,DB_Topic_Lingo,"OutlayFootnote","OutlayFootnote",}, \
+{DB_PolicyYearFootnote,DB_Topic_Lingo,"PolicyYearFootnote","PolicyYearFootnote",},
 \
+{DB_ADDTerseName,DB_Topic_Lingo,"ADDTerseName","ADDTerseName",}, \
+{DB_InsurabilityTerseName,DB_Topic_Lingo,"InsurabilityTerseName","InsurabilityTerseName",},
 \
+{DB_ChildTerseName,DB_Topic_Lingo,"ChildTerseName","ChildTerseName",}, \
+{DB_SpouseTerseName,DB_Topic_Lingo,"SpouseTerseName","SpouseTerseName",}, \
+{DB_TermTerseName,DB_Topic_Lingo,"TermTerseName","TermTerseName",}, \
+{DB_WaiverTerseName,DB_Topic_Lingo,"WaiverTerseName","WaiverTerseName",}, \
+{DB_AccelBftRiderTerseName,DB_Topic_Lingo,"AccelBftRiderTerseName","AccelBftRiderTerseName",},
 \
+{DB_OverloanRiderTerseName,DB_Topic_Lingo,"OverloanRiderTerseName","OverloanRiderTerseName",},
 \
+{DB_ADDFootnote,DB_Topic_Lingo,"ADDFootnote","ADDFootnote",}, \
+{DB_ChildFootnote,DB_Topic_Lingo,"ChildFootnote","ChildFootnote",}, \
+{DB_SpouseFootnote,DB_Topic_Lingo,"SpouseFootnote","SpouseFootnote",}, \
+{DB_TermFootnote,DB_Topic_Lingo,"TermFootnote","TermFootnote",}, \
+{DB_WaiverFootnote,DB_Topic_Lingo,"WaiverFootnote","WaiverFootnote",}, \
+{DB_AccelBftRiderFootnote,DB_Topic_Lingo,"AccelBftRiderFootnote","AccelBftRiderFootnote",},
 \
+{DB_OverloanRiderFootnote,DB_Topic_Lingo,"OverloanRiderFootnote","OverloanRiderFootnote",},
 \
+{DB_GroupQuoteShortProductName,DB_Topic_Lingo,"GroupQuoteShortProductName","GroupQuoteShortProductName",},
 \
+{DB_GroupQuoteIsNotAnOffer,DB_Topic_Lingo,"GroupQuoteIsNotAnOffer","GroupQuoteIsNotAnOffer",},
 \
+{DB_GroupQuoteRidersFooter,DB_Topic_Lingo,"GroupQuoteRidersFooter","GroupQuoteRidersFooter",},
 \
+{DB_GroupQuotePolicyFormId,DB_Topic_Lingo,"GroupQuotePolicyFormId","GroupQuotePolicyFormId",},
 \
+{DB_GroupQuoteStateVariations,DB_Topic_Lingo,"GroupQuoteStateVariations","GroupQuoteStateVariations",},
 \
+{DB_GroupQuoteProspectus,DB_Topic_Lingo,"GroupQuoteProspectus","GroupQuoteProspectus",},
 \
+{DB_GroupQuoteUnderwriter,DB_Topic_Lingo,"GroupQuoteUnderwriter","GroupQuoteUnderwriter",},
 \
+{DB_GroupQuoteBrokerDealer,DB_Topic_Lingo,"GroupQuoteBrokerDealer","GroupQuoteBrokerDealer",},
 \
+{DB_GroupQuoteRubricMandatory,DB_Topic_Lingo,"GroupQuoteRubricMandatory","GroupQuoteRubricMandatory",},
 \
+{DB_GroupQuoteRubricVoluntary,DB_Topic_Lingo,"GroupQuoteRubricVoluntary","GroupQuoteRubricVoluntary",},
 \
+{DB_GroupQuoteRubricFusion,DB_Topic_Lingo,"GroupQuoteRubricFusion","GroupQuoteRubricFusion",},
 \
+{DB_GroupQuoteFooterMandatory,DB_Topic_Lingo,"GroupQuoteFooterMandatory","GroupQuoteFooterMandatory",},
 \
+{DB_GroupQuoteFooterVoluntary,DB_Topic_Lingo,"GroupQuoteFooterVoluntary","GroupQuoteFooterVoluntary",},
 \
+{DB_GroupQuoteFooterFusion,DB_Topic_Lingo,"GroupQuoteFooterFusion","GroupQuoteFooterFusion",},
 \
+{DB_MinimumPremiumFootnote,DB_Topic_Lingo,"MinimumPremiumFootnote","MinimumPremiumFootnote",},
 \
+{DB_PremAllocationFootnote,DB_Topic_Lingo,"PremAllocationFootnote","PremAllocationFootnote",},
 \
+{DB_InterestDisclaimer,DB_Topic_Lingo,"InterestDisclaimer","InterestDisclaimer",},
 \
+{DB_GuarMortalityFootnote,DB_Topic_Lingo,"GuarMortalityFootnote","GuarMortalityFootnote",},
 \
+{DB_ProductDescription,DB_Topic_Lingo,"ProductDescription","ProductDescription",},
 \
+{DB_StableValueFootnote,DB_Topic_Lingo,"StableValueFootnote","StableValueFootnote",},
 \
+{DB_NoVanishPremiumFootnote,DB_Topic_Lingo,"NoVanishPremiumFootnote","NoVanishPremiumFootnote",},
 \
+{DB_RejectPremiumFootnote,DB_Topic_Lingo,"RejectPremiumFootnote","RejectPremiumFootnote",},
 \
+{DB_ExpRatingFootnote,DB_Topic_Lingo,"ExpRatingFootnote","ExpRatingFootnote",},
 \
+{DB_MortalityBlendFootnote,DB_Topic_Lingo,"MortalityBlendFootnote","MortalityBlendFootnote",},
 \
+{DB_HypotheticalRatesFootnote,DB_Topic_Lingo,"HypotheticalRatesFootnote","HypotheticalRatesFootnote",},
 \
+{DB_SalesLoadRefundFootnote,DB_Topic_Lingo,"SalesLoadRefundFootnote","SalesLoadRefundFootnote",},
 \
+{DB_NoLapseEverFootnote,DB_Topic_Lingo,"NoLapseEverFootnote","NoLapseEverFootnote",},
 \
+{DB_NoLapseFootnote,DB_Topic_Lingo,"NoLapseFootnote","NoLapseFootnote",}, \
+{DB_CurrentValuesFootnote,DB_Topic_Lingo,"CurrentValuesFootnote","CurrentValuesFootnote",},
 \
+{DB_DBOption1Footnote,DB_Topic_Lingo,"DBOption1Footnote","DBOption1Footnote",},
 \
+{DB_DBOption2Footnote,DB_Topic_Lingo,"DBOption2Footnote","DBOption2Footnote",},
 \
+{DB_DBOption3Footnote,DB_Topic_Lingo,"DBOption3Footnote","DBOption3Footnote",},
 \
+{DB_MinDeathBenefitFootnote,DB_Topic_Lingo,"MinDeathBenefitFootnote","MinDeathBenefitFootnote",},
 \
+{DB_ExpRatRiskChargeFootnote,DB_Topic_Lingo,"ExpRatRiskChargeFootnote","ExpRatRiskChargeFootnote",},
 \
+{DB_ExchangeChargeFootnote1,DB_Topic_Lingo,"ExchangeChargeFootnote1","ExchangeChargeFootnote1",},
 \
+{DB_FlexiblePremiumFootnote,DB_Topic_Lingo,"FlexiblePremiumFootnote","FlexiblePremiumFootnote",},
 \
+{DB_GuaranteedValuesFootnote,DB_Topic_Lingo,"GuaranteedValuesFootnote","GuaranteedValuesFootnote",},
 \
+{DB_CreditingRateFootnote,DB_Topic_Lingo,"CreditingRateFootnote","CreditingRateFootnote",},
 \
+{DB_GrossRateFootnote,DB_Topic_Lingo,"GrossRateFootnote","GrossRateFootnote",},
 \
+{DB_NetRateFootnote,DB_Topic_Lingo,"NetRateFootnote","NetRateFootnote",}, \
+{DB_MecFootnote,DB_Topic_Lingo,"MecFootnote","MecFootnote",}, \
+{DB_GptFootnote,DB_Topic_Lingo,"GptFootnote","GptFootnote",}, \
+{DB_MidpointValuesFootnote,DB_Topic_Lingo,"MidpointValuesFootnote","MidpointValuesFootnote",},
 \
+{DB_SinglePremiumFootnote,DB_Topic_Lingo,"SinglePremiumFootnote","SinglePremiumFootnote",},
 \
+{DB_MonthlyChargesFootnote,DB_Topic_Lingo,"MonthlyChargesFootnote","MonthlyChargesFootnote",},
 \
+{DB_UltCreditingRateFootnote,DB_Topic_Lingo,"UltCreditingRateFootnote","UltCreditingRateFootnote",},
 \
+{DB_UltCreditingRateHeader,DB_Topic_Lingo,"UltCreditingRateHeader","UltCreditingRateHeader",},
 \
+{DB_MaxNaarFootnote,DB_Topic_Lingo,"MaxNaarFootnote","MaxNaarFootnote",}, \
+{DB_PremTaxSurrChgFootnote,DB_Topic_Lingo,"PremTaxSurrChgFootnote","PremTaxSurrChgFootnote",},
 \
+{DB_PolicyFeeFootnote,DB_Topic_Lingo,"PolicyFeeFootnote","PolicyFeeFootnote",},
 \
+{DB_AssetChargeFootnote,DB_Topic_Lingo,"AssetChargeFootnote","AssetChargeFootnote",},
 \
+{DB_InvestmentIncomeFootnote,DB_Topic_Lingo,"InvestmentIncomeFootnote","InvestmentIncomeFootnote",},
 \
+{DB_IrrDbFootnote,DB_Topic_Lingo,"IrrDbFootnote","IrrDbFootnote",}, \
+{DB_IrrCsvFootnote,DB_Topic_Lingo,"IrrCsvFootnote","IrrCsvFootnote",}, \
+{DB_MortalityChargesFootnote,DB_Topic_Lingo,"MortalityChargesFootnote","MortalityChargesFootnote",},
 \
+{DB_LoanAndWithdrawalFootnote,DB_Topic_Lingo,"LoanAndWithdrawalFootnote","LoanAndWithdrawalFootnote",},
 \
+{DB_LoanFootnote,DB_Topic_Lingo,"LoanFootnote","LoanFootnote",}, \
+{DB_ImprimaturPresale,DB_Topic_Lingo,"ImprimaturPresale","ImprimaturPresale",},
 \
+{DB_ImprimaturPresaleComposite,DB_Topic_Lingo,"ImprimaturPresaleComposite","ImprimaturPresaleComposite",},
 \
+{DB_ImprimaturInforce,DB_Topic_Lingo,"ImprimaturInforce","ImprimaturInforce",},
 \
+{DB_ImprimaturInforceComposite,DB_Topic_Lingo,"ImprimaturInforceComposite","ImprimaturInforceComposite",},
 \
+{DB_StateMarketingImprimatur,DB_Topic_Lingo,"StateMarketingImprimatur","StateMarketingImprimatur",},
 \
+{DB_NonGuaranteedFootnote,DB_Topic_Lingo,"NonGuaranteedFootnote","NonGuaranteedFootnote",},
 \
+{DB_NonGuaranteedFootnote1,DB_Topic_Lingo,"NonGuaranteedFootnote1","NonGuaranteedFootnote1",},
 \
+{DB_NonGuaranteedFootnote1Tx,DB_Topic_Lingo,"NonGuaranteedFootnote1Tx","NonGuaranteedFootnote1Tx",},
 \
+{DB_FnMonthlyDeductions,DB_Topic_Lingo,"FnMonthlyDeductions","FnMonthlyDeductions",},
 \
+{DB_SurrenderFootnote,DB_Topic_Lingo,"SurrenderFootnote","SurrenderFootnote",},
 \
+{DB_PortabilityFootnote,DB_Topic_Lingo,"PortabilityFootnote","PortabilityFootnote",},
 \
+{DB_FundRateFootnote,DB_Topic_Lingo,"FundRateFootnote","FundRateFootnote",}, \
+{DB_IssuingCompanyFootnote,DB_Topic_Lingo,"IssuingCompanyFootnote","IssuingCompanyFootnote",},
 \
+{DB_SubsidiaryFootnote,DB_Topic_Lingo,"SubsidiaryFootnote","SubsidiaryFootnote",},
 \
+{DB_PlacementAgentFootnote,DB_Topic_Lingo,"PlacementAgentFootnote","PlacementAgentFootnote",},
 \
+{DB_MarketingNameFootnote,DB_Topic_Lingo,"MarketingNameFootnote","MarketingNameFootnote",},
 \
+{DB_GuarIssueDisclaimerNcSc,DB_Topic_Lingo,"GuarIssueDisclaimerNcSc","GuarIssueDisclaimerNcSc",},
 \
+{DB_GuarIssueDisclaimerMd,DB_Topic_Lingo,"GuarIssueDisclaimerMd","GuarIssueDisclaimerMd",},
 \
+{DB_GuarIssueDisclaimerTx,DB_Topic_Lingo,"GuarIssueDisclaimerTx","GuarIssueDisclaimerTx",},
 \
+{DB_IllRegCertAgent,DB_Topic_Lingo,"IllRegCertAgent","IllRegCertAgent",}, \
+{DB_IllRegCertAgentIl,DB_Topic_Lingo,"IllRegCertAgentIl","IllRegCertAgentIl",},
 \
+{DB_IllRegCertAgentTx,DB_Topic_Lingo,"IllRegCertAgentTx","IllRegCertAgentTx",},
 \
+{DB_IllRegCertClient,DB_Topic_Lingo,"IllRegCertClient","IllRegCertClient",}, \
+{DB_IllRegCertClientIl,DB_Topic_Lingo,"IllRegCertClientIl","IllRegCertClientIl",},
 \
+{DB_IllRegCertClientTx,DB_Topic_Lingo,"IllRegCertClientTx","IllRegCertClientTx",},
 \
+{DB_FnMaturityAge,DB_Topic_Lingo,"FnMaturityAge","FnMaturityAge",}, \
+{DB_FnPartialMortality,DB_Topic_Lingo,"FnPartialMortality","FnPartialMortality",},
 \
+{DB_FnProspectus,DB_Topic_Lingo,"FnProspectus","FnProspectus",}, \
+{DB_FnInitialSpecAmt,DB_Topic_Lingo,"FnInitialSpecAmt","FnInitialSpecAmt",}, \
+{DB_FnInforceAcctVal,DB_Topic_Lingo,"FnInforceAcctVal","FnInforceAcctVal",}, \
+{DB_FnInforceTaxBasis,DB_Topic_Lingo,"FnInforceTaxBasis","FnInforceTaxBasis",},
 \
+{DB_Fn1035Charge,DB_Topic_Lingo,"Fn1035Charge","Fn1035Charge",}, \
+{DB_FnMecExtraWarning,DB_Topic_Lingo,"FnMecExtraWarning","FnMecExtraWarning",},
 \
+{DB_FnNotTaxAdvice,DB_Topic_Lingo,"FnNotTaxAdvice","FnNotTaxAdvice",}, \
+{DB_FnNotTaxAdvice2,DB_Topic_Lingo,"FnNotTaxAdvice2","FnNotTaxAdvice2",}, \
+{DB_FnImf,DB_Topic_Lingo,"FnImf","FnImf",}, \
+{DB_FnCensus,DB_Topic_Lingo,"FnCensus","FnCensus",}, \
+{DB_FnDacTax,DB_Topic_Lingo,"FnDacTax","FnDacTax",}, \
+{DB_FnDefnLifeIns,DB_Topic_Lingo,"FnDefnLifeIns","FnDefnLifeIns",}, \
+{DB_FnBoyEoy,DB_Topic_Lingo,"FnBoyEoy","FnBoyEoy",}, \
+{DB_FnGeneralAccount,DB_Topic_Lingo,"FnGeneralAccount","FnGeneralAccount",}, \
+{DB_FnPpMemorandum,DB_Topic_Lingo,"FnPpMemorandum","FnPpMemorandum",}, \
+{DB_FnPpAccreditedInvestor,DB_Topic_Lingo,"FnPpAccreditedInvestor","FnPpAccreditedInvestor",},
 \
+{DB_FnPpLoads,DB_Topic_Lingo,"FnPpLoads","FnPpLoads",}, \
+{DB_FnProposalUnderwriting,DB_Topic_Lingo,"FnProposalUnderwriting","FnProposalUnderwriting",},
 \
+{DB_FnGuaranteedPremium,DB_Topic_Lingo,"FnGuaranteedPremium","FnGuaranteedPremium",},
 \
+{DB_FnOmnibusDisclaimer,DB_Topic_Lingo,"FnOmnibusDisclaimer","FnOmnibusDisclaimer",},
 \
+{DB_FnInitialDbo,DB_Topic_Lingo,"FnInitialDbo","FnInitialDbo",}, \
+{DB_DefnGuarGenAcctRate,DB_Topic_Lingo,"DefnGuarGenAcctRate","DefnGuarGenAcctRate",},
 \
+{DB_DefnAV,DB_Topic_Lingo,"DefnAV","DefnAV",}, \
+{DB_DefnCSV,DB_Topic_Lingo,"DefnCSV","DefnCSV",}, \
+{DB_DefnMec,DB_Topic_Lingo,"DefnMec","DefnMec",}, \
+{DB_DefnOutlay,DB_Topic_Lingo,"DefnOutlay","DefnOutlay",}, \
+{DB_DefnSpecAmt,DB_Topic_Lingo,"DefnSpecAmt","DefnSpecAmt",}, \
 {DB_Topic_Weights,DB_FIRST,"Weights","Weights for profit analysis cells [not 
yet implemented]",}, \
 {DB_WeightClass,DB_Topic_Weights,"WeightClass","Weight by underwriting class 
[not yet implemented]",}, \
 {DB_WeightGender,DB_Topic_Weights,"WeightGender","Weight by gender [not yet 
implemented]",}, \
diff --git a/dbvalue.cpp b/dbvalue.cpp
index b980831..fb7b6b4 100644
--- a/dbvalue.cpp
+++ b/dbvalue.cpp
@@ -28,7 +28,7 @@
 #include "contains.hpp"
 #include "dbnames.hpp"
 #include "et_vector.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "math_functions.hpp"           // lesser_of()
 #include "print_matrix.hpp"
 #include "value_cast.hpp"
diff --git a/dbvalue.hpp b/dbvalue.hpp
index 7452a89..a52189e 100644
--- a/dbvalue.hpp
+++ b/dbvalue.hpp
@@ -108,7 +108,7 @@ class LMI_SO database_entity final
     std::string         gloss_;
 };
 
-std::vector<int> const& LMI_SO maximum_database_dimensions();
+LMI_SO std::vector<int> const& maximum_database_dimensions();
 
 /*
 Some data are scalar by nature--for example, DB_MaturityAge.
diff --git a/elapsed_time.cpp b/elapsed_time.cpp
index c3df10b..7d3139e 100644
--- a/elapsed_time.cpp
+++ b/elapsed_time.cpp
@@ -19,7 +19,7 @@
 // email: <gchicares@sbcglobal.net>
 // snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "main_common.hpp"
 #include "system_command.hpp"
 #include "timer.hpp"
diff --git a/ellipsis.png b/ellipsis.png
new file mode 100644
index 0000000..4b047ea
Binary files /dev/null and b/ellipsis.png differ
diff --git a/emit_ledger.hpp b/emit_ledger.hpp
index b407a53..edeee08 100644
--- a/emit_ledger.hpp
+++ b/emit_ledger.hpp
@@ -65,7 +65,7 @@ class LMI_SO ledger_emitter final
     std::unique_ptr<group_quote_pdf_generator> group_quote_pdf_gen_;
 };
 
-double LMI_SO emit_ledger
+LMI_SO double emit_ledger
     (fs::path const& cell_filepath
     ,Ledger const&   ledger
     ,mcenum_emission emission
diff --git a/facets.hpp b/facets.hpp
index 1e64ecf..c94eabf 100644
--- a/facets.hpp
+++ b/facets.hpp
@@ -28,7 +28,7 @@
 
 #include <locale>
 
-std::locale const& LMI_SO blank_is_not_whitespace_locale();
-std::locale const& LMI_SO   tab_is_not_whitespace_locale();
+LMI_SO std::locale const& blank_is_not_whitespace_locale();
+LMI_SO std::locale const&   tab_is_not_whitespace_locale();
 
 #endif // facets_hpp
diff --git a/fenv_lmi.hpp b/fenv_lmi.hpp
index 4066462..d012363 100644
--- a/fenv_lmi.hpp
+++ b/fenv_lmi.hpp
@@ -50,11 +50,11 @@
 /// fe[gs]etprecision(). At least for now, they are meaningfully
 /// implemented for x87 only.
 ///
-///   bool LMI_SO fenv_is_valid()
+///   LMI_SO bool fenv_is_valid()
 /// If current floating-point environment matches lmi default, then
 /// return 'true'; else return 'false'.
 ///
-///   bool LMI_SO fenv_validate();
+///   LMI_SO bool fenv_validate();
 /// Make sure current floating-point environment matches lmi default.
 /// If it doesn't, then reset it to lmi default, display a message,
 /// and return 'false'; else return 'true'.
@@ -91,15 +91,15 @@ enum enum_fenv_indulgence
     ,e_fenv_indulge_0x027f  = 0x027f
     };
 
-void LMI_SO fenv_initialize();
+LMI_SO void fenv_initialize();
 
-e_ieee754_precision LMI_SO fenv_precision();
-void                LMI_SO fenv_precision(e_ieee754_precision);
+LMI_SO e_ieee754_precision fenv_precision();
+LMI_SO void                fenv_precision(e_ieee754_precision);
 
-e_ieee754_rounding LMI_SO fenv_rounding();
-void               LMI_SO fenv_rounding(e_ieee754_rounding);
+LMI_SO e_ieee754_rounding fenv_rounding();
+LMI_SO void               fenv_rounding(e_ieee754_rounding);
 
-bool LMI_SO fenv_is_valid();
-bool LMI_SO fenv_validate(enum_fenv_indulgence = e_fenv_indulge_nothing);
+LMI_SO bool fenv_is_valid();
+LMI_SO bool fenv_validate(enum_fenv_indulgence = e_fenv_indulge_nothing);
 
 #endif // fenv_lmi_hpp
diff --git a/file_command.hpp b/file_command.hpp
index 18edffd..604a621 100644
--- a/file_command.hpp
+++ b/file_command.hpp
@@ -30,7 +30,7 @@
 
 typedef void (*file_command_fp_type)(std::string const&, std::string const&);
 
-bool LMI_SO file_command_initialize(file_command_fp_type);
+LMI_SO bool file_command_initialize(file_command_fp_type);
 
 /// Execute a named command for a file, choosing the appropriate
 /// action based on the file's mime type (for gnome or kde) or its
diff --git a/finra_notes1.mst b/finra_notes1.mst
index f4c26cf..144ef65 100644
--- a/finra_notes1.mst
+++ b/finra_notes1.mst
@@ -30,12 +30,6 @@
     {{MecFootnote}}
 </p>
 
-{{^IsInforce}}
-    <p>
-    The initial 7-pay premium limit is ${{InitSevenPayPrem}}.
-    </p>
-{{/IsInforce}}
-
 <p>
     {{FnDacTax}}
 </p>
diff --git a/generate_product_files.cpp b/generate_product_files.cpp
index 0ce7db0..075c13b 100644
--- a/generate_product_files.cpp
+++ b/generate_product_files.cpp
@@ -23,6 +23,7 @@
 
 #include "dbdict.hpp"
 #include "fund_data.hpp"
+#include "lingo.hpp"
 #include "main_common.hpp"
 #include "path_utility.hpp"             // initialize_filesystem()
 #include "product_data.hpp"
@@ -40,12 +41,14 @@ int try_main(int, char*[])
 
     DBDictionary       ::write_database_files ();
     FundData           ::write_funds_files    ();
+    lingo              ::write_lingo_files    ();
     product_data       ::write_policy_files   ();
     rounding_rules     ::write_rounding_files ();
     stratified_charges ::write_strata_files   ();
 
     DBDictionary       ::write_proprietary_database_files ();
     FundData           ::write_proprietary_funds_files    ();
+    lingo              ::write_proprietary_lingo_files    ();
     product_data       ::write_proprietary_policy_files   ();
     rounding_rules     ::write_proprietary_rounding_files ();
     stratified_charges ::write_proprietary_strata_files   ();
diff --git a/global_settings.cpp b/global_settings.cpp
index 71c17b7..1e07a39 100644
--- a/global_settings.cpp
+++ b/global_settings.cpp
@@ -24,7 +24,7 @@
 #include "global_settings.hpp"
 
 #include "alert.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "path_utility.hpp"
 
 /// 6.7/4 might seem to permit instance() to call the ctor before the
diff --git a/gpt_view.cpp b/gpt_view.cpp
index d722ad5..760ae11 100644
--- a/gpt_view.cpp
+++ b/gpt_view.cpp
@@ -27,7 +27,7 @@
 #include "gpt_document.hpp"
 #include "gpt_input.hpp"
 #include "gpt_server.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "safely_dereference_as.hpp"
 #include "wx_new.hpp"
 
diff --git a/gui_test.sh b/gui_test.sh
index 5175110..b9e6672 100755
--- a/gui_test.sh
+++ b/gui_test.sh
@@ -26,10 +26,6 @@
 #   $./gui_test.sh
 # in a different session when prompted.
 
-# SOMEDAY !! 'wx_test$(EXEEXT)' doesn't return nonzero on failure,
-# so 'set -e' doesn't reliably exit after the first test failure.
-# That doesn't much matter as long as only one real command is run.
-
 set -e
 
 # This is why 'zsh' is specified in the hash-bang (the POSIX shell
diff --git a/gwc/.zshrc b/gwc/.zshrc
index 5dcfbad..ba919aa 100644
--- a/gwc/.zshrc
+++ b/gwc/.zshrc
@@ -3,7 +3,7 @@
 # To work with lmi, it is crucial to source 'set_toolchain.sh'. It's
 # deliberately not sourced here, so that it can assume that some
 # things have already been set up: for instance, it assumes that
-#   /usr/share/libtool/build-aux/config.guess
+#   /usr/share/misc/config.guess
 # is present, which need not be the case in a brand-new chroot.
 
 # Minimal system path.
diff --git a/gwc/allow_perf.sh b/gwc/allow_perf.sh
index d5dfd9c..38bc5eb 100755
--- a/gwc/allow_perf.sh
+++ b/gwc/allow_perf.sh
@@ -27,6 +27,9 @@
 # This may become useful someday, but for now...
 exit 9
 
+# See:
+#   https://lists.nongnu.org/archive/html/lmi/2020-09/msg00073.html
+
 cd /usr/bin || { printf 'failed: cd\n'; exit 3; }
 groupadd perf_users
 chgrp perf_users perf
@@ -47,5 +50,6 @@ echo "usermod -aG perf_users SomeUserName"
 # but see:
 #   https://lists.nongnu.org/archive/html/lmi/2020-09/msg00073.html
 
-# Disliked alternative:
-# echo 1 >/proc/sys/kernel/perf_event_paranoid
+# Disliked alternative, which has the virtue of actually working--see:
+#   https://lists.nongnu.org/archive/html/lmi/2020-10/msg00017.html
+echo 1 >/proc/sys/kernel/perf_event_paranoid
diff --git a/gwc/develop1.txt b/gwc/develop1.txt
index 2980f6e..9ebed81 100644
--- a/gwc/develop1.txt
+++ b/gwc/develop1.txt
@@ -110,12 +110,28 @@ git push origin odd/foo
 
   # to transplant unpushed commits to a new branch--see:
   #   https://lists.nongnu.org/archive/html/lmi/2020-09/msg00034.html
+  # this git-branch command creates a new branch with the given name,
+  # which points to HEAD; but it does not switch to that branch...
 git branch odd/foo
+  # ...and therefore this git-reset command affects the current
+  # branch (e.g., 'master'), but does not affect the new branch:
 git reset --keep origin/master
   # specify upstream on the first push (ignore if it's never pushed)
 git push --set-upstream origin odd/foo
   # ...and, if that branch is (later) to be rebased on 'master', be
   # sure to use either '--no-fork-point' or an explicit branch name.
+  #
+  # Alternatively, instead of the above commands, use the following:
+  # ...create and switch to a new branch (for unpushed commits)...
+git switch --create odd/foo
+  # ...add any further commits...
+git commit whatever.cpp
+  # ...specify upstream on first push, as above...
+git push --set-upstream origin odd/foo
+  # ...then awaken from the dream...
+git switch master
+  # ...and forget it, if desired, as above...
+git reset --keep origin/master
 
   # (to copy to a subdir before deletion, so it's in permanent history)
   # (this works only if all modified files are unique to the branch)
@@ -152,6 +168,10 @@ git checkout HEAD^ census_view.cpp
 
 git checkout .
 
+  # Switch locally to a particular SHA1
+
+git switch --detach [sha1sum]
+
   # Obliterate unpushed commits
 
 git reset --hard origin/master
@@ -178,6 +198,10 @@ git add --chmod=-x some-file-name
 git log -200 --graph --oneline --all --full-history
 git log -200 --graph --oneline --all --simplify-by-decoration
 
+  # Show git's file permissions
+
+git ls-files --stage -- gwc/*.sh |less
+
   # Second screen: only for updating local shadow copy of repository
   #
   # I use the last line repeatedly to keep my local shadow copy current
@@ -295,6 +319,23 @@ popd
 
 cd /opt/lmi/src/lmi
 
+  # Useful vim commands that are not readily remembered
+
+  # Find long lines
+
+/\%>80v.\+
+
+  # Change column 41 to a comma, for non-matching lines in a range
+  # ('|41' seems incompatible with '|' separator, so use 'cursor')
+
+:'<,'>g!/xyzzy/call cursor (0,41) | norm r,
+
+  # In a range, copy each matching line, appending "_term" to the copy
+
+:'<,'>g/^    ,/ copy . | s/^    ,[^ ]*/&_term
+
+  # All other...
+
   # Identify source files not encoded compatibly with UTF-8
 
 for z in *.?pp; (iconv -f UTF-8 -t UTF-8 $z &>/dev/null || echo $z)
diff --git a/gwc/develop2.txt b/gwc/develop2.txt
index aed1c12..0e63090 100644
--- a/gwc/develop2.txt
+++ b/gwc/develop2.txt
@@ -32,9 +32,9 @@ git commit --all -m"Another set of changes"
   # When everything is ready to share...
 
 cd /opt/lmi/proprietary
-git bundle create YourBundleName origin/master..HEAD --branches
+git bundle create YourBundleName origin/master..HEAD
   # for example (substitute your own initials)
-git bundle create /opt/lmi/blessed/$(date -u +'%Y%m%dT%H%MZ')-gwc.bundle 
origin/master..HEAD --branches
+git bundle create /opt/lmi/blessed/$(date -u +'%Y%m%dT%H%MZ')-gwc.bundle 
origin/master..HEAD
 
   # Email that bundle, then push the changes to your "blessed" repository
 
@@ -44,12 +44,32 @@ git push
 
 cd /opt/lmi/proprietary
 git bundle verify /path/where/you/saved/TheirBundleName
-git pull /path/where/you/saved/TheirBundleName
+git pull /path/where/you/saved/TheirBundleName master
 
   # ...then synchronize your "blessed" repository with your correspondent's
 
 git push
 
+  # Synchronize remote from local proprietary repository
+
+  # determine the latest commit present on the remote machine
+
+cd /opt/lmi/proprietary
+git rev-parse master
+
+  # ...and paste that SHA1 into this command on the local machine
+
+cd /opt/lmi/proprietary
+git bundle create YourCatchupBundleName PASTED..master
+  # for example (assuming the remote's 'master' is e5094a5a820)
+git bundle create /srv/cache_for_lmi/blessed/$(date -u 
+'%Y%m%dT%H%MZ')-catchup.bundle e5094a5a820^..master
+
+  # ...and then, on the remote machine, verify and pull it as for
+  # "When you receive a bundle in email" above; finally, copy its
+  # source code into the directory used by the compiler:
+
+cp -ia src/* /opt/lmi/src/products/src
+
   # Whenever a rate table changes, regenerate the binary database
 
 cd /opt/lmi/data
diff --git a/install_msw.sh b/gwc/install_posix.sh
similarity index 53%
copy from install_msw.sh
copy to gwc/install_posix.sh
index a5fd87f..15aff4b 100755
--- a/install_msw.sh
+++ b/gwc/install_posix.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# For msw, download and build lmi and required libraries.
+# For posix, download and build lmi and required libraries.
 
 # Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 
2017, 2018, 2019, 2020 Gregory W. Chicares.
 #
@@ -25,7 +25,7 @@ set -vx
 
 # To get the latest version of this script:
 #
-# wget -N 'https://git.savannah.nongnu.org/cgit/lmi.git/plain/install_msw.sh'
+# wget -N 'https://git.savannah.nongnu.org/cgit/lmi.git/plain/install_posix.sh'
 
 # To remove lmi prior to reinstalling with this script:
 #
@@ -40,20 +40,6 @@ lmi_build_type=$(/usr/share/libtool/build-aux/config.guess)
 
 minimal_path=${MINIMAL_PATH:-"/usr/bin:/bin:/usr/sbin:/sbin"}
 
-case "$lmi_build_type" in
-    (*-*-cygwin*)
-        minimal_path="$minimal_path:$(cygpath --sysdir)"
-        java -version
-        # Probably $java_path is unhelpful and should be deleted.A
-        # Avoid appending it to $PATH because it contains spaces.
-        java_path="/cygdrive/c/Program\ Files\ \(x86\)/Common\ 
Files/Oracle/Java/javapath"
-        "$java_path"/java -version
-        ;;
-    (*)
-        java -version
-        ;;
-esac
-
 export PATH="$minimal_path"
 
 # '--jobs=': big benefit for multicore (but can be overridden).
@@ -64,121 +50,24 @@ then
     export coefficiency
 fi
 
-case "$lmi_build_type" in
-    (*-*-cygwin*)
-        platform=Cygwin
-        ;;
-esac
-
-# 'config.guess' might indicate something like "x86_64-pc-wsl"
-# someday, but until then:
-case "$(uname -r)" in
-    (*Microsoft*)
-        platform=WSL
-        ;;
-esac
-
-if [ "Cygwin" = "$platform" ]
-then
-    mount
-
-    # Establish mounts carefully.
-    #
-    # A command such as
-    #   mkdir --parents /cygdrive/c/opt/lmi/src/lmi
-    # has the perverse effect of creating 'C:\cygwin\cygdrive'. To avoid
-    # that problem, '/opt' is first mounted, then unmounted.
-    #
-    # Don't remove the '/opt' directory from Cygwin's filesystem. Other
-    # programs may want to use it. Furthermore, if it were removed, then
-    # shell completion, e.g., '/op' [tab], wouldn't work.
-
-    # The 'mount' command differs greatly between Cygwin versions.
-    #
-    # Cygwin-1.5 stores all mounts in the msw registry:
-    #   HKLM for 'system' mounts
-    #   HKCU for 'user' mounts
-    # 'mount' adds 'system' mounts by default.
-    # 'mount --mount-commands' gives commands to replicate all mounts,
-    # with 'device|directory' arguments in double quotes; this script
-    # no longer supports that obsolete command option.
-    #
-    # Cygwin-1.7 stores all permanent mounts in files:
-    #   /etc/fstab for 'system' mounts
-    #   /etc/fstab.d/[user-name] for 'user' mounts
-    # 'mount' adds temporary mounts that vanish when the session ends; it
-    #   does not affect 'system' mounts (unless 'override' is specified,
-    #   which is never done here).
-    # 'mount --mount-entries' gives mount arguments to replicate all
-    # mounts, with no quotes around arguments (hence the trailing space
-    # in the 'grep' commands below).
-    #
-    # Regardless of version, only system mounts are wanted here, and they
-    # are never overridden.
-
-    restore_opt_mount=$(mount --mount-entries | grep '/opt/lmi ')
-
-    umount "/opt"
-    umount "/opt/lmi"
-    mkdir /opt
-    mount --force "C:/opt" "/opt"
-    mkdir --parents /opt/lmi/src/lmi
-    umount "/opt"
-    mount --force "C:/opt/lmi" "/opt/lmi"
-
-    [ -z "$restore_opt_mount" ] || sh -c mount "$restore_opt_mount"
-
-    # Read this entire thread for $CYGCHECK rationale:
-    #   https://cygwin.com/ml/cygwin/2012-02/threads.html#00910
-    #   https://cygwin.com/ml/cygwin/2012-03/threads.html#00005
-    # Cf.:
-    #   https://lists.nongnu.org/archive/html/lmi/2016-01/msg00092.html
-    CYGCHECK=$(cygpath --mixed /usr/bin/cygcheck)
-    cmd /c "$CYGCHECK" -s -v -r | tr --delete '\r'
-
-    # 'core.fileMode' rationale:
-    #   https://lists.nongnu.org/archive/html/lmi/2017-11/msg00018.html
-
-    git config --global core.fileMode false
-fi
+# Install and upgrade all packages if any is missing.
+packages_list='autoconf automake bsdtar curl dos2unix doxygen
+  gdb git libgtk-3-dev libtool make patch pkg-config rsync unzip wget
+  zip zsh'
 
-if [ "WSL" = "$platform" ]
-then
-    # Install/update packages.
-    packages_list='autoconf automake bsdtar curl dos2unix doxygen
-      gdb git libtool make patch pkg-config rsync unzip wget
-      zip zsh g++-mingw-w64-i686'
+# Disable shellcheck warning about the need to double quote $packages_list:
+# it can't be done here and we really want word splitting to happen here.
+# shellcheck disable=SC2086
+missing_packages_count=$(dpkg-query -W -f='${Status}\n' $packages_list 2>&1 | \
+  grep -v -c 'install ok installed')
 
-    # Disable shellcheck warning about the need to double quote $packages_list:
-    # it can't be done here and we really want word splitting to happen here.
+if [ "$missing_packages_count" -gt 0 ]
+then
+    echo "$missing_packages_count"
+    # For now at least, only show the commands, without running them:
+    echo sudo apt update
     # shellcheck disable=SC2086
-    missing_packages_count=$(dpkg-query -W -f='${Status}\n' $packages_list 
2>&1 | \
-      grep -v -c 'install ok installed')
-
-    if [ "$missing_packages_count" -gt 0 ]
-    then
-        sudo apt update
-        # shellcheck disable=SC2086
-        sudo apt install -y $packages_list
-    fi
-
-    # Mount /opt/lmi and /srv/cache_for_lmi directories.
-    # Unfortunately sudo must be used because we don't have permissions to
-    # write to /opt and / directories.
-    mkdir --parents /mnt/c/opt/lmi/src/lmi
-    restore_lmi_mount=$(mount | grep '/opt/lmi')
-    if [ -z "$restore_lmi_mount" ]
-    then
-        [ ! -d /opt/lmi ] && sudo mkdir /opt/lmi
-        sudo mount --bind /mnt/c/opt/lmi /opt/lmi
-    fi
-    mkdir --parents /mnt/c/srv/cache_for_lmi
-    restore_cache_mount=$(mount | grep '/srv/cache_for_lmi')
-    if [ -z "$restore_cache_mount" ]
-    then
-        [ ! -d /srv/cache_for_lmi ] && sudo mkdir /srv/cache_for_lmi
-        sudo mount --bind /mnt/c/srv/cache_for_lmi /srv/cache_for_lmi
-    fi
+    echo sudo apt install -y $packages_list
 fi
 
 if [ "/opt/lmi/src/lmi" = "$PWD" ]
@@ -210,7 +99,7 @@ then
     # shellcheck disable=SC2086
     git clone      $clone_opts git://git.savannah.nongnu.org/lmi.git \
       || git clone $clone_opts https://git.savannah.nongnu.org/r/lmi.git \
-      || git clone $clone_opts https://github.com/vadz/lmi.git
+      || git clone $clone_opts https://github.com/let-me-illustrate/lmi.git
 fi
 
 cd /opt/lmi/src/lmi || printf 'Cannot cd\n'
@@ -220,20 +109,6 @@ cd /opt/lmi/src/lmi || printf 'Cannot cd\n'
 # Get any new submodules that may have been added, even if nested.
 git submodule update "$coefficiency" --recursive --init
 
-if [ "Cygwin" = "$platform" ]
-then
-    # A "Replacing former [...] mount:" message probably means that this
-    # mount was set by an earlier lmi installation; that can be ignored.
-    # It seems quite unlikely that anyone who's building lmi would have
-    # any other need for mounts with the names used here.
-
-    restore_cache_mount=$(mount --mount-entries | grep '/srv/cache_for_lmi ')
-    [ -z "$restore_cache_mount" ] \
-      || printf '%s\n' "$restore_cache_mount" | grep --silent 
'C:/srv/cache_for_lmi' \
-      || printf 'Replacing former cache mount:\n  %s\n' "$restore_cache_mount" 
>/dev/tty
-    mount --force "C:/srv/cache_for_lmi" "/srv/cache_for_lmi"
-fi
-
 # Downloaded archives are kept in /srv/cache_for_lmi/downloads/ because
 # they are costly to download and some host might be temporarily
 # unavailable.
@@ -254,27 +129,13 @@ make "$coefficiency" --output-sync=recurse -f 
install_miscellanea.make
 export LMI_COMPILER=gcc
 export LMI_TRIPLET
 # shellcheck disable=SC2043
-#for LMI_TRIPLET in i686-w64-mingw32 ;
-for LMI_TRIPLET in x86_64-w64-mingw32 i686-w64-mingw32 ;
+for LMI_TRIPLET in x86_64-pc-linux-gnu ;
 do
     # Set a minimal path for makefiles and scripts that are
     # designed to be independent of lmi's runtime path.
     export PATH="$minimal_path"
 
-    # For Cygwin or WSL, install and use this msw-native compiler.
-    # Install it for other build types, too, even if only for
-    # validating the installation procedure.
-    mingw_dir=/opt/lmi/${LMI_COMPILER}_${LMI_TRIPLET}/gcc_msw
-    [ -d "$mingw_dir" ] && rm --force --recursive "$mingw_dir"
-    if   [ "i686-w64-mingw32"   = "$LMI_TRIPLET" ]; then
-      make "$coefficiency" --output-sync=recurse -f install_mingw32.make
-    elif [ "x86_64-w64-mingw32" = "$LMI_TRIPLET" ]; then
-      make "$coefficiency" --output-sync=recurse -f install_mingw.make
-    else
-      printf 'No MinGW compiler for this triplet.\n'
-    fi
-
-    ./install_libxml2_libxslt.sh
+    ./install_xml_libraries.sh
 
     ./install_wx.sh
     ./install_wxpdfdoc.sh
@@ -287,16 +148,8 @@ do
     make "$coefficiency" --output-sync=recurse wx_config_check
     make "$coefficiency" --output-sync=recurse show_flags
     make "$coefficiency" --output-sync=recurse clean
+    make "$coefficiency" --output-sync=recurse uninstall
     make "$coefficiency" --output-sync=recurse install
-
-    if [ "Cygwin" = "$platform" ]
-    then
-        # No lmi binary should depend on any Cygwin library.
-        for z in /opt/lmi/bin/* ;
-          do cmd /c "$CYGCHECK $z" 2>&1 | grep --silent cygwin \
-            && printf '\ncygcheck %s\n' "$z" && cmd /c "$CYGCHECK $z" ;
-          done
-    fi
 done
 
 # GID should be the same for all files.
@@ -347,11 +200,12 @@ for z in company_logo.png group_quote_banner.png ; do
 done
 
 # Configurable settings.
-#
-# Tailored to msw; for POSIX, s|C:|| and s|CMD /c|/bin/sh| (e.g.).
 
 mkdir --parents /opt/lmi/print
 
+# Like std::filesystem::root_name().
+root_name=
+
 cat >/opt/lmi/data/configurable_settings.xml <<EOF
 <?xml version="1.0"?>
 <configurable_settings version="2">
@@ -362,10 +216,10 @@ cat >/opt/lmi/data/configurable_settings.xml <<EOF
   <custom_input_1_filename>custom.inix</custom_input_1_filename>
   <custom_output_0_filename>custom.out0</custom_output_0_filename>
   <custom_output_1_filename>custom.out1</custom_output_1_filename>
-  <default_input_filename>C:/etc/opt/lmi/default.ill</default_input_filename>
+  
<default_input_filename>${root_name}/etc/opt/lmi/default.ill</default_input_filename>
   <libraries_to_preload/>
   <offer_hobsons_choice>0</offer_hobsons_choice>
-  <print_directory>C:/opt/lmi/print</print_directory>
+  <print_directory>${root_name}/opt/lmi/print</print_directory>
   <seconds_to_pause_between_printouts>10</seconds_to_pause_between_printouts>
   <skin_filename>skin.xrc</skin_filename>
   <spreadsheet_file_extension>.tsv</spreadsheet_file_extension>
@@ -373,17 +227,6 @@ cat >/opt/lmi/data/configurable_settings.xml <<EOF
 </configurable_settings>
 EOF
 
-# Remove "C:" for wine: it designates the "wine prefix" directory.
-# "Z:" could be used instead, because that's where wine maps the
-# apparent root, but that wouldn't work with posix builds. Instead,
-# therefore, symlink the directories lmi uses as described in
-# 'README.schroot'.
-
-if [ "Cygwin" != "$platform" ] && [ "WSL" != "$platform" ]
-then
-    sed -i /opt/lmi/data/configurable_settings.xml -e's/C://g'
-fi
-
 # Restore any preexisting source directory that had been preserved
 # above, renaming the pristine checkout that had replaced it.
 #
diff --git a/gwc/perf_ln.sh b/gwc/perf_ln.sh
new file mode 100755
index 0000000..8878de2
--- /dev/null
+++ b/gwc/perf_ln.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# Hard-link host's 'perf' and its dependencies for use in a chroot.
+
+# Copyright (C) 2020 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
+#
+# https://savannah.nongnu.org/projects/lmi
+# email: <gchicares@sbcglobal.net>
+# snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+# See
+#   https://lists.nongnu.org/archive/html/lmi/2020-10/msg00016.html
+# for an initial attempt that used 'cp' instead of 'ln' (and included
+# a good deal of relevant discussion), and
+#   https://lists.nongnu.org/archive/html/lmi/2020-10/msg00019.html
+# for an improvement using 'ln' instead of 'cp'.
+
+set -vx
+d=/srv/cache_for_lmi/perf_ln
+mkdir -p $d
+for z in \
+  /usr/bin/perf_4.19                                   \
+  /usr/lib/x86_64-linux-gnu/libopencsd_c_api.so.0      \
+  /usr/lib/x86_64-linux-gnu/libopencsd_c_api.so.0.10.1 \
+  /usr/lib/x86_64-linux-gnu/libopencsd.so.0            \
+  /usr/lib/x86_64-linux-gnu/libopencsd.so.0.10.1       \
+  /usr/lib/x86_64-linux-gnu/libperl.so.5.28            \
+  /usr/lib/x86_64-linux-gnu/libperl.so.5.28.1          \
+  /usr/lib/x86_64-linux-gnu/libpython3.7m.so.1.0       \
+  /usr/lib/x86_64-linux-gnu/libbabeltrace-ctf.so.1     \
+  /usr/lib/x86_64-linux-gnu/libbabeltrace-ctf.so.1.0.0 \
+  /usr/lib/x86_64-linux-gnu/libbabeltrace.so.1         \
+  /usr/lib/x86_64-linux-gnu/libbabeltrace.so.1.0.0     \
+  ;
+do ln $z $d/"$(basename "$z")"; done
+
+# later, in a chroot that mounts /srv/cache_for_lmi/
+# cd /opt/lmi/bin
+#   library path required for perf's and lmi's binaries
+# 
LD_LIBRARY_PATH=.:/opt/lmi/local/gcc_x86_64-pc-linux-gnu/lib/:/srv/cache_for_lmi/perf_ln
 /srv/cache_for_lmi/perf_ln/perf_4.19 record --freq=max --call-graph lbr 
./lmi_cli_shared --accept --data_path=/opt/lmi/data --selftest
+# Failed to open [ext4], continuing without symbols
+# Failed to open [fscrypto], continuing without symbols
+# Failed to open [kvm], continuing without symbols
+# Failed to read max cpus, using default of 4096
+# [ perf record: Captured and wrote 123.760 MB perf.data (358633 samples) ]
+#
+# LD_LIBRARY_PATH=.:/srv/cache_for_lmi/perf_ln 
/srv/cache_for_lmi/perf_ln/perf_4.19 report
diff --git a/gwc/perf_static.sh b/gwc/perf_static.sh
new file mode 100755
index 0000000..8c45094
--- /dev/null
+++ b/gwc/perf_static.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+
+# Hard-link host's static-built 'perf' for use in a chroot.
+
+# Copyright (C) 2020 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
+#
+# https://savannah.nongnu.org/projects/lmi
+# email: <gchicares@sbcglobal.net>
+# snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+# Instead of hard-linking 'perf' and all its dependencies, build it
+# statically as suggested here:
+#   https://lists.nongnu.org/archive/html/lmi/2020-10/msg00020.html
+# Unfortunately, while the resulting static 'perf' seems to work just
+# fine for 'perf record', for 'perf report' it doesn't decode symbols
+# or present the expected interactive interface--see example below.
+
+set -vx
+
+# apt-get install linux-source
+# pushd /usr/src
+#   redirect because output is about 64K lines
+#   in an interactive session, press <Tab> where indicated:
+# tar xvf /usr/src/linux-source-*<Tab> 2>&1 |less
+#   here, the tab completion is inlined:
+# tar xvf /usr/src/linux-source-4.19.tar.xz  2>&1 |less
+# pushd   /usr/src/linux-source-4.19/tools/perf
+#   this fails...
+# make clean; make EXTRA_LDFLAGS=-static 2>&1 |less
+#   ...so do this instead--see:
+#   https://lists.nongnu.org/archive/html/lmi/2020-12/msg00003.html
+# make clean; make EXTRA_LDFLAGS=-static 
EXTRA_CFLAGS=-Wno-discarded-qualifiers 2>&1 |less
+#   still, it's not purely static:
+# ldd /usr/src/linux-source-4.19/tools/perf/perf
+#   linux-vdso.so.1 (0x00007ffff5d2c000)
+#   libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 
(0x00007fd5341b6000)
+#   librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fd5341ac000)
+#   libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd534029000)
+#   libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd534024000)
+#   libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd533e63000)
+#   /lib64/ld-linux-x86-64.so.2 (0x00007fd534727000)
+# ...but perhaps that doesn't actually matter.
+
+# For this static build (cf. 'allow_perf.sh'):
+# chgrp perf_users /usr/src/linux-source-4.19/tools/perf/perf
+# chmod o-rwx /usr/src/linux-source-4.19/tools/perf/perf
+
+d=/srv/cache_for_lmi/perf_static
+mkdir -p $d
+ln /usr/src/linux-source-4.19/tools/perf/perf $d/perf
+
+# later, in a chroot that mounts /srv/cache_for_lmi/
+# cd /opt/lmi/bin
+#   library path required only for lmi's libraries, not perf's
+# LD_LIBRARY_PATH=.:/opt/lmi/local/gcc_x86_64-pc-linux-gnu/lib/ 
/srv/cache_for_lmi/perf_static/perf record --freq=max --call-graph lbr 
./lmi_cli_shared --accept --data_path=/opt/lmi/data --selftest
+# Failed to open [ext4], continuing without symbols
+# Failed to open [kvm], continuing without symbols
+# Failed to open [fscrypto], continuing without symbols
+# Failed to read max cpus, using default of 4096
+# [ perf record: Captured and wrote 126.807 MB perf.data (367155 samples) ]
+#
+# specifying $LD_LIBRARY_PATH here neither hurts nor helps:
+# LD_LIBRARY_PATH=.:/srv/cache_for_lmi/perf_static 
/srv/cache_for_lmi/perf_static/perf report
+#
+#    34.35%     0.00%  lmi_cli_shared  liblmi.so              [.] 
0x00007f58de18d8e9
+#            |
+#            ---0x7f58de18d8e9
+#               |
+#               |--28.65%--0x7f58de222bce
+#
+# No runtime error is reported, but the customary text-mode interface
+# is not offered. This static 'perf' generates a valid 'perf.data'
+# output file, which can be viewed with the 'perf_static.sh' variant
+# of perf in the chroot (which then does present the customary text-
+# mode interface and does decode symbols).
+#
+# The usual advice is to make sure the program being profiled was
+# built with debugging enabled and with '-fno-omit-frame-pointer', but
+# that doesn't help here: the program was built with those options,
+# and the 'perf_ln.sh' technique works but this 'perf_static.sh'
+# technique leads to the problems above.
diff --git a/gwc/redhat_rebuild.sh b/gwc/redhat_rebuild.sh
index 602f822..df50d14 100755
--- a/gwc/redhat_rebuild.sh
+++ b/gwc/redhat_rebuild.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 cd /srv/cache_for_lmi/logs || printf 'Cannot cd\n'
-wget -N -nv https://github.com/vadz/lmi/raw/master/lmi_setup_00.sh
+wget -N -nv https://github.com/let-me-illustrate/lmi/raw/master/lmi_setup_00.sh
 chmod +x lmi_setup_00.sh
 # It would be undesirable for root to own the output file:
 # shellcheck disable=SC2024
diff --git a/gwc/rh.sh b/gwc/rh.sh
index ada0d38..e2a6825 100644
--- a/gwc/rh.sh
+++ b/gwc/rh.sh
@@ -27,7 +27,7 @@
 # on this server, which is good enough.
 
 # Needed to do this:
-# 
%s,https://git.savannah.nongnu.org/cgit/lmi.git/plain,https://github.com/vadz/lmi/raw/master,
+# 
%s,https://git.savannah.nongnu.org/cgit/lmi.git/plain,https://github.com/let-me-illustrate/lmi/raw/master,
 # for a corporate server that enables github but, incomprehensibly, blocks 
nongnu.org
 
 # * Multi-user access
@@ -73,12 +73,11 @@ patch --dry-run --strip=0 </home/${USER}/ltmain.sh.patch \
 # See:
 #   https://lists.nongnu.org/archive/html/lmi/2019-09/msg00035.html
 
-sudo cp -a /usr/share/libtool/config/config.guess 
/usr/share/libtool/build-aux/config.guess
+sudo cp -a /usr/share/libtool/config/config.guess /usr/share/misc/config.guess
 
 # Configure zsh, for root as well as the user configured above.
 
-https://github.com/vadz/lmi/raw/master/gwc/.zshrc
-wget -N -nv 'https://github.com/vadz/lmi/raw/master/gwc/.zshrc'
+wget -N -nv 'https://github.com/let-me-illustrate/lmi/raw/master/gwc/.zshrc'
 mv .zshrc ~
 cp -a ~/.zshrc /home/${USER}/.zshrc
 chown ${USER}:${USER} /home/${USER}/.zshrc
@@ -87,7 +86,7 @@ chown ${USER}:${USER} /home/${USER}/.zshrc
 # '~/.vimrc' and '/etc/vim/vimrc.local', use '~/.vimrc' for all
 # customizations and copy that file for the normal user too.
 
-wget -N -nv 'https://github.com/vadz/lmi/raw/master/gwc/.vimrc'
+wget -N -nv 'https://github.com/let-me-illustrate/lmi/raw/master/gwc/.vimrc'
 mv .vimrc ~
 cp -a ~/.vimrc /home/${USER}/.vimrc
 chown ${USER}:${USER} /home/${USER}/.vimrc
@@ -98,7 +97,7 @@ mkdir ~/.vim
 mkdir /home/${USER}/.vim
 chown ${USER}:${USER} /home/${USER}/.vim
 # It's a much better idea to copy a mature spellfile hither:
-wget -N -nv 
'https://github.com/vadz/lmi/raw/master/gwc/.vim/spell/en.utf-8.add'
+wget -N -nv 
'https://github.com/let-me-illustrate/lmi/raw/master/gwc/.vim/spell/en.utf-8.add'
 mkdir ~/.vim/spell
 mv en.utf-8.add ~/.vim/spell/en.utf-8.add
 mkdir /home/${USER}/.vim/spell
@@ -129,7 +128,7 @@ git config --global push.default simple
 
 # Install lmi for wine.
 
-wget -N -nv 'https://github.com/vadz/lmi/raw/master/install_msw.sh'
+wget -N -nv 
'https://github.com/let-me-illustrate/lmi/raw/master/install_msw.sh'
 chmod +x install_msw.sh
 ./install_msw.sh >log 2>&1
 
diff --git a/hooks/post-checkout b/hooks/post-checkout
index 8396906..87f6913 100755
--- a/hooks/post-checkout
+++ b/hooks/post-checkout
@@ -29,6 +29,8 @@ if [ "greg" != "$(whoami)" ]; then
   exit 0
 fi
 
+printf "running post-checkout hook...\n"
+
 # Motivation. I maintain a local mirror of origin/master in a
 # directory named by ${mirror_dir}. It is often convenient to
 # compare it to my working directory using some GUI diff program,
@@ -51,7 +53,7 @@ new_head_name="$(git name-rev --name-only "$new_head")"
 
 changed_files=$(git diff --name-only "$old_head_name..$new_head_name")
 
-mirror_dir=/opt/lmi/free/src/lmi/
+mirror_dir=/opt/lmi/free/src/lmi
 
 for z in $changed_files
 do
@@ -60,3 +62,5 @@ do
         touch --no-create --reference="$z" "$y";
     fi
 done
+
+printf "...post-checkout hook finished.\n"
diff --git a/ieee754.hpp b/ieee754.hpp
index 6e81c3e..f589872 100644
--- a/ieee754.hpp
+++ b/ieee754.hpp
@@ -43,7 +43,7 @@
 template<typename T>
 T implausible_value(T const& t = -9.99999e35f)
 {
-    static_assert(::std::is_floating_point<T>::value);
+    static_assert(::std::is_floating_point_v<T>);
 
     if(std::numeric_limits<T>::has_quiet_NaN)
         {
@@ -71,7 +71,7 @@ T implausible_value(T const& t = -9.99999e35f)
 template<typename T>
 inline T infinity()
 {
-    static_assert(::std::is_floating_point<T>::value);
+    static_assert(::std::is_floating_point_v<T>);
     static_assert(std::numeric_limits<T>::has_infinity);
     static T const volatile z = std::numeric_limits<T>::infinity();
     return z;
@@ -103,7 +103,7 @@ inline T infinity()
 template<typename T>
 inline bool is_infinite(T t)
 {
-    static_assert(::std::is_floating_point<T>::value);
+    static_assert(::std::is_floating_point_v<T>);
     static T const volatile pos_inf =  std::numeric_limits<T>::infinity();
     static T const volatile neg_inf = -std::numeric_limits<T>::infinity();
     static bool const has_inf = std::numeric_limits<T>::has_infinity;
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index 1e80dd8..f356eb9 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -530,7 +530,16 @@ void AccountValue::SetInitialValues()
     AVGenAcct             = round_minutiae().c(InforceAVGenAcct);
     AVSepAcct             = round_minutiae().c(InforceAVSepAcct);
 
-    SepAcctPaymentAllocation = premium_allocation_to_sepacct(yare_input_);
+    // WX PORT !! When fund selection is finally ported from ihs,
+    // this workaround should not be needed; until then, it sidesteps
+    // spurious errors in product_test().
+    double const sa_allocation =  premium_allocation_to_sepacct(yare_input_);
+    bool const override_allocation =
+           !database().query<bool>(DB_AllowGenAcct)
+        && global_settings::instance().regression_testing()
+        ;
+//  SepAcctPaymentAllocation = premium_allocation_to_sepacct(yare_input_);
+    SepAcctPaymentAllocation = override_allocation ? 1.0 : sa_allocation ;
     GenAcctPaymentAllocation = 1.0 - SepAcctPaymentAllocation;
 
     if(!database().query<bool>(DB_AllowGenAcct) && 0.0 != 
GenAcctPaymentAllocation)
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index 8fae821..a0cfc73 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -41,6 +41,7 @@
 #include "ihs_irc7702a.hpp"
 #include "input.hpp"
 #include "interest_rates.hpp"
+#include "lingo.hpp"
 #include "loads.hpp"
 #include "math_functions.hpp"
 #include "mc_enum_types_aux.hpp"        // mc_str()
@@ -208,6 +209,7 @@ void BasicValues::Init()
             << LMI_FLUSH
             ;
         }
+    lingo_ = 
lingo::read_via_cache(AddDataDir(product().datum("LingoFilename")));
     FundData_.reset(new FundData(AddDataDir(product().datum("FundFilename"))));
     RoundingRules_.reset
         (new rounding_rules(AddDataDir(product().datum("RoundingFilename")))
@@ -298,9 +300,8 @@ void BasicValues::GPTServerInit()
             std::string("Issue age greater than maximum")
             );
         }
-//  FundData_       = new FundData
-//      (AddDataDir(product().datum("FundFilename"))
-//      );
+//  lingo_.reset(new lingo(AddDataDir(product().datum("LingoFilename"))));
+//  FundData_.reset(new FundData(AddDataDir(product().datum("FundFilename"))));
     RoundingRules_.reset
         (new rounding_rules(AddDataDir(product().datum("RoundingFilename")))
         );
diff --git a/ihs_irc7702a.hpp b/ihs_irc7702a.hpp
index cddbb9b..89de3d5 100644
--- a/ihs_irc7702a.hpp
+++ b/ihs_irc7702a.hpp
@@ -31,7 +31,7 @@
 
 #include <vector>
 
-void LMI_SO TestIrc7702A();
+LMI_SO void TestIrc7702A();
 
 // TAXATION !! TODO ?? Known defects:
 //   need to handle withdrawals correctly;
diff --git a/ihs_server7702.hpp b/ihs_server7702.hpp
index f14046d..029ed96 100644
--- a/ihs_server7702.hpp
+++ b/ihs_server7702.hpp
@@ -46,7 +46,7 @@ struct Server7702Output
     double           GuidelineSinglePremiumPolicyC; // the GSP for notional 
policy C; 0.0 at issue or if there has been no adjustable event.
 };
 
-Server7702Output LMI_SO RunServer7702FromStruct(gpt_input a_Input);
+LMI_SO Server7702Output RunServer7702FromStruct(gpt_input a_Input);
 
 class Server7702
 {
diff --git a/ill_reg_narr_summary2.mst b/ill_reg_narr_summary2.mst
index 6986217..0c0fffa 100644
--- a/ill_reg_narr_summary2.mst
+++ b/ill_reg_narr_summary2.mst
@@ -112,14 +112,6 @@ The state of issue is {{StateOfJurisdiction}}.
     {{MecFootnote}}
 </p>
 
-{{^SinglePremium}}
-    {{^IsInforce}}
-        <p>
-        The initial 7-pay premium limit is ${{InitSevenPayPrem}}.
-        </p>
-    {{/IsInforce}}
-{{/SinglePremium}}
-
 <p>
     {{FnNotTaxAdvice}}
 </p>
diff --git a/illustration_view.cpp b/illustration_view.cpp
index 8b5e6f6..519fe98 100644
--- a/illustration_view.cpp
+++ b/illustration_view.cpp
@@ -41,7 +41,7 @@
 #include "default_view.hpp"
 #include "edit_mvc_docview_parameters.hpp"
 #include "emit_ledger.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "illustration_document.hpp"
 #include "illustrator.hpp"
 #include "input.hpp"
diff --git a/illustrator.cpp b/illustrator.cpp
index 814473a..d1b3740 100644
--- a/illustrator.cpp
+++ b/illustrator.cpp
@@ -30,7 +30,7 @@
 #include "custom_io_1.hpp"
 #include "emit_ledger.hpp"
 #include "group_values.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "input.hpp"
 #include "ledgervalues.hpp"
 #include "multiple_cell_document.hpp"
diff --git a/illustrator.hpp b/illustrator.hpp
index eaf9c35..67398ea 100644
--- a/illustrator.hpp
+++ b/illustrator.hpp
@@ -65,9 +65,9 @@ class LMI_SO illustrator final
     double seconds_for_output_;
 };
 
-Input const& LMI_SO default_cell();
+LMI_SO Input const& default_cell();
 
-void LMI_SO test_census_consensus
+LMI_SO void test_census_consensus
     (mcenum_emission           emission
     ,Input              const& case_default
     ,std::vector<Input> const& all_cells
diff --git a/input_realization.cpp b/input_realization.cpp
index a2aa8c4..ca55645 100644
--- a/input_realization.cpp
+++ b/input_realization.cpp
@@ -30,7 +30,7 @@
 #include "dbnames.hpp"
 #include "dbo_rules.hpp"
 #include "global_settings.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "input_sequence_aux.hpp"       // convert_vector()
 #include "miscellany.hpp"               // each_equal(), minmax
 #include "round_to.hpp"
diff --git a/input_sequence.cpp b/input_sequence.cpp
index dfb5ded..6e86041 100644
--- a/input_sequence.cpp
+++ b/input_sequence.cpp
@@ -212,8 +212,8 @@ void set_value(ValueInterval& v, std::string const& s)
 template<typename T>
 void InputSequence::initialize_from_vector(std::vector<T> const& v)
 {
-    bool const T_is_double = std::is_same<T,double     >::value;
-    bool const T_is_string = std::is_same<T,std::string>::value;
+    bool const T_is_double = std::is_same_v<T,double     >;
+    bool const T_is_string = std::is_same_v<T,std::string>;
     static_assert(T_is_double || T_is_string);
 
     ValueInterval default_interval;
diff --git a/input_sequence_aux.hpp b/input_sequence_aux.hpp
index a813612..28bce86 100644
--- a/input_sequence_aux.hpp
+++ b/input_sequence_aux.hpp
@@ -45,7 +45,7 @@ namespace detail
 {
     typedef std::map<std::string,std::string> stringmap;
 
-    std::vector<std::string> LMI_SO extract_keys_from_string_map
+    LMI_SO std::vector<std::string> extract_keys_from_string_map
         (stringmap const& keyword_dictionary
         );
 
@@ -105,7 +105,7 @@ namespace detail
 template<typename T>
 std::vector<T> convert_vector_type
     (std::vector<mc_enum<T>> const& ve
-    ,typename std::enable_if<std::is_enum<T>::value>::type* = nullptr
+    ,typename std::enable_if<std::is_enum_v<T>>::type* = nullptr
     )
 {
     std::vector<T> z;
diff --git a/input_sequence_interval.hpp b/input_sequence_interval.hpp
index b5aedd8..402ab7c 100644
--- a/input_sequence_interval.hpp
+++ b/input_sequence_interval.hpp
@@ -58,6 +58,6 @@ struct ValueInterval
     bool          insane           = false;
 };
 
-std::string LMI_SO abridge_diagnostics(char const* what);
+LMI_SO std::string abridge_diagnostics(char const* what);
 
 #endif // input_sequence_interval_hpp
diff --git a/install_miscellanea.make b/install_miscellanea.make
index a236f63..e991f71 100644
--- a/install_miscellanea.make
+++ b/install_miscellanea.make
@@ -48,7 +48,6 @@ cgicc_archive    := cgicc-3.1.4.tar.bz2
 jing_archive     := jing-20091111.zip
 sample_archive   := lmi-data-20050618T1440Z.tar.bz2
 trang_archive    := trang-20091111.zip
-xmlwrapp_archive := xmlwrapp-0.9.0.tar.gz
 
 file_list := \
   $(boost_archive) \
@@ -56,9 +55,8 @@ file_list := \
   $(jing_archive) \
   $(sample_archive) \
   $(trang_archive) \
-  $(xmlwrapp_archive) \
 
-boost cgicc xmlwrapp: stem = $(basename $(basename $($@_archive)))
+boost cgicc:          stem = $(basename $(basename $($@_archive)))
 jing trang:           stem =            $(basename $($@_archive))
 sample:               stem = data
 
@@ -69,14 +67,12 @@ $(cgicc_archive)-url    := 
ftp://ftp.gnu.org/pub/gnu/cgicc/$(cgicc_archive)
 $(jing_archive)-url     := 
https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jing-trang/$(jing_archive)
 $(sample_archive)-url   := 
https://download.savannah.gnu.org/releases/lmi/$(sample_archive)
 $(trang_archive)-url    := 
https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jing-trang/$(trang_archive)
-$(xmlwrapp_archive)-url := 
https://github.com/vslavik/xmlwrapp/releases/download/v0.9.0/$(xmlwrapp_archive)
 
 $(boost_archive)-md5    := 2b999b2fb7798e1737d1fff8fac602ef
 $(cgicc_archive)-md5    := 6cb5153fc9fa64b4e50c7962aa557bbe
 $(jing_archive)-md5     := 13eef193921409a1636377d1efbf9843
 $(sample_archive)-md5   := e7f07133abfc3b9c2252dfa3b61191bc
 $(trang_archive)-md5    := 9d31799b948c350850eb9dd14e5b832d
-$(xmlwrapp_archive)-md5 := 5e8ac678ab03b7c60ce61ac5424e0849
 
 # Utilities 
####################################################################
 
@@ -115,7 +111,7 @@ ad_hoc_dir_exists = \
 # Targets 
######################################################################
 
 .PHONY: all
-all: boost cgicc jing sample trang xmlwrapp
+all: boost cgicc jing sample trang
 
 # Patches were generated according to this advice:
 #
@@ -201,24 +197,6 @@ trang: $(file_list)
        $(MKDIR) --parents $(dest_dir)/rng
        $(MV) $(ad_hoc_dir)/$(stem)/$@.jar $(dest_dir)/rng
 
-.PHONY: xmlwrapp
-xmlwrapp: $(file_list)
-       -[ -e $(stem).patch ] && $(PATCH) --directory=$(ad_hoc_dir) --strip=1 < 
$(stem).patch
-       $(CHMOD) -R g=u $(ad_hoc_dir)/$(stem)
-       $(MKDIR) $(third_party_include_dir)/xmlwrapp/
-       $(MV) $(ad_hoc_dir)/$(stem)/include/xmlwrapp/*.h 
$(third_party_include_dir)/xmlwrapp/
-       $(MKDIR) $(third_party_include_dir)/xsltwrapp/
-       $(MV) $(ad_hoc_dir)/$(stem)/include/xsltwrapp/*.h 
$(third_party_include_dir)/xsltwrapp/
-       $(MKDIR) $(third_party_source_dir)/libxml/
-       $(MV) $(ad_hoc_dir)/$(stem)/src/libxml/* 
$(third_party_source_dir)/libxml/
-       $(MKDIR) $(third_party_source_dir)/libxslt/
-       $(MV) $(ad_hoc_dir)/$(stem)/src/libxslt/* 
$(third_party_source_dir)/libxslt/
-       cd $(dest_dir) && $(MD5SUM) --binary include/xmlwrapp/* 
include/xsltwrapp/* src/libxml/* src/libxslt/* >$(stem).md5sums
-       cd $(dest_dir) && $(MD5SUM) --check $(CURDIR)/$(stem).md5sums
-       $(SORT) --key=2 --output=$(stem).X             $(stem).md5sums
-       $(SORT) --key=2 --output=$(stem).Y $(dest_dir)/$(stem).md5sums
-       $(DIFF) --unified $(stem).X $(stem).Y && $(RM) 
$(dest_dir)/$(stem).md5sums $(stem).X $(stem).Y
-
 $(file_list): initial_setup
 
 .PHONY: initial_setup
diff --git a/install_msw.sh b/install_msw.sh
index a5fd87f..d2c6066 100755
--- a/install_msw.sh
+++ b/install_msw.sh
@@ -34,7 +34,26 @@ set -vx
 stamp0=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
 echo "Started: $stamp0"
 
-lmi_build_type=$(/usr/share/libtool/build-aux/config.guess)
+# Ensure that '/usr/share/misc/config.guess' is available for all
+# lmi scripts and makefiles. That's the closest thing to a canonical
+# location for it. If it's not there, then try to copy it from other
+# places where installing 'libtool' would have placed it on various
+# debian and redhat systems.
+
+config_guess_0=/usr/share/misc/config.guess
+config_guess_1=/usr/share/libtool/build-aux/config.guess
+config_guess_2=/usr/share/libtool/config/config.guess
+if   [ -f "$config_guess_0" ]
+  then printf '"config.guess" found in canonical location.\n'
+elif [ -f "$config_guess_1" ]
+  then cp -a "$config_guess_1" "$config_guess_0"
+elif [ -f "$config_guess_2" ]
+  then cp -a "$config_guess_2" "$config_guess_0"
+else
+  printf '"config.guess" not found: cannot continue.\n'; exit 3;
+fi
+
+lmi_build_type=$(/usr/share/misc/config.guess)
 
 # This should work with a rather minimal path.
 
@@ -44,10 +63,6 @@ case "$lmi_build_type" in
     (*-*-cygwin*)
         minimal_path="$minimal_path:$(cygpath --sysdir)"
         java -version
-        # Probably $java_path is unhelpful and should be deleted.A
-        # Avoid appending it to $PATH because it contains spaces.
-        java_path="/cygdrive/c/Program\ Files\ \(x86\)/Common\ 
Files/Oracle/Java/javapath"
-        "$java_path"/java -version
         ;;
     (*)
         java -version
@@ -144,9 +159,9 @@ fi
 
 if [ "WSL" = "$platform" ]
 then
-    # Install/update packages.
+    # Install and upgrade all packages if any is missing.
     packages_list='autoconf automake bsdtar curl dos2unix doxygen
-      gdb git libtool make patch pkg-config rsync unzip wget
+      gdb git libgtk-3-dev libtool make patch pkg-config rsync unzip wget
       zip zsh g++-mingw-w64-i686'
 
     # Disable shellcheck warning about the need to double quote $packages_list:
@@ -210,7 +225,7 @@ then
     # shellcheck disable=SC2086
     git clone      $clone_opts git://git.savannah.nongnu.org/lmi.git \
       || git clone $clone_opts https://git.savannah.nongnu.org/r/lmi.git \
-      || git clone $clone_opts https://github.com/vadz/lmi.git
+      || git clone $clone_opts https://github.com/let-me-illustrate/lmi.git
 fi
 
 cd /opt/lmi/src/lmi || printf 'Cannot cd\n'
@@ -251,11 +266,16 @@ make "$coefficiency" --output-sync=recurse -f 
install_miscellanea.make
 # This for-loop can iterate over as many toolchains as desired.
 # Make sure the current production architecture is built last, so that
 # it's the one installed to /opt/lmi/bin/ when this script ends.
+triplets="x86_64-w64-mingw32 i686-w64-mingw32"
+if [ "Cygwin" != "$platform" ] && [ "WSL" != "$platform" ]
+then
+    triplets="x86_64-pc-linux-gnu x86_64-w64-mingw32 i686-w64-mingw32"
+fi
 export LMI_COMPILER=gcc
 export LMI_TRIPLET
 # shellcheck disable=SC2043
 #for LMI_TRIPLET in i686-w64-mingw32 ;
-for LMI_TRIPLET in x86_64-w64-mingw32 i686-w64-mingw32 ;
+for LMI_TRIPLET in ${triplets} ;
 do
     # Set a minimal path for makefiles and scripts that are
     # designed to be independent of lmi's runtime path.
@@ -274,7 +294,7 @@ do
       printf 'No MinGW compiler for this triplet.\n'
     fi
 
-    ./install_libxml2_libxslt.sh
+    ./install_xml_libraries.sh
 
     ./install_wx.sh
     ./install_wxpdfdoc.sh
@@ -287,6 +307,7 @@ do
     make "$coefficiency" --output-sync=recurse wx_config_check
     make "$coefficiency" --output-sync=recurse show_flags
     make "$coefficiency" --output-sync=recurse clean
+    make "$coefficiency" --output-sync=recurse uninstall
     make "$coefficiency" --output-sync=recurse install
 
     if [ "Cygwin" = "$platform" ]
@@ -347,11 +368,23 @@ for z in company_logo.png group_quote_banner.png ; do
 done
 
 # Configurable settings.
-#
-# Tailored to msw; for POSIX, s|C:|| and s|CMD /c|/bin/sh| (e.g.).
 
 mkdir --parents /opt/lmi/print
 
+# Like std::filesystem::root_name().
+root_name=C:
+
+# Don't use "C:" for wine: it designates the "wine prefix" directory.
+# "Z:" could be used instead, because that's where wine maps the
+# apparent root, but that wouldn't work with posix builds. Instead,
+# therefore, symlink the directories lmi uses as described in
+# 'README.schroot'.
+
+if [ "Cygwin" != "$platform" ] && [ "WSL" != "$platform" ]
+then
+    root_name=
+fi
+
 cat >/opt/lmi/data/configurable_settings.xml <<EOF
 <?xml version="1.0"?>
 <configurable_settings version="2">
@@ -362,10 +395,10 @@ cat >/opt/lmi/data/configurable_settings.xml <<EOF
   <custom_input_1_filename>custom.inix</custom_input_1_filename>
   <custom_output_0_filename>custom.out0</custom_output_0_filename>
   <custom_output_1_filename>custom.out1</custom_output_1_filename>
-  <default_input_filename>C:/etc/opt/lmi/default.ill</default_input_filename>
+  
<default_input_filename>${root_name}/etc/opt/lmi/default.ill</default_input_filename>
   <libraries_to_preload/>
   <offer_hobsons_choice>0</offer_hobsons_choice>
-  <print_directory>C:/opt/lmi/print</print_directory>
+  <print_directory>${root_name}/opt/lmi/print</print_directory>
   <seconds_to_pause_between_printouts>10</seconds_to_pause_between_printouts>
   <skin_filename>skin.xrc</skin_filename>
   <spreadsheet_file_extension>.tsv</spreadsheet_file_extension>
@@ -373,17 +406,6 @@ cat >/opt/lmi/data/configurable_settings.xml <<EOF
 </configurable_settings>
 EOF
 
-# Remove "C:" for wine: it designates the "wine prefix" directory.
-# "Z:" could be used instead, because that's where wine maps the
-# apparent root, but that wouldn't work with posix builds. Instead,
-# therefore, symlink the directories lmi uses as described in
-# 'README.schroot'.
-
-if [ "Cygwin" != "$platform" ] && [ "WSL" != "$platform" ]
-then
-    sed -i /opt/lmi/data/configurable_settings.xml -e's/C://g'
-fi
-
 # Restore any preexisting source directory that had been preserved
 # above, renaming the pristine checkout that had replaced it.
 #
diff --git a/install_wx.sh b/install_wx.sh
index 913d5c1..b7f3cfa 100755
--- a/install_wx.sh
+++ b/install_wx.sh
@@ -23,18 +23,8 @@
 
 set -vxe
 
-# A repository is cached in /srv/cache_for_lmi/vcs/, where it can be
-# kept up to date and reused cheaply--whereas cloning it from a remote
-# host takes considerable time and bandwidth, and fails if internet
-# connectivity is lost, or the host is temporarily unavailable, or
-# it is blocked by a corporate firewall.
-
 # Configurable settings 
########################################################
 
-remote_host_url=${remote_host_url:-"https://github.com/wxWidgets/wxWidgets.git"}
-
-wx_commit_sha=${wx_commit_sha:-"6cdaedd42ba59331b3dc4ead50e0bac76ae14c19"}
-
 wx_skip_clean=${wx_skip_clean:-"0"}
 
 coefficiency=${coefficiency:-"--jobs=$(nproc)"}
@@ -51,41 +41,12 @@ mingw_dir=/opt/lmi/${LMI_COMPILER}_${LMI_TRIPLET}/gcc_msw
 prefix=/opt/lmi/local
 exec_prefix="$prefix/${LMI_COMPILER}_${LMI_TRIPLET}"
 
-repo_name="wxWidgets"
-
-# Script commands 
##############################################################
+srcdir=$(dirname "$(readlink --canonicalize "$0")")
+wx_dir="$srcdir/third_party/wx"
 
-proxy_parent_dir="/srv/cache_for_lmi/vcs"
-mkdir --parents "$proxy_parent_dir"
-
-proxy_wx_dir="$proxy_parent_dir"/$repo_name
-
-# Create a local mirror if it doesn't already exist.
-if [ ! -d "$proxy_wx_dir" ]
-then
-    cd "$proxy_parent_dir"
-    git clone "$coefficiency" --recurse-submodules "$remote_host_url" 
$repo_name
-fi
+build_type=$(/usr/share/misc/config.guess)
 
-cd "$proxy_wx_dir"
-
-# Fetch desired commit from remote host if missing.
-if ! git rev-parse --quiet --verify "$wx_commit_sha^{commit}" >/dev/null
-then
-    git fetch origin
-fi
-
-# Reset in case git-checkout would fail. See:
-#   https://lists.nongnu.org/archive/html/lmi/2020-07/msg00053.html
-git reset --hard
-git submodule foreach 'git reset --hard'
-
-git checkout "$wx_commit_sha"
-
-# Get any new submodules that may have been added, even if nested.
-git submodule update "$coefficiency" --recursive --init
-
-build_type=$("$proxy_wx_dir"/config.guess)
+# Script commands 
##############################################################
 
 case "$build_type" in
     (*-*-cygwin*)
@@ -94,8 +55,8 @@ case "$build_type" in
 esac
 
 # Distinguish wx dll by host type, compiler version, and wx SHA1.
-gcc_version=$("${mingw_bin_dir}${LMI_TRIPLET}-$LMI_COMPILER" -dumpversion|tr 
-d '\r')
-vendor=${LMI_TRIPLET}-$gcc_version-$wx_commit_sha
+gcc_version=$(make --no-print-directory --directory="$srcdir" show_gcc_version)
+vendor=${LMI_TRIPLET}-$gcc_version-$(git rev-parse --short HEAD:third_party/wx)
 
 # Configuration reference:
 #   https://lists.nongnu.org/archive/html/lmi/2007-11/msg00001.html
@@ -154,7 +115,7 @@ mkdir --parents "$build_dir"
 cd "$build_dir"
 # 'configure' options must not be double-quoted
 # shellcheck disable=SC2086
-"$proxy_wx_dir"/configure $config_options CFLAGS="$wx_cc_flags" 
CXXFLAGS="$wx_cxx_flags"
+"$wx_dir"/configure $config_options CFLAGS="$wx_cc_flags" 
CXXFLAGS="$wx_cxx_flags"
 $MAKE
 $MAKE install
 # autotools: 'make install' doesn't respect group permissions--see:
diff --git a/install_wxpdfdoc.sh b/install_wxpdfdoc.sh
index 9025484..53e062a 100755
--- a/install_wxpdfdoc.sh
+++ b/install_wxpdfdoc.sh
@@ -23,18 +23,8 @@
 
 set -vxe
 
-# A repository is cached in /srv/cache_for_lmi/vcs/, where it can be
-# kept up to date and reused cheaply--whereas cloning it from a remote
-# host takes considerable time and bandwidth, and fails if internet
-# connectivity is lost, or the host is temporarily unavailable, or
-# it is blocked by a corporate firewall.
-
 # Configurable settings 
########################################################
 
-remote_host_url=${remote_host_url:-"https://github.com/vadz/wxpdfdoc.git"}
-
-wxpdfdoc_commit_sha=${wxpdfdoc_commit_sha:-"acbd019d18e991cca46a80e1be58e637774d5d3b"}
-
 wxpdfdoc_skip_clean=${wxpdfdoc_skip_clean:-"0"}
 
 coefficiency=${coefficiency:-"--jobs=$(nproc)"}
@@ -51,37 +41,12 @@ mingw_dir=/opt/lmi/${LMI_COMPILER}_${LMI_TRIPLET}/gcc_msw
 prefix=/opt/lmi/local
 exec_prefix="$prefix/${LMI_COMPILER}_${LMI_TRIPLET}"
 
-repo_name="wxpdfdoc"
-
-# Script commands 
##############################################################
-
-proxy_parent_dir="/srv/cache_for_lmi/vcs"
-mkdir --parents "$proxy_parent_dir"
-
-proxy_wxpdfdoc_dir="$proxy_parent_dir"/$repo_name
-
-# Create a local mirror if it doesn't already exist.
-if [ ! -d "$proxy_wxpdfdoc_dir" ]
-then
-    cd "$proxy_parent_dir"
-    git clone "$coefficiency" "$remote_host_url" $repo_name
-fi
+srcdir=$(dirname "$(readlink --canonicalize "$0")")
+wxpdfdoc_dir="$srcdir/third_party/wxpdfdoc"
 
-cd "$proxy_wxpdfdoc_dir"
+build_type=$(/usr/share/misc/config.guess)
 
-# Fetch desired commit from remote host if missing.
-if ! git rev-parse --quiet --verify "$wxpdfdoc_commit_sha^{commit}" >/dev/null
-then
-    git fetch origin
-fi
-
-# Reset in case git-checkout would fail. See:
-#   https://lists.nongnu.org/archive/html/lmi/2020-07/msg00053.html
-git reset --hard
-
-git checkout "$wxpdfdoc_commit_sha"
-
-build_type=$("$proxy_wxpdfdoc_dir"/admin/build-aux/config.guess)
+# Script commands 
##############################################################
 
 case "$build_type" in
     (*-*-cygwin*)
@@ -97,17 +62,31 @@ config_options="
   --exec-prefix=$exec_prefix
   --with-wx-prefix=$prefix
   --with-wx-exec-prefix=$exec_prefix
-  --build=$build_type
-  --host=$LMI_TRIPLET
   --disable-dependency-tracking
 "
 
+# Provide the host and the build type only when cross-compiling,
+# because specifying host for native builds, e.g.:
+#   wx-config --host=$(/usr/share/misc/config.guess)
+# fails. See:
+#   https://lists.nongnu.org/archive/html/lmi/2020-10/msg00039.html
+#   https://trac.wxwidgets.org/ticket/12698
+if [ "$LMI_TRIPLET" != "$build_type" ]
+then
+    config_options="
+      $config_options
+      --build=$build_type
+      --host=$LMI_TRIPLET
+    "
+fi
+
 [ -n "$mingw_bin_dir" ] && export PATH="$mingw_bin_dir:${PATH}"
 
-cd "$proxy_wxpdfdoc_dir"
+cd "$wxpdfdoc_dir"
 autoreconf --verbose
 
-build_dir="$exec_prefix/wxpdfdoc-ad_hoc/wxpdfdoc-$wxpdfdoc_commit_sha"
+gcc_version=$(make --no-print-directory --directory="$srcdir" show_gcc_version)
+build_dir="$exec_prefix/wxpdfdoc-ad_hoc/lmi-$LMI_COMPILER-$gcc_version"
 
 if [ "$wxpdfdoc_skip_clean" != 1 ]
 then
@@ -121,7 +100,7 @@ mkdir --parents "$build_dir"
 cd "$build_dir"
 # 'configure' options must not be double-quoted
 # shellcheck disable=SC2086
-"$proxy_wxpdfdoc_dir"/configure $config_options CFLAGS="$wxpdfdoc_cc_flags" 
CXXFLAGS="$wxpdfdoc_cxx_flags"
+"$wxpdfdoc_dir"/configure $config_options CFLAGS="$wxpdfdoc_cc_flags" 
CXXFLAGS="$wxpdfdoc_cxx_flags"
 $MAKE
 $MAKE install
 # autotools: 'make install' doesn't respect group permissions--see:
diff --git a/install_libxml2_libxslt.sh b/install_xml_libraries.sh
similarity index 68%
rename from install_libxml2_libxslt.sh
rename to install_xml_libraries.sh
index dcb2746..88b059f 100755
--- a/install_libxml2_libxslt.sh
+++ b/install_xml_libraries.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Install libxml2 and libxslt with options suitable for lmi.
+# Install libxml2, libxslt and xmlwrapp with options suitable for lmi.
 #
 # Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 
2016, 2017, 2018, 2019, 2020 Gregory W. Chicares.
 #
@@ -45,7 +45,7 @@ srcdir=$(dirname "$(readlink --canonicalize "$0")")
 
 build_dir="${exec_prefix}/xml-ad_hoc"
 
-build_type=$(/usr/share/libtool/build-aux/config.guess)
+build_type=$(/usr/share/misc/config.guess)
 
 case "$build_type" in
     (*-*-cygwin*)
@@ -55,6 +55,9 @@ esac
 
 export PKG_CONFIG_PATH="$exec_prefix/lib/pkgconfig"
 
+# Don't prepend libraries and headers paths with the sysroot directory.
+export PKG_CONFIG_SYSROOT_DIR=
+
 # For 'host' and 'build' configure options, see:
 #   https://cygwin.com/ml/cygwin/2002-01/msg00837.html
 # Do not use '-fno-omit-frame-pointer' because of an ICE:
@@ -93,7 +96,14 @@ xmlsoft_common_cflags=$(echo '
   -Wno-unused-variable
 ' | tr '\n' ' ' | tr -s ' ' )
 
-xmlsoft_common_options="
+xmlsoft_common_ldflags=""
+case "$LMI_TRIPLET" in
+    *-*-cygwin*|*-*-mingw*)
+        xmlsoft_common_ldflags="$xmlsoft_common_ldflags -lws2_32"
+        ;;
+esac
+
+third_party_libraries_common_options="
   --prefix=$prefix
   --exec-prefix=$exec_prefix
   --build=$build_type
@@ -101,11 +111,15 @@ xmlsoft_common_options="
   --disable-dependency-tracking
   --disable-static
   --enable-shared
+"
+
+xmlsoft_common_options="
+  $third_party_libraries_common_options
   --with-debug
   --without-python
 "
 
-# This variable is used inside eval, which is beyond spellcheck's ken.
+# This variable is used inside eval, which is beyond shellcheck's ken.
 # shellcheck disable=SC2034
 libxml2_options="
   $xmlsoft_common_options
@@ -131,7 +145,14 @@ libxslt_options="
   --without-crypto
 "
 
-# Actually build ##############################################################
+xmlwrapp_options="
+  $third_party_libraries_common_options
+  --disable-docs
+  --disable-examples
+  --disable-tests
+"
+
+# Optionally, clean beforehand ################################################
 
 # Nonchalantly remove pkgconfig and cmake subdirectories, even though
 # other libraries might someday write files in them, because lmi never
@@ -141,19 +162,48 @@ libxslt_options="
 # each package's makefile.
 if [ "$xml_skip_clean" != 1 ]; then
     rm --force --recursive "$exec_prefix"/bin/*xml2*
+    rm --force --recursive "$exec_prefix"/bin/*xmlwrapp*
     rm --force --recursive "$exec_prefix"/bin/*xslt*
     rm --force --recursive "$exec_prefix"/bin/xmllint*
     rm --force --recursive "$exec_prefix"/bin/xmlcatalog*
     rm --force --recursive "$exec_prefix"/include/libxml2
+    rm --force --recursive "$exec_prefix"/include/libxmlwrapp
     rm --force --recursive "$exec_prefix"/include/libxslt
+    rm --force --recursive "$exec_prefix"/include/libxsltwrapp
     rm --force --recursive "$exec_prefix"/include/libexslt
     rm --force --recursive "$exec_prefix"/lib/*xml2*
+    rm --force --recursive "$exec_prefix"/lib/*xmlwrapp*
     rm --force --recursive "$exec_prefix"/lib/*xslt*
     rm --force --recursive "$exec_prefix"/lib/cmake
     rm --force --recursive "$exec_prefix"/lib/pkgconfig
     rm --force --recursive "$build_dir"
 fi
 
+# Create an XML catalog #######################################################
+
+# This forestalls about a thousand lines of bogus error messages.
+
+throwaway_catalog=/etc/opt/lmi/xml_catalog
+
+cat >"$throwaway_catalog" <<EOF
+<?xml version="1.0"?>
+<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog 
V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd";>
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+  <rewriteURI 
uriStartString="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";
+   
rewritePrefix="file://$PWD/third_party/libxml2/test/valid/dtds/xhtml1-transitional.dtd"/>
+  <rewriteURI uriStartString="http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent";
+   
rewritePrefix="file://$PWD/third_party/libxml2/test/valid/dtds/xhtml-lat1.ent"/>
+  <rewriteURI 
uriStartString="http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent";
+   
rewritePrefix="file://$PWD/third_party/libxml2/test/valid/dtds/xhtml-special.ent"/>
+  <rewriteURI uriStartString="http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent";
+   
rewritePrefix="file://$PWD/third_party/libxml2/test/valid/dtds/xhtml-symbol.ent"/>
+</catalog>
+EOF
+
+export XML_CATALOG_FILES="$throwaway_catalog"
+
+# Actually build ##############################################################
+
 for lib in libxml2 libxslt; do
     libdir="$srcdir/third_party/$lib"
     if [ ! -x "$libdir/configure" ]; then
@@ -165,13 +215,35 @@ for lib in libxml2 libxslt; do
     # 'configure' options must not be double-quoted
     # shellcheck disable=SC2046
     "$libdir/configure" \
-        LDFLAGS='-lws2_32' \
+        LDFLAGS="$xmlsoft_common_ldflags" \
         CPPFLAGS='-w' \
         CFLAGS="-g -O2 $xmlsoft_common_cflags" \
         $(eval "echo \$${lib}_options")
     $MAKE install
 done
 
+# Building xmlwrapp is similar, but sufficiently different to not try to fit it
+# into the loop above, but reuse the same structure for it just to emphasize
+# the similarity.
+# shellcheck disable=SC2043
+for lib in xmlwrapp; do
+    libdir="$srcdir/third_party/$lib"
+    if [ ! -x "$libdir/configure" ]; then
+        cd "$libdir"
+        autoreconf --install
+    fi
+    mkdir --parents "$build_dir/$lib"
+    cd "$build_dir/$lib"
+    # shellcheck disable=SC2086
+    "$libdir/configure" \
+        PKG_CONFIG_LIBDIR="$exec_prefix"/lib/pkgconfig \
+        $xmlwrapp_options
+    $MAKE install
+done
+
+# Expunge the throwaway XML catalog.
+rm --force "$throwaway_catalog"
+
 # autotools: 'make install' doesn't respect group permissions--see:
 #   https://lists.gnu.org/archive/html/automake/2019-01/msg00000.html
 # After the 'chmod' calls, the 'find' command should find nothing.
@@ -185,6 +257,8 @@ chmod -R g=u "$build_dir"
 chmod -R g=u "$prefix"/include/libexslt
 chmod -R g=u "$prefix"/include/libxml2
 chmod -R g=u "$prefix"/include/libxslt
+chmod -R g=u "$prefix"/include/xmlwrapp
+chmod -R g=u "$prefix"/include/xsltwrapp
 chmod -R g=u "$prefix"/share/doc/libxml2-*
 chmod -R g=u "$prefix"/share/doc/libxslt-*
 chmod -R g=u "$prefix"/share/gtk-doc/html/libxml2
diff --git a/interpolate_string.hpp b/interpolate_string.hpp
index 4a5d2d8..67c49a7 100644
--- a/interpolate_string.hpp
+++ b/interpolate_string.hpp
@@ -63,7 +63,7 @@ using lookup_function
 /// Throw if the lookup function throws, if the string uses invalid syntax or
 /// if the maximum recursion level is exceeded.
 
-std::string LMI_SO interpolate_string
+LMI_SO std::string interpolate_string
     (char const* s
     ,lookup_function const& lookup
     );
diff --git a/ledger.hpp b/ledger.hpp
index db92c75..4c6d059 100644
--- a/ledger.hpp
+++ b/ledger.hpp
@@ -140,7 +140,7 @@ std::vector<double> numeric_vector
     ,std::string const& compound_name
     );
 
-bool LMI_SO is_interdicted      (Ledger const&);
-void LMI_SO throw_if_interdicted(Ledger const&);
+LMI_SO bool is_interdicted      (Ledger const&);
+LMI_SO void throw_if_interdicted(Ledger const&);
 
 #endif // ledger_hpp
diff --git a/ledger_evaluator.cpp b/ledger_evaluator.cpp
index e6d7820..f6662a8 100644
--- a/ledger_evaluator.cpp
+++ b/ledger_evaluator.cpp
@@ -31,7 +31,7 @@
 #include "configurable_settings.hpp"
 #include "contains.hpp"
 #include "global_settings.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "ledger_invariant.hpp"
 #include "ledger_text_formats.hpp"      // ledger_format()
 #include "ledger_variant.hpp"
diff --git a/ledger_invariant.cpp b/ledger_invariant.cpp
index 0fa60ee..63cfa6d 100644
--- a/ledger_invariant.cpp
+++ b/ledger_invariant.cpp
@@ -302,7 +302,6 @@ void LedgerInvariant::Alloc(int len)
     Strings         ["FlexiblePremiumFootnote"    ] = &FlexiblePremiumFootnote 
   ;
     Strings         ["GuaranteedValuesFootnote"   ] = 
&GuaranteedValuesFootnote   ;
     Strings         ["CreditingRateFootnote"      ] = &CreditingRateFootnote   
   ;
-    Strings         ["DefnGuarGenAcctRate"        ] = &DefnGuarGenAcctRate     
   ;
     Strings         ["GrossRateFootnote"          ] = &GrossRateFootnote       
   ;
     Strings         ["NetRateFootnote"            ] = &NetRateFootnote         
   ;
     Strings         ["MecFootnote"                ] = &MecFootnote             
   ;
@@ -357,6 +356,7 @@ void LedgerInvariant::Alloc(int len)
     Strings         ["Fn1035Charge"               ] = &Fn1035Charge            
   ;
     Strings         ["FnMecExtraWarning"          ] = &FnMecExtraWarning       
   ;
     Strings         ["FnNotTaxAdvice"             ] = &FnNotTaxAdvice          
   ;
+    Strings         ["FnNotTaxAdvice2"            ] = &FnNotTaxAdvice2         
   ;
     Strings         ["FnImf"                      ] = &FnImf                   
   ;
     Strings         ["FnCensus"                   ] = &FnCensus                
   ;
     Strings         ["FnDacTax"                   ] = &FnDacTax                
   ;
@@ -371,6 +371,7 @@ void LedgerInvariant::Alloc(int len)
     Strings         ["FnOmnibusDisclaimer"        ] = &FnOmnibusDisclaimer     
   ;
     Strings         ["FnInitialDbo"               ] = &FnInitialDbo            
   ;
 
+    Strings         ["DefnGuarGenAcctRate"        ] = &DefnGuarGenAcctRate     
   ;
     Strings         ["DefnAV"                     ] = &DefnAV                  
   ;
     Strings         ["DefnCSV"                    ] = &DefnCSV                 
   ;
     Strings         ["DefnMec"                    ] = &DefnMec                 
   ;
diff --git a/ledger_invariant.hpp b/ledger_invariant.hpp
index a3c9faf..484963a 100644
--- a/ledger_invariant.hpp
+++ b/ledger_invariant.hpp
@@ -191,7 +191,7 @@ class LMI_SO LedgerInvariant final
 
     // Essential strings describing the policy and company.
     std::string PolicyForm;
-    // Ledger needs no member like product_data::PolicyFormAlternative;
+    // Ledger needs no member like product_data::PolicyFormAlternative; // 
LINGO !! expunge
     std::string PolicyMktgName;
     std::string PolicyLegalName;
     std::string CsoEra;
@@ -313,7 +313,6 @@ class LMI_SO LedgerInvariant final
     std::string FlexiblePremiumFootnote;
     std::string GuaranteedValuesFootnote;
     std::string CreditingRateFootnote;
-    std::string DefnGuarGenAcctRate;
     std::string GrossRateFootnote;
     std::string NetRateFootnote;
     std::string MecFootnote;
@@ -367,6 +366,7 @@ class LMI_SO LedgerInvariant final
     std::string Fn1035Charge;
     std::string FnMecExtraWarning;
     std::string FnNotTaxAdvice;
+    std::string FnNotTaxAdvice2;
     std::string FnImf;
     std::string FnCensus;
     std::string FnDacTax;
@@ -380,6 +380,7 @@ class LMI_SO LedgerInvariant final
     std::string FnGuaranteedPremium;
     std::string FnOmnibusDisclaimer;
     std::string FnInitialDbo;
+    std::string DefnGuarGenAcctRate;
     std::string DefnAV;
     std::string DefnCSV;
     std::string DefnMec;
diff --git a/ledger_invariant_init.cpp b/ledger_invariant_init.cpp
index e759f28..035bfa6 100644
--- a/ledger_invariant_init.cpp
+++ b/ledger_invariant_init.cpp
@@ -33,6 +33,7 @@
 #include "death_benefits.hpp"
 #include "fund_data.hpp"
 #include "interest_rates.hpp"
+#include "lingo.hpp"
 #include "lmi.hpp"                      // is_antediluvian_fork()
 #include "loads.hpp"
 #include "mc_enum_types_aux.hpp"        // mc_str()
@@ -79,6 +80,9 @@ void LedgerInvariant::Init(BasicValues const* b)
 
     irr_precision_ = b->round_irr().decimals();
 
+    ProductName                = b->yare_input_.ProductName;
+    StateOfJurisdiction        = mc_str(b->GetStateOfJurisdiction());
+
     // BOY vectors.
 
 //  GrossPmt                   = DYNAMIC
@@ -313,7 +317,7 @@ void LedgerInvariant::Init(BasicValues const* b)
     if(!is_antediluvian_fork())
         {
         product_data const& p = b->product();
-        // Accommodate one alternative policy-form name.
+        // Accommodate one alternative policy-form name. // LINGO !! expunge 
this block:
         // DATABASE !! It would be much better, of course, to let all
         // strings in class product_data vary across the same axes as
         // database_entity objects.
@@ -325,7 +329,55 @@ void LedgerInvariant::Init(BasicValues const* b)
 
         // Strings.
 
-        PolicyForm = p.datum(alt_form ? "PolicyFormAlternative" : 
"PolicyForm");
+        PolicyForm = p.datum(alt_form ? "PolicyFormAlternative" : 
"PolicyForm"); // LINGO !! expunge old implementation here
+
+        auto policy_form = b->database().query<int>(DB_PolicyForm);
+        bool const policy_form_is_okay =
+               b->lingo_->lookup(policy_form) == PolicyForm
+            || "{PolicyFormAlternative}" == PolicyForm
+            ;
+        if(!policy_form_is_okay)
+            alarum()
+                << b->lingo_->lookup(policy_form) << " 
b->lingo_->lookup(policy_form)\n"
+                << PolicyForm << " PolicyForm\n"
+                << LMI_FLUSH
+                ;
+        PolicyForm = b->lingo_->lookup(policy_form);
+
+        // LINGO !! Temporary expedient: validate all lingo.
+        if(begins_with(ProductName, "sample"))
+            for(auto const& i : p.member_names())
+                {
+                if(ends_with(i, "Filename") || i == "InsCoDomicile")
+                    continue;
+                auto const k = 
static_cast<e_database_key>(db_key_from_name(i));
+                auto const lingo_index = 
b->database().query<e_database_key>(k);
+                std::string const newer = b->lingo_->lookup(lingo_index);
+                std::string const older = p.datum(i);
+                if(newer != older)
+                    {
+                    // Allow an "alternative" policy form for now.
+                    if("PolicyForm" == i)
+                        warning()
+                            << "Expected difference:\n"
+                            << i << " entity\n"
+                            << newer << " newer\n"
+                            << older << " older\n"
+                            << StateOfJurisdiction << " StateOfJurisdiction\n"
+                            << LMI_FLUSH
+                            ;
+                    else
+                        alarum()
+                            << "ERROR:\n"
+                            << i << " entity\n"
+                            << newer << " newer\n"
+                            << older << " older\n"
+                            << StateOfJurisdiction << " StateOfJurisdiction\n"
+                            << LMI_FLUSH
+                            ;
+                    }
+                }
+
         PolicyMktgName             = p.datum("PolicyMktgName"                 
);
         PolicyLegalName            = p.datum("PolicyLegalName"                
);
         CsoEra     = mc_str(b->database().query<mcenum_cso_era>(DB_CsoEra));
@@ -446,7 +498,6 @@ void LedgerInvariant::Init(BasicValues const* b)
         FlexiblePremiumFootnote    = p.datum("FlexiblePremiumFootnote"        
);
         GuaranteedValuesFootnote   = p.datum("GuaranteedValuesFootnote"       
);
         CreditingRateFootnote      = p.datum("CreditingRateFootnote"          
);
-        DefnGuarGenAcctRate        = p.datum("DefnGuarGenAcctRate"            
);
         GrossRateFootnote          = p.datum("GrossRateFootnote"              
);
         NetRateFootnote            = p.datum("NetRateFootnote"                
);
         MecFootnote                = p.datum("MecFootnote"                    
);
@@ -500,6 +551,7 @@ void LedgerInvariant::Init(BasicValues const* b)
         Fn1035Charge               = p.datum("Fn1035Charge"                   
);
         FnMecExtraWarning          = p.datum("FnMecExtraWarning"              
);
         FnNotTaxAdvice             = p.datum("FnNotTaxAdvice"                 
);
+        FnNotTaxAdvice2            = p.datum("FnNotTaxAdvice2"                
);
         FnImf                      = p.datum("FnImf"                          
);
         FnCensus                   = p.datum("FnCensus"                       
);
         FnDacTax                   = p.datum("FnDacTax"                       
);
@@ -513,6 +565,7 @@ void LedgerInvariant::Init(BasicValues const* b)
         FnGuaranteedPremium        = p.datum("FnGuaranteedPremium"            
);
         FnOmnibusDisclaimer        = p.datum("FnOmnibusDisclaimer"            
);
         FnInitialDbo               = p.datum("FnInitialDbo"                   
);
+        DefnGuarGenAcctRate        = p.datum("DefnGuarGenAcctRate"            
);
         DefnAV                     = p.datum("DefnAV"                         
);
         DefnCSV                    = p.datum("DefnCSV"                        
);
         DefnMec                    = p.datum("DefnMec"                        
);
@@ -522,7 +575,6 @@ void LedgerInvariant::Init(BasicValues const* b)
 
     // Strings from class Input.
 
-    ProductName                = b->yare_input_.ProductName;
     ProducerName               = b->yare_input_.AgentName;
 
     std::string const agent_city     = b->yare_input_.AgentCity;
@@ -584,7 +636,6 @@ void LedgerInvariant::Init(BasicValues const* b)
     DefnLifeIns                = 
mc_str(b->yare_input_.DefinitionOfLifeInsurance);
     DefnMaterialChange         = 
mc_str(b->yare_input_.DefinitionOfMaterialChange);
     PartMortTableName          = "1983 GAM"; // TODO ?? Hardcoded.
-    StateOfJurisdiction        = mc_str(b->GetStateOfJurisdiction());
     PremiumTaxState            = mc_str(b->GetPremiumTaxState());
     CountryIso3166Abbrev       = mc_str(b->yare_input_.Country);
     Comments                   = b->yare_input_.Comments;
diff --git a/ledger_text_formats.hpp b/ledger_text_formats.hpp
index b16599f..5b7fd7c 100644
--- a/ledger_text_formats.hpp
+++ b/ledger_text_formats.hpp
@@ -34,22 +34,22 @@
 
 class Ledger;
 
-std::string LMI_SO FormatSelectedValuesAsHtml(Ledger const&);
-std::string LMI_SO FormatSelectedValuesAsTsv (Ledger const&);
+LMI_SO std::string FormatSelectedValuesAsHtml(Ledger const&);
+LMI_SO std::string FormatSelectedValuesAsTsv (Ledger const&);
 
-void LMI_SO PrintCellTabDelimited  (Ledger const&, std::string const& 
file_name);
+LMI_SO void PrintCellTabDelimited  (Ledger const&, std::string const& 
file_name);
 
-void LMI_SO PrintRosterHeaders     (               std::string const& 
file_name);
-void LMI_SO PrintRosterTabDelimited(Ledger const&, std::string const& 
file_name);
+LMI_SO void PrintRosterHeaders     (               std::string const& 
file_name);
+LMI_SO void PrintRosterTabDelimited(Ledger const&, std::string const& 
file_name);
 
-void LMI_SO PrintLedgerFlatText    (Ledger const&, std::ostream&);
+LMI_SO void PrintLedgerFlatText    (Ledger const&, std::ostream&);
 
-std::string LMI_SO ledger_format
+LMI_SO std::string ledger_format
     (double                            d
     ,std::pair<int,oenum_format_style> f
     );
 
-std::vector<std::string> LMI_SO ledger_format
+LMI_SO std::vector<std::string> ledger_format
     (std::vector<double> const&        dv
     ,std::pair<int,oenum_format_style> f
     );
diff --git a/license.hpp b/license.hpp
index 69f8cb2..171a6b3 100644
--- a/license.hpp
+++ b/license.hpp
@@ -36,9 +36,9 @@
 // ensures that the license and its required notices are available
 // unaltered.
 
-std::string const& LMI_SO license_as_html();
-std::string const& LMI_SO license_as_text();
-std::string const& LMI_SO license_notices_as_html();
-std::string const& LMI_SO license_notices_as_text();
+LMI_SO std::string const& license_as_html();
+LMI_SO std::string const& license_as_text();
+LMI_SO std::string const& license_notices_as_html();
+LMI_SO std::string const& license_notices_as_text();
 
 #endif // license_hpp
diff --git a/lingo.cpp b/lingo.cpp
new file mode 100644
index 0000000..5bfa449
--- /dev/null
+++ b/lingo.cpp
@@ -0,0 +1,687 @@
+// Text to be dropped into report templates.
+//
+// Copyright (C) 2020 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
+//
+// https://savannah.nongnu.org/projects/lmi
+// email: <gchicares@sbcglobal.net>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+#include "pchfile.hpp"
+
+#include "lingo.hpp"
+
+#include "alert.hpp"
+#include "data_directory.hpp"           // AddDataDir()
+#include "map_lookup.hpp"
+#include "my_proem.hpp"                 // ::write_proem()
+#include "sample.hpp"                   // superior::lingo
+#include "xml_lmi.hpp"
+#include "xml_serialize.hpp"
+
+#include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/path.hpp>
+
+/// Construct from filename.
+
+lingo::lingo(std::string const& filename)
+{
+    xml_lmi::dom_parser parser(filename);
+    xml::element const& root = parser.root_node(xml_root_name());
+    int file_version = 0;
+    if(!xml_lmi::get_attr(root, "version", file_version))
+        {
+        alarum()
+            << "XML tag <"
+            << xml_root_name()
+            << "> lacks required version attribute."
+            << LMI_FLUSH
+            ;
+        }
+    xml_serialize::from_xml(root, map_);
+}
+
+std::string const& lingo::lookup(int index) const
+{
+    return map_lookup(map_, index);
+}
+
+namespace
+{
+static std::string const S_FnMonthlyDeductions =
+  "Monthly charges are deducted from the account value; if it is depleted,"
+  " additional premiums may be required.";
+
+// These two certifications are copied verbatim et literatim from the
+// illustration reg.
+static std::string const S_IllRegCertAgent =
+  "I certify that this illustration has been presented to the applicant and"
+  " that I have explained that any non-guaranteed elements illustrated are"
+  " subject to change. I have made no statements that are inconsistent with"
+  " the illustration.";
+static std::string const S_IllRegCertClient =
+  "I have received a copy of this illustration and understand that any"
+  " non-guaranteed elements illustrated are subject to change and could be"
+  " either higher or lower. The agent has told me they are not guaranteed.";
+
+static std::string const S_FnMaturityAge =
+  "¶¶Maturity age: {{EndtAge}}.";
+
+static std::string const S_FnPartialMortality =
+  "¶¶Columns reflect mortality, beginning at {{PartMortTableMult[0]}}"
+  " of the {{PartMortTableName}} table,"
+  " with all deaths at the end of each year"
+  "{{#SurviveToExpectancy}}"
+  " and survival limited to life expectancy"
+  "{{/SurviveToExpectancy}}"
+  "{{#SurviveToYear}}"
+  " and survival limited to {{SurvivalMaxYear}} years"
+  "{{/SurviveToYear}}"
+  "{{#SurviveToAge}}"
+  " and survival limited to age {{SurvivalMaxAge}}"
+  "{{/SurviveToAge}}"
+  ".";
+
+static std::string const S_FnProspectus =
+  "Must be preceded or accompanied by a prospectus.";
+static std::string const S_FnInitialSpecAmt =
+  "The initial specified amount is ${{InitTotalSA}}.";
+static std::string const S_FnInforceAcctVal =
+  "The inforce account value is ${{InforceTotalAV}}.";
+static std::string const S_FnInforceTaxBasis =
+  "The inforce tax basis is ${{InforceTaxBasis}}.";
+static std::string const S_Fn1035Charge =
+  "A charge may be deducted from the proceeds of a 1035 exchange.";
+static std::string const S_FnMecExtraWarning =
+  "{{#IsMec}}¶¶This is a Modified Endowment Contract.{{/IsMec}}";
+static std::string const S_FnNotTaxAdvice =
+  "{{InsCoShortName}} cannot give tax advice. Consult your own advisors.";
+static std::string const S_FnImf =
+  "Initial investment management fee: {{TotalIMF[0]}}.";
+static std::string const S_FnCensus =
+  ""; // There is no census attached to a composite.
+static std::string const S_FnDacTax =
+  "There is no explicit charge for DAC tax.";
+
+static std::string const S_FnDefnLifeIns =
+  "This policy is intended to qualify as life insurance under the IRC §7702"
+  "{{#DefnLifeInsIsGPT}}"
+  " guideline premium test. ${{InitGSP}} is the guideline single premium,"
+  " and ${{InitGLP}} is the guideline level premium."
+  "{{/DefnLifeInsIsGPT}}"
+  "{{^DefnLifeInsIsGPT}}"
+  "cash value accumulation test."
+  "{{/DefnLifeInsIsGPT}}";
+
+static std::string const S_FnBoyEoy =
+  "Premiums are payable in advance. Benefits are as of year end.";
+static std::string const S_FnGeneralAccount =
+  "The general account credits interest of at least 
{{InitAnnGenAcctInt_Guaranteed}}.";
+static std::string const S_FnPpMemorandum =
+  "Must be preceded or accompanied by a prospectus.";
+static std::string const S_FnPpAccreditedInvestor =
+  "Available only to accredited investors.";
+static std::string const S_FnPpLoads =
+  ""; // Explanation of any special loads.
+static std::string const S_FnProposalUnderwriting =
+  ""; // Explanation of group underwriting.
+static std::string const S_FnGuaranteedPremium =
+  "An outlay of ${{GuarPrem}} ({{InitEeMode}}) will guarantee coverage"
+  " to age {{EndtAge}}"
+  "{{#DefnLifeInsIsGPT}}"
+  ", subject to guideline premium test limits"
+  "{{/DefnLifeInsIsGPT}}"
+  ".";
+static std::string const S_FnOmnibusDisclaimer =
+  "Non-guaranteed values are based on current assumptions, which are"
+  " subject to change. Actual results may be more or less favorable.";
+static std::string const S_FnInitialDbo =
+  "The initial death benefit option is {{InitDBOpt}}.";
+static std::string const S_DefnGuarGenAcctRate =
+  "¶¶«Guaranteed Crediting Rate:»"
+  " The minimum annual interest rate credited on unloaned funds."
+  ;
+static std::string const S_DefnAV =
+  "Account value is the accumulation of payments less charges and 
disbursements.";
+static std::string const S_DefnCSV =
+  "Cash surrender value is account value less any surrender charge.";
+static std::string const S_DefnMec =
+  "A Modified Endowment Contract is a contract that does not qualify"
+  " for favorable tax treatment under IRC §7702A.";
+static std::string const S_DefnOutlay =
+  "Outlay is premium paid out of pocket.";
+static std::string const S_DefnSpecAmt =
+  "Specified amount is the nominal face amount.";
+static std::string const S_Poe0 =
+  "The \"Red Death\" had long devastated the country. No pestilence"
+  " had ever been so fatal, or so hideous. Blood was its Avatar and"
+  " its seal--the redness and the horror of blood. There were sharp"
+  " pains, and sudden dizziness, and then profuse bleeding at the"
+  " pores, with dissolution. The scarlet stains upon the body and"
+  " especially upon the face of the victim, were the pest ban which"
+  " shut him out from the aid and from the sympathy of his fellow-men."
+  " And the whole seizure, progress and termination of the disease,"
+  " were the incidents of half an hour.";
+static std::string const S_Poe1 =
+  "But the Prince Prospero was happy and dauntless and sagacious. When"
+  " his dominions were half depopulated, he summoned to his presence a"
+  " thousand hale and light-hearted friends from among the knights and"
+  " dames of his court, and with these retired to the deep seclusion"
+  " of one of his castellated abbeys. This was an extensive and"
+  " magnificent structure, the creation of the prince's own eccentric"
+  " yet august taste. A strong and lofty wall girdled it in. This wall"
+  " had gates of iron. The courtiers, having entered, brought furnaces"
+  " and massy hammers and welded the bolts. They resolved to leave"
+  " means neither of ingress nor egress to the sudden impulses of"
+  " despair or of frenzy from within. The abbey was amply provisioned."
+  " With such precautions the courtiers might bid defiance to contagion."
+  " The external world could take care of itself. In the meantime it"
+  " was folly to grieve, or to think. The prince had provided all the"
+  " appliances of pleasure. There were buffoons, there were"
+  " improvisatori, there were ballet-dancers, there were musicians,"
+  " there was Beauty, there was wine. All these and security were"
+  " within. Without was the \"Red Death\".";
+static std::string const S_Poe2 =
+  "It was towards the close of the fifth or sixth month of his"
+  " seclusion, and while the pestilence raged most furiously abroad,"
+  " that the Prince Prospero entertained his thousand friends at a"
+  " masked ball of the most unusual magnificence.";
+static std::string const S_Poe3 =
+  "It was a voluptuous scene, that masquerade. But first let me tell"
+  " of the rooms in which it was held. These were seven--an imperial"
+  " suite. In many palaces, however, such suites form a long and"
+  " straight vista, while the folding doors slide back nearly to the"
+  " walls on either hand, so that the view of the whole extent is"
+  " scarcely impeded. Here the case was very different, as might have"
+  " been expected from the duke's love of the _bizarre_. The apartments"
+  " were so irregularly disposed that the vision embraced but little"
+  " more than one at a time. There was a sharp turn at every twenty or"
+  " thirty yards, and at each turn a novel effect. To the right and"
+  " left, in the middle of each wall, a tall and narrow Gothic window"
+  " looked out upon a closed corridor which pursued the windings of the"
+  " suite. These windows were of stained glass whose color varied in"
+  " accordance with the prevailing hue of the decorations of the"
+  " chamber into which it opened. That at the eastern extremity was"
+  " hung, for example in blue--and vividly blue were its windows. The"
+  " second chamber was purple in its ornaments and tapestries, and here"
+  " the panes were purple. The third was green throughout, and so were"
+  " the casements. The fourth was furnished and lighted with orange--the"
+  " fifth with white--the sixth with violet. The seventh apartment was"
+  " closely shrouded in black velvet tapestries that hung all over the"
+  " ceiling and down the walls, falling in heavy folds upon a carpet of"
+  " the same material and hue. But in this chamber only, the color of"
+  " the windows failed to correspond with the decorations. The panes"
+  " here were scarlet--a deep blood color. Now in no one of the seven"
+  " apartments was there any lamp or candelabrum, amid the profusion of"
+  " golden ornaments that lay scattered to and fro or depended from the"
+  " roof. There was no light of any kind emanating from lamp or candle"
+  " within the suite of chambers. But in the corridors that followed the"
+  " suite, there stood, opposite to each window, a heavy tripod, bearing"
+  " a brazier of fire, that projected its rays through the tinted glass"
+  " and so glaringly illumined the room. And thus were produced a"
+  " multitude of gaudy and fantastic appearances. But in the western or"
+  " black chamber the effect of the fire-light that streamed upon the"
+  " dark hangings through the blood-tinted panes, was ghastly in the"
+  " extreme, and produced so wild a look upon the countenances of those"
+  " who entered, that there were few of the company bold enough to set"
+  " foot within its precincts at all.";
+} // Unnamed namespace.
+
+// 'sample2*' products generally use this pattern:
+//   ,{superior::TelephoneNumber_term, "{TelephoneNumber}"}
+// so that an MST template containing
+//   "Call {{TelephoneNumber}} for service."
+// is rendered to PDF as
+//   "Call {TelephoneNumber} for service."
+// which is useful for testing.
+//
+// LINGO !! reconsider this...
+// It would probably make more sense to write a separate map (perhaps
+// with separate enumerators) for 'sample' and 'sample2', instead of
+// combining them (as here) and distinguishing the 'sample2' elements
+// with a "_term" suffix. For the nonce, combining them into one large
+// '.lingo' file makes the overhead (and the need for caching) more
+// obvious: suppressing the '#if 1' block materially affects speed.
+
+void lingo::write_lingo_files()
+{
+    // superior::lingo enumerators are used for clarity in specifying
+    // this map. They decay to integers in the resulting file, which
+    // can therefore be read without the enumerators being visible.
+    //
+    // For clarity of presentation, every enumerator-string pair is
+    // explicitly initialized here, even if the string is empty; but
+    // that is not necessary, because superior::empty_string is used
+    // for database entities with the default value of zero.
+    //
+    static std::unordered_map<superior::lingo,std::string> const 
enumerative_map
+        {{superior::empty_string                        , ""}
+        // Essential strings describing the policy and company.
+        ,{superior::policy_form_term                    , "{PolicyForm}"}
+        ,{superior::policy_form                         , "UL32768-NY"}
+        ,{superior::policy_form_KS_KY                   , "UL32768-X"}
+#if 1
+        // LINGO !! reconsider this...
+        // These MixedCase terms seem better--it's easier to grep for a
+        // string that has no lower_case_with_underscores variant:
+//      ,{superior::PolicyForm_term                     , "{PolicyForm}"}
+//      ,{superior::PolicyForm                          , "UL32768-NY"}
+        ,{superior::PolicyFormAlternative_term          , 
"{PolicyFormAlternative}"} // LINGO !! expunge
+        ,{superior::PolicyFormAlternative               , "UL32768-X"} // 
LINGO !! expunge
+        ,{superior::PolicyMktgName_term                 , "{PolicyMktgName}"}
+        ,{superior::PolicyMktgName                      , "UL Supreme"}
+        ,{superior::PolicyLegalName_term                , "{PolicyLegalName}"}
+        ,{superior::PolicyLegalName                     , "Flexible Premium 
Adjustable Life Insurance Policy"}
+        ,{superior::InsCoShortName_term                 , "{InsCoShortName}"}
+        ,{superior::InsCoShortName                      , "Superior Life"}
+        ,{superior::InsCoName_term                      , "{InsCoName}"}
+        ,{superior::InsCoName                           , "Superior Life 
Insurance Company"}
+        ,{superior::InsCoAddr_term                      , "{InsCoAddr}"}
+        ,{superior::InsCoAddr                           , "Superior, WI 12345"}
+        ,{superior::InsCoStreet_term                    , "{InsCoStreet}"}
+        ,{superior::InsCoStreet                         , "246 Main Street"}
+        ,{superior::InsCoPhone_term                     , "{InsCoPhone}"}
+        ,{superior::InsCoPhone                          , "(800) 555-1212"}
+        ,{superior::MainUnderwriter_term                , "{MainUnderwriter}"}
+        ,{superior::MainUnderwriter                     , "Superior 
Securities"}
+        ,{superior::MainUnderwriterAddress_term         , 
"{MainUnderwriterAddress}"}
+        ,{superior::MainUnderwriterAddress              , "246-M Main Street, 
Superior, WI 12345"}
+        ,{superior::CoUnderwriter_term                  , "{CoUnderwriter}"}
+        ,{superior::CoUnderwriter                       , "Superior Investors"}
+        ,{superior::CoUnderwriterAddress_term           , 
"{CoUnderwriterAddress}"}
+        ,{superior::CoUnderwriterAddress                , "246-C Main Street, 
Superior, WI 12345"}
+
+        // Terms defined in the contract, which must be used for column
+        // headers, footnotes, etc. according to the illustration reg.
+        ,{superior::AvName_term                         , "{AvName}"}
+        ,{superior::AvName                              , "Account"}
+        ,{superior::CsvName_term                        , "{CsvName}"}
+        ,{superior::CsvName                             , "Cash Surrender"}
+        ,{superior::CsvHeaderName_term                  , "{CsvHeaderName}"}
+        ,{superior::CsvHeaderName                       , "Cash Surr"}
+        ,{superior::NoLapseProvisionName_term           , 
"{NoLapseProvisionName}"}
+        ,{superior::NoLapseProvisionName                , "No-lapse Provision"}
+        ,{superior::ContractName_term                   , "{ContractName}"}
+        ,{superior::ContractName                        , "contract"} // 
Alternatively, "policy" or "certificate".
+        ,{superior::DboName_term                        , "{DboName}"}
+        ,{superior::DboName                             , "Death Benefit 
Option"}
+        ,{superior::DboNameLevel_term                   , "{DboNameLevel}"}
+        ,{superior::DboNameLevel                        , "A"}
+        ,{superior::DboNameIncreasing_term              , 
"{DboNameIncreasing}"}
+        ,{superior::DboNameIncreasing                   , "B"}
+        ,{superior::DboNameReturnOfPremium_term         , 
"{DboNameReturnOfPremium}"}
+        ,{superior::DboNameReturnOfPremium              , "ROP"}
+        ,{superior::DboNameMinDeathBenefit_term         , 
"{DboNameMinDeathBenefit}"}
+        ,{superior::DboNameMinDeathBenefit              , "MDB"}
+        ,{superior::GenAcctName_term                    , "{GenAcctName}"}
+        ,{superior::GenAcctName                         , "General Account"}
+        ,{superior::GenAcctNameElaborated_term          , 
"{GenAcctNameElaborated}"}
+        ,{superior::GenAcctNameElaborated               , "General Account 
(GA)"}
+        ,{superior::SepAcctName_term                    , "{SepAcctName}"}
+        ,{superior::SepAcctName                         , "Separate Account"}
+        ,{superior::SpecAmtName_term                    , "{SpecAmtName}"}
+        ,{superior::SpecAmtName                         , "Specified Amount"}
+        ,{superior::SpecAmtNameElaborated_term          , 
"{SpecAmtNameElaborated}"}
+        ,{superior::SpecAmtNameElaborated               , "Specified (Face) 
Amount"}
+
+        // Underwriting terms.
+        ,{superior::UwBasisMedical_term                 , "{UwBasisMedical}"}
+        ,{superior::UwBasisMedical                      , "Medical"}
+        ,{superior::UwBasisParamedical_term             , 
"{UwBasisParamedical}"}
+        ,{superior::UwBasisParamedical                  , "Paramedical"}
+        ,{superior::UwBasisNonmedical_term              , 
"{UwBasisNonmedical}"}
+        ,{superior::UwBasisNonmedical                   , "Nonmedical"}
+        ,{superior::UwBasisSimplified_term              , 
"{UwBasisSimplified}"}
+        ,{superior::UwBasisSimplified                   , "Simplified Issue"}
+        ,{superior::UwBasisGuaranteed_term              , 
"{UwBasisGuaranteed}"}
+        ,{superior::UwBasisGuaranteed                   , "Guaranteed Issue"}
+        ,{superior::UwClassPreferred_term               , "{UwClassPreferred}"}
+        ,{superior::UwClassPreferred                    , "Preferred"}
+        ,{superior::UwClassStandard_term                , "{UwClassStandard}"}
+        ,{superior::UwClassStandard                     , "Standard"}
+        ,{superior::UwClassRated_term                   , "{UwClassRated}"}
+        ,{superior::UwClassRated                        , "Rated"}
+        ,{superior::UwClassUltra_term                   , "{UwClassUltra}"}
+        ,{superior::UwClassUltra                        , "Ultrapreferred"}
+
+        // Ledger column definitions.
+        ,{superior::AccountValueFootnote_term           , 
"{AccountValueFootnote}"}
+        ,{superior::AccountValueFootnote                , ""}
+        ,{superior::AttainedAgeFootnote_term            , 
"{AttainedAgeFootnote}"}
+        ,{superior::AttainedAgeFootnote                 , ""}
+        ,{superior::CashSurrValueFootnote_term          , 
"{CashSurrValueFootnote}"}
+        ,{superior::CashSurrValueFootnote               , ""}
+        ,{superior::DeathBenefitFootnote_term           , 
"{DeathBenefitFootnote}"}
+        ,{superior::DeathBenefitFootnote                , ""}
+        ,{superior::InitialPremiumFootnote_term         , 
"{InitialPremiumFootnote}"}
+        ,{superior::InitialPremiumFootnote              , ""}
+        ,{superior::NetPremiumFootnote_term             , 
"{NetPremiumFootnote}"}
+        ,{superior::NetPremiumFootnote                  , ""}
+        ,{superior::GrossPremiumFootnote_term           , 
"{GrossPremiumFootnote}"}
+        ,{superior::GrossPremiumFootnote                , ""}
+        ,{superior::OutlayFootnote_term                 , "{OutlayFootnote}"}
+        ,{superior::OutlayFootnote                      , ""}
+        ,{superior::PolicyYearFootnote_term             , 
"{PolicyYearFootnote}"}
+        ,{superior::PolicyYearFootnote                  , ""}
+
+        // Terse rider names.
+        ,{superior::ADDTerseName_term                   , "{ADDTerseName}"}
+        ,{superior::ADDTerseName                        , "Accident"}
+        ,{superior::InsurabilityTerseName_term          , 
"{InsurabilityTerseName}"}
+        ,{superior::InsurabilityTerseName               , "Insurability"}
+        ,{superior::ChildTerseName_term                 , "{ChildTerseName}"}
+        ,{superior::ChildTerseName                      , "Child"}
+        ,{superior::SpouseTerseName_term                , "{SpouseTerseName}"}
+        ,{superior::SpouseTerseName                     , "Spouse"}
+        ,{superior::TermTerseName_term                  , "{TermTerseName}"}
+        ,{superior::TermTerseName                       , "Term"}
+        ,{superior::WaiverTerseName_term                , "{WaiverTerseName}"}
+        ,{superior::WaiverTerseName                     , "Waiver"}
+        ,{superior::AccelBftRiderTerseName_term         , 
"{AccelBftRiderTerseName}"}
+        ,{superior::AccelBftRiderTerseName              , "Acceleration"}
+        ,{superior::OverloanRiderTerseName_term         , 
"{OverloanRiderTerseName}"}
+        ,{superior::OverloanRiderTerseName              , "Overloan"}
+
+        // Rider footnotes.
+        ,{superior::ADDFootnote_term                    , "{ADDFootnote}"}
+        ,{superior::ADDFootnote                         , ""}
+        ,{superior::ChildFootnote_term                  , "{ChildFootnote}"}
+        ,{superior::ChildFootnote                       , ""}
+        ,{superior::SpouseFootnote_term                 , "{SpouseFootnote}"}
+        ,{superior::SpouseFootnote                      , ""}
+        ,{superior::TermFootnote_term                   , "{TermFootnote}"}
+        ,{superior::TermFootnote                        , ""}
+        ,{superior::WaiverFootnote_term                 , "{WaiverFootnote}"}
+        ,{superior::WaiverFootnote                      , ""}
+        ,{superior::AccelBftRiderFootnote_term          , 
"{AccelBftRiderFootnote}"}
+        ,{superior::AccelBftRiderFootnote               , ""}
+        ,{superior::OverloanRiderFootnote_term          , 
"{OverloanRiderFootnote}"}
+        ,{superior::OverloanRiderFootnote               , ""}
+
+        // Group quotes.
+        ,{superior::GroupQuoteShortProductName_term     , 
"{GroupQuoteShortProductName}"}
+        ,{superior::GroupQuoteShortProductName          , "UL SUPREME®"}
+        ,{superior::GroupQuoteIsNotAnOffer_term         , 
"{GroupQuoteIsNotAnOffer}"}
+        ,{superior::GroupQuoteIsNotAnOffer              , "This is not an 
offer of insurance."}
+        ,{superior::GroupQuoteRidersFooter_term         , 
"{GroupQuoteRidersFooter}"}
+        ,{superior::GroupQuoteRidersFooter              , "Available riders: 
accident and waiver."}
+        ,{superior::GroupQuotePolicyFormId_term         , 
"{GroupQuotePolicyFormId}"}
+        ,{superior::GroupQuotePolicyFormId              , "Policy form 
UL32768-NY is a flexible premium contract."}
+        ,{superior::GroupQuoteStateVariations_term      , 
"{GroupQuoteStateVariations}"}
+        ,{superior::GroupQuoteStateVariations           , "Not available in 
all states."}
+        ,{superior::GroupQuoteProspectus_term           , 
"{GroupQuoteProspectus}"}
+        ,{superior::GroupQuoteProspectus                , "Read the prospectus 
carefully."}
+        ,{superior::GroupQuoteUnderwriter_term          , 
"{GroupQuoteUnderwriter}"}
+        ,{superior::GroupQuoteUnderwriter               , "Securities 
underwritten by Superior Securities."}
+        ,{superior::GroupQuoteBrokerDealer_term         , 
"{GroupQuoteBrokerDealer}"}
+        ,{superior::GroupQuoteBrokerDealer              , "Securities offered 
through Superior Brokerage."}
+        // Group plan type is one of:
+        //   -Mandatory: no individual selection of amounts; typically,
+        //     the employer pays the entire premium
+        //   -Voluntary: individual selection of amounts; typically, the
+        //      employee pays the premium; may be called "supplemental"
+        //      when it complements a (separate) "mandatory" plan
+        //   -Fusion: mandatory and supplemental combined; typically, the
+        //      employer and employee pay their respective premiums
+        ,{superior::GroupQuoteRubricMandatory_term      , 
"{GroupQuoteRubricMandatory}"}
+        ,{superior::GroupQuoteRubricMandatory           , "Mandatory"}
+        ,{superior::GroupQuoteRubricVoluntary_term      , 
"{GroupQuoteRubricVoluntary}"}
+        ,{superior::GroupQuoteRubricVoluntary           , "Voluntary"}
+        ,{superior::GroupQuoteRubricFusion_term         , 
"{GroupQuoteRubricFusion}"}
+        ,{superior::GroupQuoteRubricFusion              , "Fusion"}
+        ,{superior::GroupQuoteFooterMandatory_term      , 
"{GroupQuoteFooterMandatory}"}
+        ,{superior::GroupQuoteFooterMandatory           , "The employer pays 
all premiums."}
+        ,{superior::GroupQuoteFooterVoluntary_term      , 
"{GroupQuoteFooterVoluntary}"}
+        ,{superior::GroupQuoteFooterVoluntary           , "The employee pays 
all premiums."}
+        ,{superior::GroupQuoteFooterFusion_term         , 
"{GroupQuoteFooterFusion}"}
+        ,{superior::GroupQuoteFooterFusion              , "The employer and 
employee pay their respective premiums."}
+
+        // Premium-specific footnotes.
+        ,{superior::MinimumPremiumFootnote_term         , 
"{MinimumPremiumFootnote}"}
+        ,{superior::MinimumPremiumFootnote              , ""}
+        ,{superior::PremAllocationFootnote_term         , 
"{PremAllocationFootnote}"}
+        ,{superior::PremAllocationFootnote              , ""}
+
+        // Miscellaneous other footnotes.
+        ,{superior::InterestDisclaimer_term             , 
"{InterestDisclaimer}"}
+        ,{superior::InterestDisclaimer                  , ""}
+        ,{superior::GuarMortalityFootnote_term          , 
"{GuarMortalityFootnote}"}
+        ,{superior::GuarMortalityFootnote               , "Guaranteed 
mortality basis: {{CsoEra}} CSO."}
+        ,{superior::ProductDescription_term             , 
"{ProductDescription}"}
+        ,{superior::ProductDescription                  , ""}
+        ,{superior::StableValueFootnote_term            , 
"{StableValueFootnote}"}
+        ,{superior::StableValueFootnote                 , ""}
+        ,{superior::NoVanishPremiumFootnote_term        , 
"{NoVanishPremiumFootnote}"}
+        ,{superior::NoVanishPremiumFootnote             , ""}
+        ,{superior::RejectPremiumFootnote_term          , 
"{RejectPremiumFootnote}"}
+        ,{superior::RejectPremiumFootnote               , ""}
+        ,{superior::ExpRatingFootnote_term              , 
"{ExpRatingFootnote}"}
+        ,{superior::ExpRatingFootnote                   , ""}
+        ,{superior::MortalityBlendFootnote_term         , 
"{MortalityBlendFootnote}"}
+        ,{superior::MortalityBlendFootnote              , ""}
+        ,{superior::HypotheticalRatesFootnote_term      , 
"{HypotheticalRatesFootnote}"}
+        ,{superior::HypotheticalRatesFootnote           , ""}
+        ,{superior::SalesLoadRefundFootnote_term        , 
"{SalesLoadRefundFootnote}"}
+        ,{superior::SalesLoadRefundFootnote             , ""}
+        ,{superior::NoLapseEverFootnote_term            , 
"{NoLapseEverFootnote}"}
+        ,{superior::NoLapseEverFootnote                 , ""}
+        ,{superior::NoLapseFootnote_term                , "{NoLapseFootnote}"}
+        ,{superior::NoLapseFootnote                     , ""}
+        ,{superior::CurrentValuesFootnote_term          , 
"{CurrentValuesFootnote}"}
+        ,{superior::CurrentValuesFootnote               , ""}
+        ,{superior::DBOption1Footnote_term              , 
"{DBOption1Footnote}"}
+        ,{superior::DBOption1Footnote                   , ""}
+        ,{superior::DBOption2Footnote_term              , 
"{DBOption2Footnote}"}
+        ,{superior::DBOption2Footnote                   , ""}
+        ,{superior::DBOption3Footnote_term              , 
"{DBOption3Footnote}"}
+        ,{superior::DBOption3Footnote                   , ""}
+        ,{superior::MinDeathBenefitFootnote_term        , 
"{MinDeathBenefitFootnote}"}
+        ,{superior::MinDeathBenefitFootnote             , ""}
+        ,{superior::ExpRatRiskChargeFootnote_term       , 
"{ExpRatRiskChargeFootnote}"}
+        ,{superior::ExpRatRiskChargeFootnote            , ""}
+        ,{superior::ExchangeChargeFootnote1_term        , 
"{ExchangeChargeFootnote1}"}
+        ,{superior::ExchangeChargeFootnote1             , ""}
+        ,{superior::FlexiblePremiumFootnote_term        , 
"{FlexiblePremiumFootnote}"}
+        ,{superior::FlexiblePremiumFootnote             , ""}
+        ,{superior::GuaranteedValuesFootnote_term       , 
"{GuaranteedValuesFootnote}"}
+        ,{superior::GuaranteedValuesFootnote            , ""}
+        ,{superior::CreditingRateFootnote_term          , 
"{CreditingRateFootnote}"}
+        ,{superior::CreditingRateFootnote               , ""}
+        ,{superior::GrossRateFootnote_term              , 
"{GrossRateFootnote}"}
+        ,{superior::GrossRateFootnote                   , ""}
+        ,{superior::NetRateFootnote_term                , "{NetRateFootnote}"}
+        ,{superior::NetRateFootnote                     , ""}
+        ,{superior::MecFootnote_term                    , "{MecFootnote}"}
+        ,{superior::MecFootnote                         , ""}
+        ,{superior::GptFootnote_term                    , "{GptFootnote}"}
+        ,{superior::GptFootnote                         , ""}
+        ,{superior::MidpointValuesFootnote_term         , 
"{MidpointValuesFootnote}"}
+        ,{superior::MidpointValuesFootnote              , ""}
+        ,{superior::SinglePremiumFootnote_term          , 
"{SinglePremiumFootnote}"}
+        ,{superior::SinglePremiumFootnote               , ""}
+        ,{superior::MonthlyChargesFootnote_term         , 
"{MonthlyChargesFootnote}"}
+        ,{superior::MonthlyChargesFootnote              , ""}
+        ,{superior::UltCreditingRateFootnote_term       , 
"{UltCreditingRateFootnote}"}
+        ,{superior::UltCreditingRateFootnote            , ""}
+        ,{superior::UltCreditingRateHeader_term         , 
"{UltCreditingRateHeader}"}
+        ,{superior::UltCreditingRateHeader              , ""}
+        ,{superior::MaxNaarFootnote_term                , "{MaxNaarFootnote}"}
+        ,{superior::MaxNaarFootnote                     , ""}
+        ,{superior::PremTaxSurrChgFootnote_term         , 
"{PremTaxSurrChgFootnote}"}
+        ,{superior::PremTaxSurrChgFootnote              , ""}
+        ,{superior::PolicyFeeFootnote_term              , 
"{PolicyFeeFootnote}"}
+        ,{superior::PolicyFeeFootnote                   , ""}
+        ,{superior::AssetChargeFootnote_term            , 
"{AssetChargeFootnote}"}
+        ,{superior::AssetChargeFootnote                 , ""}
+        ,{superior::InvestmentIncomeFootnote_term       , 
"{InvestmentIncomeFootnote}"}
+        ,{superior::InvestmentIncomeFootnote            , ""}
+        ,{superior::IrrDbFootnote_term                  , "{IrrDbFootnote}"}
+        ,{superior::IrrDbFootnote                       , ""}
+        ,{superior::IrrCsvFootnote_term                 , "{IrrCsvFootnote}"}
+        ,{superior::IrrCsvFootnote                      , ""}
+        ,{superior::MortalityChargesFootnote_term       , 
"{MortalityChargesFootnote}"}
+        ,{superior::MortalityChargesFootnote            , ""}
+        ,{superior::LoanAndWithdrawalFootnote_term      , 
"{LoanAndWithdrawalFootnote}"}
+        ,{superior::LoanAndWithdrawalFootnote           , ""}
+        ,{superior::LoanFootnote_term                   , "{LoanFootnote}"}
+        ,{superior::LoanFootnote                        , ""}
+        ,{superior::ImprimaturPresale_term              , 
"{ImprimaturPresale}"}
+        ,{superior::ImprimaturPresale                   , ""}
+        ,{superior::ImprimaturPresaleComposite_term     , 
"{ImprimaturPresaleComposite}"}
+        ,{superior::ImprimaturPresaleComposite          , ""}
+        ,{superior::ImprimaturInforce_term              , 
"{ImprimaturInforce}"}
+        ,{superior::ImprimaturInforce                   , ""}
+        ,{superior::ImprimaturInforceComposite_term     , 
"{ImprimaturInforceComposite}"}
+        ,{superior::ImprimaturInforceComposite          , ""}
+        ,{superior::StateMarketingImprimatur_term       , 
"{StateMarketingImprimatur}"}
+        ,{superior::StateMarketingImprimatur            , ""}
+        ,{superior::NonGuaranteedFootnote_term          , 
"{NonGuaranteedFootnote}"}
+        ,{superior::NonGuaranteedFootnote               , ""}
+        ,{superior::NonGuaranteedFootnote1_term         , 
"{NonGuaranteedFootnote1}"}
+        ,{superior::NonGuaranteedFootnote1              , ""}
+        ,{superior::NonGuaranteedFootnote1Tx_term       , 
"{NonGuaranteedFootnote1Tx}"}
+        ,{superior::NonGuaranteedFootnote1Tx            , ""}
+        ,{superior::FnMonthlyDeductions_term            , 
"{FnMonthlyDeductions}"}
+        ,{superior::FnMonthlyDeductions                 , 
S_FnMonthlyDeductions}
+        ,{superior::SurrenderFootnote_term              , 
"{SurrenderFootnote}"}
+        ,{superior::SurrenderFootnote                   , ""}
+        ,{superior::PortabilityFootnote_term            , 
"{PortabilityFootnote}"}
+        ,{superior::PortabilityFootnote                 , ""}
+        ,{superior::FundRateFootnote_term               , "{FundRateFootnote}"}
+        ,{superior::FundRateFootnote                    , ""}
+        ,{superior::IssuingCompanyFootnote_term         , 
"{IssuingCompanyFootnote}"}
+        ,{superior::IssuingCompanyFootnote              , ""}
+        ,{superior::SubsidiaryFootnote_term             , 
"{SubsidiaryFootnote}"}
+        ,{superior::SubsidiaryFootnote                  , ""}
+        ,{superior::PlacementAgentFootnote_term         , 
"{PlacementAgentFootnote}"}
+        ,{superior::PlacementAgentFootnote              , ""}
+        ,{superior::MarketingNameFootnote_term          , 
"{MarketingNameFootnote}"}
+        ,{superior::MarketingNameFootnote               , "Policy form 
UL32768-NY is marketed as 'UL Supreme'."}
+        ,{superior::GuarIssueDisclaimerNcSc_term        , 
"{GuarIssueDisclaimerNcSc}"}
+        ,{superior::GuarIssueDisclaimerNcSc             , ""}
+        ,{superior::GuarIssueDisclaimerMd_term          , 
"{GuarIssueDisclaimerMd}"}
+        ,{superior::GuarIssueDisclaimerMd               , ""}
+        ,{superior::GuarIssueDisclaimerTx_term          , 
"{GuarIssueDisclaimerTx}"}
+        ,{superior::GuarIssueDisclaimerTx               , ""}
+        ,{superior::IllRegCertAgent_term                , "{IllRegCertAgent}"}
+        ,{superior::IllRegCertAgent                     , S_IllRegCertAgent}
+        ,{superior::IllRegCertAgentIl_term              , 
"{IllRegCertAgentIl}"}
+        ,{superior::IllRegCertAgentIl                   , S_IllRegCertAgent}
+        ,{superior::IllRegCertAgentTx_term              , 
"{IllRegCertAgentTx}"}
+        ,{superior::IllRegCertAgentTx                   , S_IllRegCertAgent}
+        ,{superior::IllRegCertClient_term               , "{IllRegCertClient}"}
+        ,{superior::IllRegCertClient                    , S_IllRegCertClient}
+        ,{superior::IllRegCertClientIl_term             , 
"{IllRegCertClientIl}"}
+        ,{superior::IllRegCertClientIl                  , S_IllRegCertClient}
+        ,{superior::IllRegCertClientTx_term             , 
"{IllRegCertClientTx}"}
+        ,{superior::IllRegCertClientTx                  , S_IllRegCertClient}
+        ,{superior::FnMaturityAge_term                  , "{FnMaturityAge}"}
+        ,{superior::FnMaturityAge                       , S_FnMaturityAge}
+        ,{superior::FnPartialMortality_term             , 
"{FnPartialMortality}"}
+        ,{superior::FnPartialMortality                  , S_FnPartialMortality}
+        ,{superior::FnProspectus_term                   , "{FnProspectus}"}
+        ,{superior::FnProspectus                        , S_FnProspectus}
+        ,{superior::FnInitialSpecAmt_term               , "{FnInitialSpecAmt}"}
+        ,{superior::FnInitialSpecAmt                    , S_FnInitialSpecAmt}
+        ,{superior::FnInforceAcctVal_term               , "{FnInforceAcctVal}"}
+        ,{superior::FnInforceAcctVal                    , S_FnInforceAcctVal}
+        ,{superior::FnInforceTaxBasis_term              , 
"{FnInforceTaxBasis}"}
+        ,{superior::FnInforceTaxBasis                   , S_FnInforceTaxBasis}
+        ,{superior::Fn1035Charge_term                   , "{Fn1035Charge}"}
+        ,{superior::Fn1035Charge                        , S_Fn1035Charge}
+        ,{superior::FnMecExtraWarning_term              , 
"{FnMecExtraWarning}"}
+        ,{superior::FnMecExtraWarning                   , S_FnMecExtraWarning}
+        ,{superior::FnNotTaxAdvice_term                 , "{FnNotTaxAdvice}"}
+        ,{superior::FnNotTaxAdvice                      , S_FnNotTaxAdvice}
+        ,{superior::FnNotTaxAdvice2_term                , "{FnNotTaxAdvice2}"}
+        ,{superior::FnNotTaxAdvice2                     , ""} // Deliberately 
empty: shouldn't even exist.
+        ,{superior::FnImf_term                          , "{FnImf}"}
+        ,{superior::FnImf                               , S_FnImf}
+        ,{superior::FnCensus_term                       , "{FnCensus}"}
+        ,{superior::FnCensus                            , S_FnCensus}
+        ,{superior::FnDacTax_term                       , "{FnDacTax}"}
+        ,{superior::FnDacTax                            , S_FnDacTax}
+        ,{superior::FnDefnLifeIns_term                  , "{FnDefnLifeIns}"}
+        ,{superior::FnDefnLifeIns                       , S_FnDefnLifeIns}
+        ,{superior::FnBoyEoy_term                       , "{FnBoyEoy}"}
+        ,{superior::FnBoyEoy                            , S_FnBoyEoy}
+        ,{superior::FnGeneralAccount_term               , "{FnGeneralAccount}"}
+        ,{superior::FnGeneralAccount                    , S_FnGeneralAccount}
+        ,{superior::FnPpMemorandum_term                 , "{FnPpMemorandum}"}
+        ,{superior::FnPpMemorandum                      , S_FnPpMemorandum}
+        ,{superior::FnPpAccreditedInvestor_term         , 
"{FnPpAccreditedInvestor}"}
+        ,{superior::FnPpAccreditedInvestor              , 
S_FnPpAccreditedInvestor}
+        ,{superior::FnPpLoads_term                      , "{FnPpLoads}"}
+        ,{superior::FnPpLoads                           , S_FnPpLoads}
+        ,{superior::FnProposalUnderwriting_term         , 
"{FnProposalUnderwriting}"}
+        ,{superior::FnProposalUnderwriting              , 
S_FnProposalUnderwriting}
+        ,{superior::FnGuaranteedPremium_term            , 
"{FnGuaranteedPremium}"}
+        ,{superior::FnGuaranteedPremium                 , 
S_FnGuaranteedPremium}
+        ,{superior::FnOmnibusDisclaimer_term            , 
"{FnOmnibusDisclaimer}"}
+        ,{superior::FnOmnibusDisclaimer                 , 
S_FnOmnibusDisclaimer}
+        ,{superior::FnInitialDbo_term                   , "{FnInitialDbo}"}
+        ,{superior::FnInitialDbo                        , S_FnInitialDbo}
+        ,{superior::DefnGuarGenAcctRate_term            , 
"{DefnGuarGenAcctRate}"}
+        ,{superior::DefnGuarGenAcctRate                 , 
S_DefnGuarGenAcctRate}
+        ,{superior::DefnAV_term                         , "{DefnAV}"}
+        ,{superior::DefnAV                              , S_DefnAV}
+        ,{superior::DefnCSV_term                        , "{DefnCSV}"}
+        ,{superior::DefnCSV                             , S_DefnCSV}
+        ,{superior::DefnMec_term                        , "{DefnMec}"}
+        ,{superior::DefnMec                             , S_DefnMec}
+        ,{superior::DefnOutlay_term                     , "{DefnOutlay}"}
+        ,{superior::DefnOutlay                          , S_DefnOutlay}
+        ,{superior::DefnSpecAmt_term                    , "{DefnSpecAmt}"}
+        ,{superior::DefnSpecAmt                         , S_DefnSpecAmt}
+
+        // Esoterica.
+        ,{superior::Poe0                                , S_Poe0}
+        ,{superior::Poe1                                , S_Poe1}
+        ,{superior::Poe2                                , S_Poe2}
+        ,{superior::Poe3                                , S_Poe3}
+#endif // 1
+        };
+
+    fs::path const path(AddDataDir("sample.lingo"));
+    xml_lmi::xml_document document(xml_root_name());
+    write_proem(document, fs::basename(path));
+    xml::element& root = document.root_node();
+    xml_lmi::set_attr(root, "version", class_version());
+    xml_serialize::to_xml(root, enumerative_map);
+    document.save(path.string());
+}
+
+/// Backward-compatibility serial number of this class's xml version.
+///
+/// version 0: 20201109T1600Z
+
+int lingo::class_version()
+{
+    return 0;
+}
+
+std::string const& lingo::xml_root_name()
+{
+    static std::string const s("lingo");
+    return s;
+}
+
+void lingo::write_proem
+    (xml_lmi::xml_document& document
+    ,std::string const&     file_leaf_name
+    )
+{
+    ::write_proem(document, file_leaf_name);
+}
diff --git a/lingo.hpp b/lingo.hpp
new file mode 100644
index 0000000..6ecd12d
--- /dev/null
+++ b/lingo.hpp
@@ -0,0 +1,62 @@
+// Text to be dropped into report templates.
+//
+// Copyright (C) 2020 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
+//
+// https://savannah.nongnu.org/projects/lmi
+// email: <gchicares@sbcglobal.net>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+#ifndef lingo_hpp
+#define lingo_hpp
+
+#include "config.hpp"
+
+#include "cache_file_reads.hpp"
+#include "so_attributes.hpp"
+#include "xml_lmi_fwd.hpp"
+
+#include <string>
+#include <unordered_map>
+
+/// Company-specific lingo.
+
+class LMI_SO lingo final
+    :public cache_file_reads<lingo>
+{
+  public:
+    explicit lingo(std::string const& filename);
+
+    std::string const& lookup(int) const;
+
+    // Legacy functions to support creating product files programmatically.
+    static void write_lingo_files();
+    static void write_proprietary_lingo_files();
+
+  private:
+    // This class does not derive from xml_serializable, but it
+    // implements these three functions that are akin to virtuals
+    // of class xml_serializable.
+    static int class_version();
+    static std::string const& xml_root_name();
+    static void write_proem
+        (xml_lmi::xml_document& document
+        ,std::string const&     file_leaf_name
+        );
+
+    std::unordered_map<int,std::string> map_;
+};
+
+#endif // lingo_hpp
diff --git a/lmi.hpp b/lmi.hpp
index 5294f23..e7537c7 100644
--- a/lmi.hpp
+++ b/lmi.hpp
@@ -28,6 +28,6 @@
 
 /// Distinguish the antediluvian fork from production.
 
-bool LMI_SO is_antediluvian_fork();
+LMI_SO bool is_antediluvian_fork();
 
 #endif // lmi_hpp
diff --git a/lmi_setup_00.sh b/lmi_setup_00.sh
index 9128585..16d1047 100755
--- a/lmi_setup_00.sh
+++ b/lmi_setup_00.sh
@@ -31,7 +31,7 @@ echo "Started: $stamp0"
 if curl https://git.savannah.nongnu.org:443 >/dev/null 2>&1 ; then
   GIT_URL_BASE=https://git.savannah.nongnu.org/cgit/lmi.git/plain
 else
-  GIT_URL_BASE=https://github.com/vadz/lmi/raw/master
+  GIT_URL_BASE=https://github.com/let-me-illustrate/lmi/raw/master
 fi
 
 # Store dynamic configuration in a temporary file. This method is
diff --git a/lmi_setup_00c.sh b/lmi_setup_00c.sh
index 4965412..7e94b5e 100755
--- a/lmi_setup_00c.sh
+++ b/lmi_setup_00c.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_01.sh b/lmi_setup_01.sh
index ea8d5fc..91a284f 100755
--- a/lmi_setup_01.sh
+++ b/lmi_setup_01.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_01c.sh b/lmi_setup_01c.sh
index 97e976c..b966c2f 100755
--- a/lmi_setup_01c.sh
+++ b/lmi_setup_01c.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_01r.sh b/lmi_setup_01r.sh
index 9c0be2c..92fd705 100755
--- a/lmi_setup_01r.sh
+++ b/lmi_setup_01r.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
@@ -63,7 +64,12 @@ schroot --chroot=${CHRTNAME} --user="${user}"        
--directory=/tmp ./lmi_setu
 } done
 schroot --chroot=${CHRTNAME} --user="${NORMAL_USER}" --directory=/tmp 
./lmi_setup_42.sh
 schroot --chroot=${CHRTNAME} --user="${NORMAL_USER}" --directory=/tmp 
./lmi_setup_43.sh
-schroot --chroot=${CHRTNAME} --user=nemo             --directory=/tmp 
./lmi_setup_44.sh
+# Ideally, this test would be run as a different user, but the 'nemo'
+# account created for that purpose stopped working on a corporate
+# redhat server--see:
+#   https://lists.nongnu.org/archive/html/lmi/2020-10/msg00058.html
+# schroot --chroot=${CHRTNAME} --user=nemo             --directory=/tmp 
./lmi_setup_44.sh
+schroot --chroot=${CHRTNAME} --user="${NORMAL_USER}" --directory=/tmp 
./lmi_setup_44.sh
 
 stamp=$(date -u +'%Y%m%dT%H%M%SZ')
 echo "$stamp $0 [redhat host]"  | tee /dev/tty
diff --git a/lmi_setup_02.sh b/lmi_setup_02.sh
index 4515d5b..97c9c5f 100755
--- a/lmi_setup_02.sh
+++ b/lmi_setup_02.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_02c.sh b/lmi_setup_02c.sh
index 990fb68..57ff6ae 100755
--- a/lmi_setup_02c.sh
+++ b/lmi_setup_02c.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_05c.sh b/lmi_setup_05c.sh
index 46dfc15..12b0267 100755
--- a/lmi_setup_05c.sh
+++ b/lmi_setup_05c.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_05r.sh b/lmi_setup_05r.sh
index 4a1d97d..89df2a1 100755
--- a/lmi_setup_05r.sh
+++ b/lmi_setup_05r.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_07r.sh b/lmi_setup_07r.sh
index 755791e..06ce1e0 100755
--- a/lmi_setup_07r.sh
+++ b/lmi_setup_07r.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_10.sh b/lmi_setup_10.sh
index 2d55276..7a98dc8 100755
--- a/lmi_setup_10.sh
+++ b/lmi_setup_10.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_10c.sh b/lmi_setup_10c.sh
index c733492..2e63fc9 100755
--- a/lmi_setup_10c.sh
+++ b/lmi_setup_10c.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_10r.sh b/lmi_setup_10r.sh
index 8bebd69..de318f0 100755
--- a/lmi_setup_10r.sh
+++ b/lmi_setup_10r.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_11.sh b/lmi_setup_11.sh
index 9031262..98de1bc 100755
--- a/lmi_setup_11.sh
+++ b/lmi_setup_11.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_20.sh b/lmi_setup_20.sh
index 83725c5..90cd37b 100755
--- a/lmi_setup_20.sh
+++ b/lmi_setup_20.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
@@ -92,6 +93,7 @@ apt-get --assume-yes install \
   jing \
   libarchive-tools \
   libc6-dbg \
+  libgtk-3-dev \
   libtool \
   libxml2-utils \
   libxslt1-dev \
diff --git a/lmi_setup_21.sh b/lmi_setup_21.sh
index 5344f24..ada7920 100755
--- a/lmi_setup_21.sh
+++ b/lmi_setup_21.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_24.sh b/lmi_setup_24.sh
index 7e34c35..cf9d709 100755
--- a/lmi_setup_24.sh
+++ b/lmi_setup_24.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_24c.sh b/lmi_setup_24c.sh
index bb2a8f2..9a81cb1 100755
--- a/lmi_setup_24c.sh
+++ b/lmi_setup_24c.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_25.sh b/lmi_setup_25.sh
index fe6cfc1..d0ff3d0 100755
--- a/lmi_setup_25.sh
+++ b/lmi_setup_25.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
@@ -62,6 +63,7 @@ git config --global log.date iso8601-strict-local
 git config --global log.follow true
 git config --global pull.ff only
 git config --global push.default simple
+git config --global push.recurseSubmodules check
 if [ "greg" = "$(whoami)" ]; then
 git config --global user.email gchicares@sbcglobal.net
 git config --global user.name "Gregory W. Chicares"
diff --git a/lmi_setup_29.sh b/lmi_setup_29.sh
index e2d565a..27d9a2c 100755
--- a/lmi_setup_29.sh
+++ b/lmi_setup_29.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_30.sh b/lmi_setup_30.sh
index c156071..58dae1f 100755
--- a/lmi_setup_30.sh
+++ b/lmi_setup_30.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_40.sh b/lmi_setup_40.sh
index 3f0b34e..0b387e4 100755
--- a/lmi_setup_40.sh
+++ b/lmi_setup_40.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_42.sh b/lmi_setup_42.sh
index 09275fc..a4363f3 100755
--- a/lmi_setup_42.sh
+++ b/lmi_setup_42.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/lmi_setup_43.sh b/lmi_setup_43.sh
index dc208aa..de1e421 100755
--- a/lmi_setup_43.sh
+++ b/lmi_setup_43.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
@@ -96,6 +97,7 @@ chmod g=u+s     /opt/lmi/touchstone
 cp -a /opt/lmi/proprietary/test/* /opt/lmi/touchstone/
 
 # Remove object files previously built without proprietary source:
+# shellcheck disable=SC1091
 . /opt/lmi/src/lmi/set_toolchain.sh
 rm /opt/lmi/"${LMI_COMPILER}_${LMI_TRIPLET}"/build/ship/my*
 
@@ -131,7 +133,7 @@ cd free/src || { printf 'failed: cd\n'; exit 3; }
 
 git clone git://git.savannah.nongnu.org/lmi.git \
   || git clone https://git.savannah.nongnu.org/r/lmi.git \
-  || git clone https://github.com/vadz/lmi.git
+  || git clone https://github.com/let-me-illustrate/lmi.git
 
 cd lmi || { printf 'failed: cd\n'; exit 3; }
 find . -path ./.git -prune -o -type f -print0 \
diff --git a/lmi_setup_44.sh b/lmi_setup_44.sh
index ebe7cf4..b1a6f8f 100755
--- a/lmi_setup_44.sh
+++ b/lmi_setup_44.sh
@@ -22,6 +22,7 @@
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
 . ./lmi_setup_inc.sh
+# shellcheck disable=SC1091
 . /tmp/schroot_env
 
 set -evx
diff --git a/main_cgi.cpp b/main_cgi.cpp
index f0719a6..fe3f52a 100644
--- a/main_cgi.cpp
+++ b/main_cgi.cpp
@@ -35,6 +35,7 @@
 
 #include "alert.hpp"
 #include "configurable_settings.hpp"
+#include "global_settings.hpp"
 #include "illustrator.hpp"
 #include "input.hpp"
 #include "lmi.hpp"                      // is_antediluvian_fork()
@@ -89,6 +90,8 @@ int try_main(int argc, char* argv[])
   try {
     initialize_filesystem();
 
+    global_settings::instance().set_data_directory("/opt/lmi/data");
+
     gLogFile.rdbuf()->open
         (configurable_settings::instance().cgi_bin_log_filename().c_str()
         ,ios_out_trunc_binary()
@@ -96,7 +99,16 @@ int try_main(int argc, char* argv[])
 
     if(argc == 2 && argv[1] == std::string("--capture"))
         {
-        std::system("set > settings");
+#       if defined LMI_POSIX
+        int exit_code = std::system("env > settings");
+#       else
+        int exit_code = std::system("set > settings");
+#       endif // defined LMI_POSIX
+        if(EXIT_SUCCESS != exit_code)
+            {
+            std::cerr << "Failed to execute 'set' command;";
+            return EXIT_FAILURE;
+            }
         std::ofstream os("stdin.txt", ios_out_trunc_binary());
         os << std::cin.rdbuf();
         std::cout
diff --git a/main_cli.cpp b/main_cli.cpp
index 1da64c5..5daa6bd 100644
--- a/main_cli.cpp
+++ b/main_cli.cpp
@@ -29,6 +29,7 @@
 #include "getopt.hpp"
 #include "global_settings.hpp"
 #include "gpt_server.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "illustrator.hpp"
 #include "input.hpp"
 #include "ledger.hpp"
@@ -191,13 +192,45 @@ void self_test()
 #endif // !defined _GLIBCXX_DEBUG
 }
 
-/// Run self-test repeatedly (intended for use with 'gprof').
+/// Validate products.
+///
+/// Run an illustration for every product in every state (whether
+/// approved there or not), reporting any conflict in parameters
+/// that would make that impossible. See:
+///   https://lists.nongnu.org/archive/html/lmi/2020-11/msg00020.html
 
-void profile()
+void product_test()
 {
-    for(int j = 0; j < 10; ++j)
+    // Allow unapproved states.
+    global_settings::instance().set_regression_testing(true);
+
+    // Pay zero and don't solve, to make this test go faster.
+    Input input;
+    input["Payment"           ] = "0.0";
+    input["SolveType"         ] = "No solve";
+
+    illustrator z(mce_emit_nothing);
+
+    ce_product_name c;
+    std::vector<std::string> const& p = c.all_strings();
+    std::vector<std::string> const& s = all_strings_state();
+    for(auto const& i : p)
         {
-        self_test();
+        std::cout << "Testing product " << i << std::endl;
+        input["ProductName"        ] = i;
+        for(auto const& j : s)
+            {
+            input["StateOfJurisdiction"] = j;
+            try
+                {
+                z("eraseme", input);
+                }
+            catch(...)
+                {
+                std::cout << i << ", " << j << ":" << std::endl;
+                report_exception();
+                }
+            }
         }
 }
 
@@ -217,7 +250,7 @@ void process_command_line(int argc, char* argv[])
         {"file"         ,REQD_ARG ,nullptr ,'f' ,nullptr ,"input file to run"},
         {"help"         ,NO_ARG   ,nullptr ,'h' ,nullptr ,"display this help 
and exit"},
         {"license"      ,NO_ARG   ,nullptr ,'l' ,nullptr ,"display license and 
exit"},
-        {"profile"      ,NO_ARG   ,nullptr ,'o' ,nullptr ,"set up for 
profiling and exit"},
+        {"product_test" ,NO_ARG   ,nullptr ,'o' ,nullptr ,"validate products 
and exit"},
         {"print_db"     ,NO_ARG   ,nullptr ,'p' ,nullptr ,"print products and 
exit"},
         {"selftest"     ,NO_ARG   ,nullptr ,'s' ,nullptr ,"perform self test 
and exit"},
         {"test_db"      ,NO_ARG   ,nullptr ,'t' ,nullptr ,"test products and 
exit"},
@@ -412,7 +445,7 @@ void process_command_line(int argc, char* argv[])
 
             case 'o':
                 {
-                profile();
+                product_test();
                 return;
                 }
                 break;
diff --git a/main_common.cpp b/main_common.cpp
index 9edbae6..c9323b0 100644
--- a/main_common.cpp
+++ b/main_common.cpp
@@ -24,7 +24,7 @@
 #include "main_common.hpp"
 
 #include "fenv_lmi.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "sigfpe.hpp"
 
 #include <csignal>
diff --git a/main_common_non_wx.cpp b/main_common_non_wx.cpp
index e7d6561..5836595 100644
--- a/main_common_non_wx.cpp
+++ b/main_common_non_wx.cpp
@@ -24,7 +24,7 @@
 #include "main_common.hpp"
 
 #include "fenv_lmi.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 
 #include <iostream>
 #include <ostream>
diff --git a/main_wx.cpp b/main_wx.cpp
index da738c1..0bea18e 100644
--- a/main_wx.cpp
+++ b/main_wx.cpp
@@ -34,7 +34,7 @@
 #include "alert.hpp"                    // safely_show_message()
 #include "fenv_lmi.hpp"
 #include "force_linking.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "main_common.hpp"              // initialize_application()
 #include "path_utility.hpp"             // initialize_filesystem()
 #include "skeleton.hpp"
diff --git a/main_wx_test.cpp b/main_wx_test.cpp
index 1fd33c4..293f22e 100644
--- a/main_wx_test.cpp
+++ b/main_wx_test.cpp
@@ -175,6 +175,9 @@ class application_test final
     // Used to check if distribution tests should be enabled.
     bool is_distribution_test() const { return is_distribution_test_; }
 
+    // Returns the exit code based of tests results.
+    int get_exit_code() const { return exit_code_; }
+
   private:
     application_test() = default;
     application_test(application_test const&) = delete;
@@ -231,6 +234,8 @@ class application_test final
     bool run_all_              {true};
 
     bool is_distribution_test_ {false};
+
+    int  exit_code_            {EXIT_FAILURE};
 };
 
 application_test& application_test::instance()
@@ -509,6 +514,8 @@ TestsResults application_test::run()
             }
         }
 
+    exit_code_ = results.failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+
     return results;
 }
 
@@ -645,6 +652,7 @@ class SkeletonTest final : public Skeleton
 
     // wxApp overrides.
     bool OnInit                 () override;
+    int  OnRun                  () override;
     bool OnExceptionInMainLoop  () override;
     bool StoreCurrentException  () override;
     void RethrowStoredException () override;
@@ -711,6 +719,20 @@ bool SkeletonTest::OnInit()
     return true;
 }
 
+int SkeletonTest::OnRun()
+{
+    int exit_code = Skeleton::OnRun();
+
+    // If the application exited successfully then return the exit code
+    // based on test results.
+    if(exit_code == 0)
+        {
+        exit_code = application_test::instance().get_exit_code();
+        }
+
+    return exit_code;
+}
+
 bool SkeletonTest::StoreCurrentException()
 {
     // We store all the exceptions that are expected to be caught by the tests
diff --git a/math_functions.hpp b/math_functions.hpp
index b186fa6..f219974 100644
--- a/math_functions.hpp
+++ b/math_functions.hpp
@@ -86,7 +86,7 @@ struct mean
     using first_argument_type  = T;
     using second_argument_type = T;
     using result_type          = T;
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& x, T const& y) const
         {return 0.5 * x + 0.5 * y;}
 };
@@ -100,7 +100,7 @@ struct mean
 template<typename T>
 inline T outward_quotient(T numerator, T denominator)
 {
-    static_assert(std::is_integral<T>::value);
+    static_assert(std::is_integral_v<T>);
 
     LMI_ASSERT(0 != denominator);
 
@@ -138,7 +138,7 @@ inline T outward_quotient(T numerator, T denominator)
 template<typename T, int n>
 struct i_upper_n_over_n_from_i
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     static_assert(0 < n);
     T operator()(T const& i) const
         {
@@ -165,7 +165,7 @@ struct i_upper_12_over_12_from_i
 {
     using argument_type = T;
     using result_type   = T;
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i) const
         {
         return i_upper_n_over_n_from_i<T,12>()(i);
@@ -175,7 +175,7 @@ struct i_upper_12_over_12_from_i
 template<typename T, int n>
 struct i_from_i_upper_n_over_n
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     static_assert(0 < n);
     T operator()(T const& i) const
         {
@@ -189,7 +189,7 @@ struct i_from_i_upper_n_over_n
 template<typename T>
 struct i_from_i_upper_12_over_12
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i) const
         {
         return i_from_i_upper_n_over_n<T,12>()(i);
@@ -199,7 +199,7 @@ struct i_from_i_upper_12_over_12
 template<typename T, int n>
 struct d_upper_n_from_i
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     static_assert(0 < n);
     T operator()(T const& i) const
         {
@@ -224,7 +224,7 @@ struct d_upper_n_from_i
 template<typename T>
 struct d_upper_12_from_i
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i) const
         {
         return d_upper_n_from_i<T,12>()(i);
@@ -240,7 +240,7 @@ struct d_upper_12_from_i
 template<typename T, int n>
 struct net_i_from_gross
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     static_assert(0 < n);
     T operator()(T const& i, T const& spread, T const& fee) const
         {
@@ -293,7 +293,7 @@ struct coi_rate_from_q
     using first_argument_type  = T;
     using second_argument_type = T;
     using result_type          = T;
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& q, T const& max_coi) const
         {
         if(!(0.0 <= max_coi && max_coi <= 1.0))
diff --git a/math_functions_test.cpp b/math_functions_test.cpp
index a03868a..a21285c 100644
--- a/math_functions_test.cpp
+++ b/math_functions_test.cpp
@@ -47,7 +47,7 @@ namespace
 template<typename T>
 struct i_upper_12_over_12_from_i_naive
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i) const
         {
         long double z = -1.0L + std::pow((1.0L + i), 1.0L / 12.0L);
@@ -58,7 +58,7 @@ struct i_upper_12_over_12_from_i_naive
 template<typename T>
 struct i_from_i_upper_12_over_12_naive
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i) const
         {
         long double z = -1.0L + std::pow((1.0L + i), 12.0L);
@@ -69,7 +69,7 @@ struct i_from_i_upper_12_over_12_naive
 template<typename T>
 struct d_upper_12_from_i_naive
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i) const
         {
         long double z = 12.0L * (1.0L - std::pow(1.0L + i, -1.0L / 12.0L));
@@ -80,7 +80,7 @@ struct d_upper_12_from_i_naive
 template<typename T, int n>
 struct net_i_from_gross_naive
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i, T const& spread, T const& fee) const
         {
         static long double const reciprocal_n = 1.0L / n;
@@ -99,7 +99,7 @@ struct net_i_from_gross_naive
 template<typename T>
 struct coi_rate_from_q_naive
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& q, T const& max_coi) const
         {
         if(0.0 == q)
@@ -124,7 +124,7 @@ struct coi_rate_from_q_naive
 template<typename T, int n>
 struct i_upper_n_over_n_from_i_naive
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i) const
         {
         return T(-1) + std::pow((T(1) + i), T(1) / n);
@@ -137,7 +137,7 @@ struct i_upper_n_over_n_from_i_naive
 template<typename T, int n>
 struct i_upper_n_over_n_from_i_T
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
     T operator()(T const& i) const
         {
         static T const reciprocal_n = T(1) / n;
@@ -162,28 +162,30 @@ void sample_results()
     std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
     std::cout.precision(25);
     std::cout
-        << "\n  daily rate corresponding to 1% annual interest"
-        << ", by various methods\n"
-        << "    method in production\n      "
-        << i_upper_n_over_n_from_i      <long double,365>()(0.01) << '\n'
+        << "\nDaily rate corresponding to 1% annual interest"
+        << ", by various methods:\n"
+        << "        000000000111111111122\n"
+        << "        123456789012345678901\n"
+        << "  " << i_upper_n_over_n_from_i      <long double,365>()(0.01)
+        << "  method in production\n"
         ;
 #if defined LMI_X87
     fenv_precision(fe_ldblprec);
     std::cout
-        << "    long double precision, std::expm1 and std::log1p\n      "
-        << i_upper_n_over_n_from_i_T    <long double,365>()(0.01) << '\n'
-        << "    long double precision, std::pow\n      "
-        << i_upper_n_over_n_from_i_naive<long double,365>()(0.01) << '\n'
+        << "  " << i_upper_n_over_n_from_i_T    <long double,365>()(0.01)
+        << "  long double precision, std::expm1 and std::log1p\n"
+        << "  " << i_upper_n_over_n_from_i_naive<long double,365>()(0.01)
+        << "  long double precision, std::pow\n"
         ;
 
     fenv_initialize();
     fenv_precision(fe_dblprec);
 #endif // defined LMI_X87
     std::cout
-        << "    double precision, std::expm1 and std::log1p\n      "
-        << i_upper_n_over_n_from_i_T    <double,365>()(0.01) << '\n'
-        << "    double precision, std::pow\n      "
-        << i_upper_n_over_n_from_i_naive<double,365>()(0.01) << '\n'
+        << "  " << i_upper_n_over_n_from_i_T    <double,365>()(0.01)
+        << "  double precision, std::expm1 and std::log1p\n"
+        << "  " << i_upper_n_over_n_from_i_naive<double,365>()(0.01)
+        << "  double precision, std::pow\n"
         ;
 
     fenv_initialize();
@@ -198,10 +200,13 @@ void mete0()
 {
     double volatile x;
     stifle_warning_for_unused_value(x);
-    x = i_upper_12_over_12_from_i_naive<double>()(0.04);
-    x = i_from_i_upper_12_over_12_naive<double>()(0.04);
-    x = d_upper_12_from_i_naive        <double>()(0.04);
-    x = net_i_from_gross_naive<double,365>()(0.04, 0.007, 0.003);
+    for(int j = 0; j < 100000; ++j)
+        {
+        x = i_upper_12_over_12_from_i_naive<double>()(0.04);
+        x = i_from_i_upper_12_over_12_naive<double>()(0.04);
+        x = d_upper_12_from_i_naive        <double>()(0.04);
+        x = net_i_from_gross_naive<double,365>()(0.04, 0.007, 0.003);
+        }
 }
 
 // This implementation uses production functors.
@@ -209,16 +214,42 @@ void mete1()
 {
     double volatile x;
     stifle_warning_for_unused_value(x);
-    x = i_upper_12_over_12_from_i<double>()(0.04);
-    x = i_from_i_upper_12_over_12<double>()(0.04);
-    x = d_upper_12_from_i        <double>()(0.04);
-    x = net_i_from_gross<double,365>()(0.04, 0.007, 0.003);
+    for(int j = 0; j < 100000; ++j)
+        {
+        x = i_upper_12_over_12_from_i<double>()(0.04);
+        x = i_from_i_upper_12_over_12<double>()(0.04);
+        x = d_upper_12_from_i        <double>()(0.04);
+        x = net_i_from_gross<double,365>()(0.04, 0.007, 0.003);
+        }
+}
+
+void mete2()
+{
+    double volatile x;
+    stifle_warning_for_unused_value(x);
+    for(int j = 0; j < 100000; ++j)
+        {
+        x = i_upper_n_over_n_from_i_T<double,365>()(0.01);
+        }
+}
+
+void mete3()
+{
+    long double volatile x;
+    stifle_warning_for_unused_value(x);
+    for(int j = 0; j < 100000; ++j)
+        {
+        x = i_upper_n_over_n_from_i_T<long double,365>()(0.01);
+        }
 }
 
 void assay_speed()
 {
-    std::cout << "  Speed test: std::pow  \n    " << TimeAnAliquot(mete0) << 
'\n';
-    std::cout << "  Speed test: std::expm1\n    " << TimeAnAliquot(mete1) << 
'\n';
+    std::cout << "Speed tests:\n";
+    std::cout << "  std::pow         " << TimeAnAliquot(mete0) << '\n';
+    std::cout << "  std::expm1       " << TimeAnAliquot(mete1) << '\n';
+    std::cout << "  double      i365 " << TimeAnAliquot(mete2) << '\n';
+    std::cout << "  long double i365 " << TimeAnAliquot(mete3) << '\n';
 }
 
 int test_main(int, char*[])
diff --git a/mc_enum.hpp b/mc_enum.hpp
index d0807e9..e34c2c3 100644
--- a/mc_enum.hpp
+++ b/mc_enum.hpp
@@ -92,7 +92,7 @@ template<typename T>
 class mc_enum final
     :public mc_enum_base
 {
-    static_assert(std::is_enum<T>::value);
+    static_assert(std::is_enum_v<T>);
 
     friend class mc_enum_test;
     template<typename U> friend std::vector<std::string> const& all_strings();
diff --git a/mc_enum_types_aux.hpp b/mc_enum_types_aux.hpp
index 996fca7..e029122 100644
--- a/mc_enum_types_aux.hpp
+++ b/mc_enum_types_aux.hpp
@@ -40,20 +40,20 @@ enum
     ,mc_n_rate_periods = 2
     };
 
-std::vector<std::string> const& LMI_SO all_strings_gender   ();
-std::vector<std::string> const& LMI_SO all_strings_class    ();
-std::vector<std::string> const& LMI_SO all_strings_smoking  ();
-std::vector<std::string> const& LMI_SO all_strings_uw_basis ();
-std::vector<std::string> const& LMI_SO all_strings_state    ();
+LMI_SO std::vector<std::string> const& all_strings_gender   ();
+LMI_SO std::vector<std::string> const& all_strings_class    ();
+LMI_SO std::vector<std::string> const& all_strings_smoking  ();
+LMI_SO std::vector<std::string> const& all_strings_uw_basis ();
+LMI_SO std::vector<std::string> const& all_strings_state    ();
 
-std::vector<std::string> LMI_SO allowed_strings_emission();
+LMI_SO std::vector<std::string> allowed_strings_emission();
 
 mcenum_dbopt_7702 effective_dbopt_7702
     (mcenum_dbopt      actual_dbopt
     ,mcenum_dbopt_7702 rop_equivalent
     );
 
-bool LMI_SO is_subject_to_ill_reg(mcenum_ledger_type);
+LMI_SO bool is_subject_to_ill_reg(mcenum_ledger_type);
 
 bool is_three_rate_finra(mcenum_ledger_type);
 
@@ -67,7 +67,7 @@ bool is_three_rate_finra(mcenum_ledger_type);
 template<typename T>
 std::string mc_str(T);
 
-mcenum_emission LMI_SO mc_emission_from_string(std::string const&);
+LMI_SO mcenum_emission mc_emission_from_string(std::string const&);
 
 mcenum_state mc_state_from_string(std::string const&);
 
diff --git a/mec_view.cpp b/mec_view.cpp
index 9bef994..698609a 100644
--- a/mec_view.cpp
+++ b/mec_view.cpp
@@ -24,7 +24,7 @@
 #include "mec_view.hpp"
 
 #include "edit_mvc_docview_parameters.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "mec_document.hpp"
 #include "mec_input.hpp"
 #include "mec_server.hpp"
diff --git a/miscellany.hpp b/miscellany.hpp
index 0ce0085..6df0d3b 100644
--- a/miscellany.hpp
+++ b/miscellany.hpp
@@ -127,21 +127,21 @@ template<typename T> bool operator<=(T t, minmax<T> m) 
{return t <= m.minimum();
 template<typename T> bool operator< (minmax<T> m, T t) {return m.maximum() <  
t;}
 template<typename T> bool operator<=(minmax<T> m, T t) {return m.maximum() <= 
t;}
 
-int LMI_SO scale_power(int max_power, double min_value, double max_value);
+LMI_SO int scale_power(int max_power, double min_value, double max_value);
 
-int LMI_SO count_newlines(std::string const&);
+LMI_SO int count_newlines(std::string const&);
 
-std::vector<std::string> LMI_SO split_into_lines(std::string const&);
+LMI_SO std::vector<std::string> split_into_lines(std::string const&);
 
 std::string htmlize(std::string const&);
 
-bool LMI_SO begins_with(std::string const& s, std::string const& prefix);
+LMI_SO bool begins_with(std::string const& s, std::string const& prefix);
 
-bool LMI_SO ends_with(std::string const& s, std::string const& suffix);
+LMI_SO bool ends_with(std::string const& s, std::string const& suffix);
 
-void LMI_SO ltrim(std::string& s, char const* superfluous);
+LMI_SO void ltrim(std::string& s, char const* superfluous);
 
-void LMI_SO rtrim(std::string& s, char const* superfluous);
+LMI_SO void rtrim(std::string& s, char const* superfluous);
 
 inline std::ios_base::openmode ios_in_binary()
 {
diff --git a/msw_common.make b/msw_common.make
index c7f353c..bfaa9dd 100644
--- a/msw_common.make
+++ b/msw_common.make
@@ -36,16 +36,12 @@ SHREXT := .dll
 # and rarely needs to be updated.
 
 platform_defines := \
-  -DLIBXML_USE_DLL \
+  -DXMLWRAPP_USE_DLL \
+  -DXSLTWRAPP_USE_DLL \
   -DSTRICT \
 
 platform_gui_ldflags := -mwindows
 
-platform_gnome_xml_libraries := \
-  -lexslt \
-  -lxslt \
-  -lxml2 \
-
 # In addition to other reasons for treating these libraries as mere
 # collections of source files, there's a specific problem with boost.
 # The build system provided by boost produces library names such as
@@ -58,8 +54,6 @@ platform_boost_libraries :=
 
 platform_cgicc_libraries :=
 
-platform_xmlwrapp_libraries :=
-
 
################################################################################
 
 # HTML server's cgi-bin directory. Not used yet. Eventually, an
diff --git a/msw_workarounds.cpp b/msw_workarounds.cpp
index 0538122..a376c24 100644
--- a/msw_workarounds.cpp
+++ b/msw_workarounds.cpp
@@ -28,7 +28,7 @@
 #include "alert.hpp"
 #include "configurable_settings.hpp"
 #include "fenv_lmi.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 
 #include <windows.h>
 
diff --git a/multidimgrid_safe.hpp b/multidimgrid_safe.hpp
index b34723c..42d709c 100644
--- a/multidimgrid_safe.hpp
+++ b/multidimgrid_safe.hpp
@@ -258,7 +258,7 @@ template<typename AdjustControl, typename BaseAxisType = 
MultiDimAxisAny>
 class MultiDimAdjustableAxis
     :public BaseAxisType
 {
-    static_assert(std::is_base_of<MultiDimAxisAny,BaseAxisType>::value);
+    static_assert(std::is_base_of_v<MultiDimAxisAny,BaseAxisType>);
 
   protected:
     typedef AdjustControl AxisAdjustControl;
diff --git a/multidimgrid_tools.hpp b/multidimgrid_tools.hpp
index 85bc8c7..37c0591 100644
--- a/multidimgrid_tools.hpp
+++ b/multidimgrid_tools.hpp
@@ -88,7 +88,7 @@ template<typename Integral>
 class AxisMaxBoundAdjuster
     :public AxisMaxBoundAdjusterBase
 {
-    static_assert(std::is_integral<Integral>::value);
+    static_assert(std::is_integral_v<Integral>);
 
   public:
     AxisMaxBoundAdjuster
diff --git a/mvc_controller.tpp b/mvc_controller.tpp
index c368082..e02278e 100644
--- a/mvc_controller.tpp
+++ b/mvc_controller.tpp
@@ -69,8 +69,8 @@ T const& MvcController::ModelReference(std::string const& 
name) const
 template<typename T>
 T& MvcController::WindowFromXrcName(char const* name) const
 {
-    static_assert(!std::is_pointer<T>::value);
-    static_assert(std::is_base_of<wxWindow,T>::value);
+    static_assert(!std::is_pointer_v<T>);
+    static_assert(std::is_base_of_v<wxWindow,T>);
 
     wxWindow* w = FindWindow(wxXmlResource::GetXRCID(name));
     if(!w)
diff --git a/my_lingo.cpp b/my_lingo.cpp
new file mode 100644
index 0000000..c5068dc
--- /dev/null
+++ b/my_lingo.cpp
@@ -0,0 +1,43 @@
+// Text to be dropped into report templates.
+//
+// Copyright (C) 2020 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
+//
+// https://savannah.nongnu.org/projects/lmi
+// email: <gchicares@sbcglobal.net>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// This file is a template for embedding product-specific data. Doing
+// that creates a derived work covered by the GPL. But you may prefer
+// not to publish your data, for instance because it is proprietary.
+// In that case, the GPL does not permit you to distribute the derived
+// work at all. But read the second paragraph of section 0 of the GPL
+// carefully: it permits you to run your modified version of the
+// program--and to distribute its output, which is not a derived work
+// because it's merely your data, trivially cast in a format suitable
+// for use with lmi. You can therefore distribute the files created by
+// your modified version of this program, but not that program itself.
+// Those files are all you need: distributing the program itself isn't
+// necessary anyway.
+
+#include "pchfile.hpp"
+
+#include "lingo.hpp"
+
+void lingo::write_proprietary_lingo_files()
+{
+// Not necessary for 'sample*' products, because they're built in.
+// For other products, clone the write_lingo_files() implementation.
+}
diff --git a/my_prod.cpp b/my_prod.cpp
index fc54750..a0f6d9e 100644
--- a/my_prod.cpp
+++ b/my_prod.cpp
@@ -58,6 +58,7 @@ void product_data::write_proprietary_policy_files()
 
     z.DatabaseFilename           = glossed_string("sample.database");
     z.FundFilename               = glossed_string("sample.funds");
+    z.LingoFilename              = glossed_string("sample.lingo");
     z.RoundingFilename           = glossed_string("sample.rounding");
     z.TierFilename               = glossed_string("sample.strata");
 
@@ -80,8 +81,8 @@ void product_data::write_proprietary_policy_files()
     z.SubstdTblMultFilename      = glossed_string("sample");
     z.CurrSpecAmtLoadFilename    = glossed_string("sample");
     z.GuarSpecAmtLoadFilename    = glossed_string("sample");
-    z.PolicyForm                 = glossed_string("UL32768-NY");
-    z.PolicyFormAlternative      = glossed_string("UL32768-X");
+    z.PolicyForm                 = glossed_string("UL32768-NY"); // LINGO !! 
expunge
+    z.PolicyFormAlternative      = glossed_string("UL32768-X"); // LINGO !! 
expunge
     z.PolicyMktgName             = glossed_string("UL Supreme");
     z.PolicyLegalName            = glossed_string("Flexible Premium Adjustable 
Life Insurance Policy");
     z.InsCoShortName             = glossed_string("Superior Life");
diff --git a/null_stream.hpp b/null_stream.hpp
index 5b34bc2..742b34f 100644
--- a/null_stream.hpp
+++ b/null_stream.hpp
@@ -28,7 +28,7 @@
 
 #include <iosfwd>
 
-std::streambuf& LMI_SO null_streambuf();
-std::ostream&   LMI_SO null_stream();
+LMI_SO std::streambuf& null_streambuf();
+LMI_SO std::ostream&   null_stream();
 
 #endif // null_stream_hpp
diff --git a/numeric_io_cast.hpp b/numeric_io_cast.hpp
index beebed8..5418960 100644
--- a/numeric_io_cast.hpp
+++ b/numeric_io_cast.hpp
@@ -117,8 +117,8 @@ To numeric_io_cast(From from, To = To())
 template<typename To, typename From>
 struct numeric_converter
 {
-    static_assert(std::is_void<To  >::value);
-    static_assert(std::is_void<From>::value);
+    static_assert(std::is_void_v<To  >);
+    static_assert(std::is_void_v<From>);
 
     To operator()(From const&) const
         {
@@ -132,7 +132,7 @@ struct numeric_converter
 template<typename To>
 struct numeric_converter<To, std::string>
 {
-    static_assert(std::is_arithmetic<To>::value);
+    static_assert(std::is_arithmetic_v<To>);
 
     typedef std::string From;
     To operator()(From const& from) const
@@ -201,7 +201,7 @@ struct numeric_converter<To, char const*>
 template<typename From>
 struct numeric_converter<std::string, From>
 {
-    static_assert(std::is_arithmetic<From>::value);
+    static_assert(std::is_arithmetic_v<From>);
 
     typedef std::string To;
     To operator()(From const& from) const
diff --git a/numeric_io_test.cpp b/numeric_io_test.cpp
index a7308dc..48b7012 100644
--- a/numeric_io_test.cpp
+++ b/numeric_io_test.cpp
@@ -23,7 +23,7 @@
 
 #include "numeric_io_cast.hpp"
 
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "ieee754.hpp"                  // infinity<>()
 #include "miscellany.hpp"
 #include "test_tools.hpp"
diff --git a/numeric_io_traits.hpp b/numeric_io_traits.hpp
index 321cfc2..bb8e98e 100644
--- a/numeric_io_traits.hpp
+++ b/numeric_io_traits.hpp
@@ -59,7 +59,7 @@
 template<typename T>
 inline int floating_point_decimals(T t)
 {
-    static_assert(std::is_floating_point<T>::value);
+    static_assert(std::is_floating_point_v<T>);
 #if defined LMI_MSVCRT
     // COMPILER !! This C runtime not only writes infinity as "1.#INF"
     // instead of "inf" but also "respects" the precision specifier
diff --git a/nychthemeral_test.sh b/nychthemeral_test.sh
index e6fa41e..43c672f 100755
--- a/nychthemeral_test.sh
+++ b/nychthemeral_test.sh
@@ -40,11 +40,6 @@ setopt PIPE_FAIL
 
 srcdir=$(dirname "$(readlink --canonicalize "$0")")
 
-# Cannot recursively check script on path determined at runtime, so
-# a directive like 'source="$srcdir"' doesn't work.
-# shellcheck disable=SC1090
-. "$srcdir"/set_toolchain.sh
-
 coefficiency=${coefficiency:-"--jobs=$(nproc)"}
 
 build_clutter='
@@ -60,6 +55,10 @@ build_clutter='
 /^[^ ]*windres -o /d
 '
 
+uninstall_clutter='
+/^find \/opt\/lmi\/bin -type f -delete$/d
+'
+
 concinnity_clutter='
 /.*\/test_coding_rules_test\.sh$/d
 /^Testing .test_coding_rules.\.$/d
@@ -129,6 +128,7 @@ nychthemeral_clutter='
 /^  *[1-9][0-9]* source files/d
 /^  *[1-9][0-9]* source lines/d
 /^  *[1-9][0-9]* marked defects/d
+/^# speed test/d
 /^# xrc tests/d
 /^# test all valid emission types/d
 /^# schema tests/d
@@ -136,12 +136,31 @@ nychthemeral_clutter='
 /^$/d
 '
 
+lmi_build_type=$(/usr/share/misc/config.guess)
+
+case "$lmi_build_type" in
+    (*-*-cygwin*)
+        platform=Cygwin
+        ;;
+esac
+
 # This for-loop can iterate over as many toolchains as desired.
 # Make sure the current production architecture is built last, so that
 # it's the one installed to /opt/lmi/bin/ when this script ends.
+triplets="x86_64-w64-mingw32 i686-w64-mingw32"
+if [ "Cygwin" != "$platform" ] && [ "WSL" != "$platform" ]
+then
+# 'triplets' really is used, but in a zsh-specific way
+# shellcheck disable=SC2034
+  triplets="x86_64-pc-linux-gnu x86_64-w64-mingw32 i686-w64-mingw32"
+fi
 export LMI_COMPILER=gcc
 export LMI_TRIPLET
-for LMI_TRIPLET in x86_64-w64-mingw32 i686-w64-mingw32 ;
+# shellcheck disable=SC2043
+#for LMI_TRIPLET in i686-w64-mingw32 ;
+# "${=...} expansion--see zsh faq 3.1:
+#  "Why does $var where var="foo bar" not do what I expect?"
+for LMI_TRIPLET in ${=triplets} ;
 do
 # Directory for test logs.
 #
@@ -154,8 +173,16 @@ mkdir --parents "$log_dir"
 {
 printf 'LMI_TRIPLET = "%s"\n' "$LMI_TRIPLET" > /dev/tty
 
+# Cannot recursively check script on path determined at runtime, so
+# a directive like 'source="$srcdir"' doesn't work.
+# shellcheck disable=SC1090
+. "$srcdir"/set_toolchain.sh
+
 cd /opt/lmi/src/lmi
 
+make "$coefficiency" uninstall 2>&1 \
+  | tee "$log_dir"/uninstall | sed -e "$build_clutter" -e "$uninstall_clutter"
+
 printf '\n# test concinnity\n\n'
 make "$coefficiency" check_concinnity 2>&1 \
   | tee "$log_dir"/concinnity | sed -e "$build_clutter" -e 
"$concinnity_clutter"
@@ -201,6 +228,12 @@ printf '\n# unit tests in libstdc++ debug mode\n\n'
 make "$coefficiency" --output-sync=recurse unit_tests build_type=safestdlib 
2>&1 \
   | tee >(grep '\*\*\*') >(grep \?\?\?\?) >(grep '!!!!' --count | xargs printf 
'%d tests succeeded\n') >"$log_dir"/unit_tests_safestdlib
 
+if [ "greg" = "$(whoami)" ]
+then
+  printf '\n# speed test\n\n'
+  make cli_timing
+fi
+
 printf '\n# xrc tests\n\n'
 java -jar /opt/lmi/third_party/rng/jing.jar -c xrc.rnc ./*.xrc 2>&1 \
   | tee "$log_dir"/xrc
diff --git a/objects.make b/objects.make
index f8f0839..e8f21e9 100644
--- a/objects.make
+++ b/objects.make
@@ -65,7 +65,7 @@ boost_regex_objects := \
 # run correctly.
 
 ifneq (,$(USE_SO_ATTRIBUTES))
-  duplicated_objects = $(boost_filesystem_objects) $(xmlwrapp_objects)
+  duplicated_objects = $(boost_filesystem_objects)
 endif
 
 # GNU cgicc.
@@ -109,11 +109,7 @@ cgicc_3_1_4_objects = \
   HTTPHeaders.o \
   MStreamable.o \
 
-# xmlwrapp and xsltwrapp.
-
-xmlwrapp_objects := xml_xslt_wrapp.o
-
-# For systems that already have boost, cgicc, and xmlwrapp libraries
+# For systems that already have boost and cgicc libraries
 # installed, define 'HAVE_THIRD_PARTY_LIBRARIES' to use them instead
 # of using the workarounds above.
 #
@@ -125,7 +121,6 @@ ifdef HAVE_THIRD_PARTY_LIBRARIES
   boost_filesystem_objects :=
   boost_regex_objects :=
   cgicc_objects :=
-  xmlwrapp_objects :=
 endif
 
 
################################################################################
@@ -176,7 +171,6 @@ cli_objects := \
 
 common_common_objects := \
   $(boost_filesystem_objects) \
-  $(xmlwrapp_objects) \
   actuarial_table.o \
   alert.o \
   calendar_date.o \
@@ -298,6 +292,7 @@ lmi_common_objects := \
   ihs_mortal.o \
   ihs_server7702.o \
   irc7702_tables.o \
+  lingo.o \
   lmi.o \
   md5.o \
   md5sum.o \
@@ -505,7 +500,6 @@ account_value_test$(EXEEXT): \
 actuarial_table_test$(EXEEXT): \
   $(boost_filesystem_objects) \
   $(common_test_objects) \
-  $(xmlwrapp_objects) \
   actuarial_table.o \
   actuarial_table_test.o \
   cso_table.o \
@@ -585,7 +579,6 @@ commutation_functions_test$(EXEEXT): \
 configurable_settings_test$(EXEEXT): \
   $(boost_filesystem_objects) \
   $(common_test_objects) \
-  $(xmlwrapp_objects) \
   calendar_date.o \
   configurable_settings.o \
   configurable_settings_test.o \
@@ -701,7 +694,6 @@ input_sequence_test$(EXEEXT): \
 input_test$(EXEEXT): \
   $(boost_filesystem_objects) \
   $(common_test_objects) \
-  $(xmlwrapp_objects) \
   calendar_date.o \
   ce_product_name.o \
   configurable_settings.o \
@@ -751,7 +743,6 @@ interpolate_string_test$(EXEEXT): \
 irc7702a_test$(EXEEXT): \
   $(boost_filesystem_objects) \
   $(common_test_objects) \
-  $(xmlwrapp_objects) \
   calendar_date.o \
   global_settings.o \
   ihs_irc7702a.o \
@@ -771,7 +762,6 @@ istream_to_string_test$(EXEEXT): \
 ledger_test$(EXEEXT): \
   $(boost_filesystem_objects) \
   $(common_test_objects) \
-  $(xmlwrapp_objects) \
   calendar_date.o \
   configurable_settings.o \
   crc32.o \
@@ -890,7 +880,6 @@ path_utility_test$(EXEEXT): \
 premium_tax_test$(EXEEXT): \
   $(boost_filesystem_objects) \
   $(common_test_objects) \
-  $(xmlwrapp_objects) \
   calendar_date.o \
   data_directory.o \
   database.o \
@@ -928,7 +917,6 @@ print_matrix_test$(EXEEXT): \
 product_file_test$(EXEEXT): \
   $(boost_filesystem_objects) \
   $(common_test_objects) \
-  $(xmlwrapp_objects) \
   calendar_date.o \
   data_directory.o \
   database.o \
@@ -939,6 +927,7 @@ product_file_test$(EXEEXT): \
   facets.o \
   fund_data.o \
   global_settings.o \
+  lingo.o \
   lmi.o \
   mc_enum.o \
   mc_enum_types.o \
@@ -1076,7 +1065,6 @@ wx_new_test$(EXEEXT): \
 xml_serialize_test$(EXEEXT): \
   $(boost_filesystem_objects) \
   $(common_test_objects) \
-  $(xmlwrapp_objects) \
   calendar_date.o \
   global_settings.o \
   miscellany.o \
@@ -1209,6 +1197,7 @@ product_files$(EXEEXT): \
   main_common_non_wx.o \
   my_db.o \
   my_fund.o \
+  my_lingo.o \
   my_prod.o \
   my_proem.o \
   my_rnd.o \
diff --git a/path_utility.cpp b/path_utility.cpp
index a24972a..b815f6b 100644
--- a/path_utility.cpp
+++ b/path_utility.cpp
@@ -130,7 +130,7 @@ void initialize_filesystem()
 /// Notably, path("/bin/sh/") succeeds, silently discarding the
 /// trailing '/'.
 
-fs::path LMI_SO modify_directory
+fs::path modify_directory
     (fs::path const& original_filepath
     ,fs::path const& supplied_directory
     )
@@ -193,6 +193,31 @@ std::string orthodox_filename(std::string const& 
original_filename)
     return s;
 }
 
+/// Remove an msw root /^.*:/ from path iff system is not msw.
+///
+/// Motivation: Prevent the ghastly outcome demonstrated in the unit
+/// test when an msw-native path is used on a posix system.
+///
+/// On an msw system, return the path unaltered: it may contain a
+/// 'root-name', but that 'root-name' is native, not alien.
+
+fs::path remove_alien_msw_root(fs::path const& original_filepath)
+{
+#if defined LMI_POSIX
+    std::string s {original_filepath.string()};
+    std::string::size_type p = s.find_last_of(':');
+    if(std::string::npos != p)
+        {
+        s.erase(0, 1 + p);
+        }
+    return s;
+#elif defined LMI_MSW
+    return original_filepath;
+#else  // Unknown platform.
+    throw "Unrecognized platform."
+#endif // Unknown platform.
+}
+
 namespace
 {
 /// Prepend a serial number to a file extension. This is intended to
diff --git a/path_utility.hpp b/path_utility.hpp
index 70ba68b..47ac584 100644
--- a/path_utility.hpp
+++ b/path_utility.hpp
@@ -31,35 +31,39 @@
 #include <ostream>
 #include <string>
 
-void LMI_SO initialize_filesystem(); // Listed first because of its importance.
+LMI_SO void initialize_filesystem(); // Listed first because of its importance.
 
-fs::path LMI_SO modify_directory
+LMI_SO fs::path modify_directory
     (fs::path const& original_filepath
     ,fs::path const& supplied_directory
     );
 
-std::string LMI_SO orthodox_filename
+LMI_SO std::string orthodox_filename
     (std::string const& original_filename
     );
 
-fs::path LMI_SO serial_file_path
+LMI_SO fs::path remove_alien_msw_root
+    (fs::path    const& original_filepath
+    );
+
+LMI_SO fs::path serial_file_path
     (fs::path    const& exemplar
     ,std::string const& personal_name
     ,int                serial_number
     ,std::string const& extension
     );
 
-fs::path LMI_SO unique_filepath
+LMI_SO fs::path unique_filepath
     (fs::path    const& original_filepath
     ,std::string const& supplied_extension
     );
 
-void LMI_SO validate_directory
+LMI_SO void validate_directory
     (std::string const& directory
     ,std::string const& context
     );
 
-void LMI_SO validate_filepath
+LMI_SO void validate_filepath
     (std::string const& filepath
     ,std::string const& context
     );
diff --git a/path_utility_test.cpp b/path_utility_test.cpp
index 02ed71e..85a264f 100644
--- a/path_utility_test.cpp
+++ b/path_utility_test.cpp
@@ -294,11 +294,19 @@ void test_unique_filepath_with_ludicrous_filenames()
     fs::path path2 = unique_filepath(fs::path(""), "");
     BOOST_TEST_EQUAL(path2.string(), "");
 
+#if defined LMI_MSW
+    // fs::change_extension()'s argument is ".[extension]", so ".."
+    // represents a '.' extension-delimiter followed by an extension
+    // consisting of a single '.'. When fs::change_extension() is
+    // called by unique_filepath() here, adding that extension to ".."
+    // yields "...", which is forbidden by msw, but allowed (although
+    // of course discouraged) by posix.
     BOOST_TEST_THROW
         (unique_filepath(fs::path(".."), "..")
         ,fs::filesystem_error
         ,""
         );
+#endif // defined LMI_MSW
 }
 
 void test_path_inserter()
@@ -344,11 +352,27 @@ void test_path_validation()
     validate_filepath("./path_utility_test_file", context);
 
     // Not well formed.
+#if 0
+    // Neither posix nor msw allows NUL in paths. However, the boost
+    // filesystem library doesn't throw an explicit exception here;
+    // instead, it aborts with:
+    //   "Assertion `src.size() == std::strlen( src.c_str() )' failed."
+    // Perhaps std::filesystem will trap this and throw an exception.
+    std::string nulls = {'\0', '\0'};
+    BOOST_TEST_THROW
+        (validate_filepath(nulls, context)
+        ,std::runtime_error
+        ,lmi_test::what_regex("invalid name \"<|>\" in path")
+        );
+#endif // 0
+
+#if defined LMI_MSW
     BOOST_TEST_THROW
         (validate_filepath("<|>", context)
         ,std::runtime_error
         ,lmi_test::what_regex("invalid name \"<|>\" in path")
         );
+#endif // defined LMI_MSW
 
     // Not empty.
     BOOST_TEST_THROW
@@ -383,6 +407,40 @@ void test_path_validation()
     fs::remove("path_utility_test_dir");
 }
 
+/// Demonstrate a boost::filesystem oddity.
+///
+/// A print directory is specified in 'configurable_settings.xml', and
+/// managed by 'preferences_model.cpp'. Using an msw build of lmi to
+/// change its value endues it with a 'root-name'. Subsequently using
+/// a posix build of lmi does not remove the 'root-name'; instead, it
+/// does something bizarre, viz.:
+///   fs::system_complete(/opt/lmi/data) returns:
+///   /opt/lmi/data
+/// as expected, but
+///   fs::system_complete(Z:/opt/lmi/data) bizarrely returns:
+///   /opt/lmi/gcc_x86_64-pc-linux-gnu/build/ship/Z:/opt/lmi/data
+/// or something like that, depending on the build directory.
+
+void test_oddities()
+{
+    std::string const z0 = "/opt/lmi/data";
+    std::string const z1 = "Z:/opt/lmi/data";
+    std::string const z2 = remove_alien_msw_root(z1).string();
+#if defined LMI_POSIX
+    BOOST_TEST_EQUAL  (z0, fs::system_complete(z0).string());
+    BOOST_TEST_UNEQUAL(z0, fs::system_complete(z1).string());
+    BOOST_TEST_EQUAL  (z0, z2);
+    BOOST_TEST_EQUAL  (z0, fs::system_complete(z2).string());
+#elif defined LMI_MSW
+    BOOST_TEST_EQUAL  (z1, fs::system_complete(z0).string());
+    BOOST_TEST_EQUAL  (z1, fs::system_complete(z1).string());
+    BOOST_TEST_EQUAL  (z1, z2);
+    BOOST_TEST_EQUAL  (z1, fs::system_complete(z2).string());
+#else  // Unknown platform.
+    throw "Unrecognized platform."
+#endif // Unknown platform.
+}
+
 int test_main(int, char*[])
 {
     initialize_filesystem();
@@ -394,6 +452,7 @@ int test_main(int, char*[])
     test_unique_filepath_with_ludicrous_filenames();
     test_path_inserter();
     test_path_validation();
+    test_oddities();
 
     return EXIT_SUCCESS;
 }
diff --git a/pdf_command.hpp b/pdf_command.hpp
index 6535c51..7b6bca5 100644
--- a/pdf_command.hpp
+++ b/pdf_command.hpp
@@ -32,8 +32,8 @@ class Ledger;
 
 typedef void (*pdf_command_fp_type)(Ledger const&, fs::path const&);
 
-bool LMI_SO pdf_command_initialize(pdf_command_fp_type);
+LMI_SO bool pdf_command_initialize(pdf_command_fp_type);
 
-void LMI_SO pdf_command(Ledger const&, fs::path const&);
+LMI_SO void pdf_command(Ledger const&, fs::path const&);
 
 #endif // pdf_command_hpp
diff --git a/policy_document.cpp b/policy_document.cpp
index f4a81c2..7ca5534 100644
--- a/policy_document.cpp
+++ b/policy_document.cpp
@@ -39,9 +39,18 @@ PolicyDocument::PolicyDocument()
     ,values_               {}
 {
     values_["DatabaseFilename"        ] = &product_data_.DatabaseFilename      
  .datum_;
+    values_["LingoFilename"           ] = &product_data_.LingoFilename         
  .datum_;
+    values_["RoundingFilename"        ] = &product_data_.RoundingFilename      
  .datum_;
     values_["FundFilename"            ] = &product_data_.FundFilename          
  .datum_;
-    values_["CvatCorridorFilename"    ] = &product_data_.CvatCorridorFilename  
  .datum_;
+    values_["TierFilename"            ] = &product_data_.TierFilename          
  .datum_;
+    values_["Irc7702QFilename"        ] = &product_data_.Irc7702QFilename      
  .datum_;
     values_["Irc7702NspFilename"      ] = &product_data_.Irc7702NspFilename    
  .datum_;
+    values_["CvatCorridorFilename"    ] = &product_data_.CvatCorridorFilename  
  .datum_;
+    values_["SevenPayFilename"        ] = &product_data_.SevenPayFilename      
  .datum_;
+    values_["GroupProxyFilename"      ] = &product_data_.GroupProxyFilename    
  .datum_;
+    values_["PartialMortalityFilename"] = 
&product_data_.PartialMortalityFilename.datum_;
+    values_["SubstdTblMultFilename"   ] = &product_data_.SubstdTblMultFilename 
  .datum_;
+    values_["InsCoDomicile"           ] = &product_data_.InsCoDomicile         
  .datum_;
     values_["CurrCOIFilename"         ] = &product_data_.CurrCOIFilename       
  .datum_;
     values_["GuarCOIFilename"         ] = &product_data_.GuarCOIFilename       
  .datum_;
     values_["WPFilename"              ] = &product_data_.WPFilename            
  .datum_;
@@ -51,36 +60,9 @@ PolicyDocument::PolicyDocument()
     values_["GuarSpouseRiderFilename" ] = 
&product_data_.GuarSpouseRiderFilename .datum_;
     values_["CurrTermFilename"        ] = &product_data_.CurrTermFilename      
  .datum_;
     values_["GuarTermFilename"        ] = &product_data_.GuarTermFilename      
  .datum_;
-    values_["GroupProxyFilename"      ] = &product_data_.GroupProxyFilename    
  .datum_;
-    values_["SevenPayFilename"        ] = &product_data_.SevenPayFilename      
  .datum_;
-    values_["TgtPremFilename"         ] = &product_data_.TgtPremFilename       
  .datum_;
-    values_["Irc7702QFilename"        ] = &product_data_.Irc7702QFilename      
  .datum_;
-    values_["PartialMortalityFilename"] = 
&product_data_.PartialMortalityFilename.datum_;
-    values_["SubstdTblMultFilename"   ] = &product_data_.SubstdTblMultFilename 
  .datum_;
     values_["CurrSpecAmtLoadFilename" ] = 
&product_data_.CurrSpecAmtLoadFilename .datum_;
     values_["GuarSpecAmtLoadFilename" ] = 
&product_data_.GuarSpecAmtLoadFilename .datum_;
-    values_["RoundingFilename"        ] = &product_data_.RoundingFilename      
  .datum_;
-    values_["TierFilename"            ] = &product_data_.TierFilename          
  .datum_;
-    values_["PolicyForm"              ] = &product_data_.PolicyForm            
  .datum_;
-    values_["PolicyFormAlternative"   ] = &product_data_.PolicyFormAlternative 
  .datum_;
-    values_["PolicyMktgName"          ] = &product_data_.PolicyMktgName        
  .datum_;
-    values_["PolicyLegalName"         ] = &product_data_.PolicyLegalName       
  .datum_;
-    values_["InsCoShortName"          ] = &product_data_.InsCoShortName        
  .datum_;
-    values_["InsCoName"               ] = &product_data_.InsCoName             
  .datum_;
-    values_["InsCoAddr"               ] = &product_data_.InsCoAddr             
  .datum_;
-    values_["InsCoStreet"             ] = &product_data_.InsCoStreet           
  .datum_;
-    values_["InsCoPhone"              ] = &product_data_.InsCoPhone            
  .datum_;
-    values_["InsCoDomicile"           ] = &product_data_.InsCoDomicile         
  .datum_;
-    values_["MainUnderwriter"         ] = &product_data_.MainUnderwriter       
  .datum_;
-    values_["MainUnderwriterAddress"  ] = 
&product_data_.MainUnderwriterAddress  .datum_;
-    values_["CoUnderwriter"           ] = &product_data_.CoUnderwriter         
  .datum_;
-    values_["CoUnderwriterAddress"    ] = &product_data_.CoUnderwriterAddress  
  .datum_;
-    values_["AvName"                  ] = &product_data_.AvName                
  .datum_;
-    values_["CsvName"                 ] = &product_data_.CsvName               
  .datum_;
-    values_["CsvHeaderName"           ] = &product_data_.CsvHeaderName         
  .datum_;
-    values_["NoLapseProvisionName"    ] = &product_data_.NoLapseProvisionName  
  .datum_;
-    values_["InterestDisclaimer"      ] = &product_data_.InterestDisclaimer    
  .datum_;
-    values_["GuarMortalityFootnote"   ] = &product_data_.GuarMortalityFootnote 
  .datum_;
+    values_["TgtPremFilename"         ] = &product_data_.TgtPremFilename       
  .datum_;
 }
 
 PolicyView& PolicyDocument::PredominantView() const
diff --git a/policy_view.xrc b/policy_view.xrc
index 230c5e3..caec3e3 100644
--- a/policy_view.xrc
+++ b/policy_view.xrc
@@ -64,12 +64,12 @@
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>TierFilename</label>
+                                            <label>LingoFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="TierFilename"/>
+                                        <object class="wxTextCtrl" 
name="LingoFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
@@ -97,133 +97,45 @@
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>CvatCorridorFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CvatCorridorFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>Irc7702NspFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="Irc7702NspFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>CurrCOIFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CurrCOIFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>GuarCOIFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="GuarCOIFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>WPFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="WPFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>ADDFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="ADDFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>ChildRiderFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="ChildRiderFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            
<label>CurrSpouseRiderFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CurrSpouseRiderFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            
<label>GuarSpouseRiderFilename</label>
+                                            <label>TierFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="GuarSpouseRiderFilename"/>
+                                        <object class="wxTextCtrl" 
name="TierFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>CurrTermFilename</label>
+                                            <label>Irc7702QFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CurrTermFilename"/>
+                                        <object class="wxTextCtrl" 
name="Irc7702QFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>GuarTermFilename</label>
+                                            <label>Irc7702NspFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="GuarTermFilename"/>
+                                        <object class="wxTextCtrl" 
name="Irc7702NspFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>GroupProxyFilename</label>
+                                            <label>CvatCorridorFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="GroupProxyFilename"/>
+                                        <object class="wxTextCtrl" 
name="CvatCorridorFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
@@ -240,23 +152,12 @@
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>TgtPremFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="TgtPremFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>Irc7702QFilename</label>
+                                            <label>GroupProxyFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="Irc7702QFilename"/>
+                                        <object class="wxTextCtrl" 
name="GroupProxyFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
@@ -284,23 +185,12 @@
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            
<label>CurrSpecAmtLoadFilename</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CurrSpecAmtLoadFilename"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            
<label>GuarSpecAmtLoadFilename</label>
+                                            <label>InsCoDomicile</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="GuarSpecAmtLoadFilename"/>
+                                        <object class="wxTextCtrl" 
name="InsCoDomicile"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                 </object><!-- wxFlexGridSizer -->
@@ -316,221 +206,133 @@
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>PolicyForm</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="PolicyForm"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            
<label>PolicyFormAlternative</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="PolicyFormAlternative"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>PolicyMktgName</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="PolicyMktgName"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>PolicyLegalName</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="PolicyLegalName"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>InsCoShortName</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="InsCoShortName"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>InsCoName</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="InsCoName"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>InsCoAddr</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="InsCoAddr"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>InsCoStreet</label>
-                                        </object>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="InsCoStreet"/>
-                                        <minsize>160,-1</minsize>
-                                    </object>
-                                    <object class="sizeritem">
-                                        
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxStaticText">
-                                            <label>InsCoPhone</label>
+                                            <label>CurrCOIFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="InsCoPhone"/>
+                                        <object class="wxTextCtrl" 
name="CurrCOIFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>InsCoDomicile</label>
+                                            <label>GuarCOIFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="InsCoDomicile"/>
+                                        <object class="wxTextCtrl" 
name="GuarCOIFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>MainUnderwriter</label>
+                                            <label>WPFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="MainUnderwriter"/>
+                                        <object class="wxTextCtrl" 
name="WPFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            
<label>MainUnderwriterAddress</label>
+                                            <label>ADDFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="MainUnderwriterAddress"/>
+                                        <object class="wxTextCtrl" 
name="ADDFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>CoUnderwriter</label>
+                                            <label>ChildRiderFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CoUnderwriter"/>
+                                        <object class="wxTextCtrl" 
name="ChildRiderFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>CoUnderwriterAddress</label>
+                                            
<label>CurrSpouseRiderFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CoUnderwriterAddress"/>
+                                        <object class="wxTextCtrl" 
name="CurrSpouseRiderFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>AvName</label>
+                                            
<label>GuarSpouseRiderFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="AvName"/>
+                                        <object class="wxTextCtrl" 
name="GuarSpouseRiderFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>CsvName</label>
+                                            <label>CurrTermFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CsvName"/>
+                                        <object class="wxTextCtrl" 
name="CurrTermFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>CsvHeaderName</label>
+                                            <label>GuarTermFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="CsvHeaderName"/>
+                                        <object class="wxTextCtrl" 
name="GuarTermFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>NoLapseProvisionName</label>
+                                            
<label>CurrSpecAmtLoadFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="NoLapseProvisionName"/>
+                                        <object class="wxTextCtrl" 
name="CurrSpecAmtLoadFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            <label>InterestDisclaimer</label>
+                                            
<label>GuarSpecAmtLoadFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="InterestDisclaimer"/>
+                                        <object class="wxTextCtrl" 
name="GuarSpecAmtLoadFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL</flag>
                                         <object class="wxStaticText">
-                                            
<label>GuarMortalityFootnote</label>
+                                            <label>TgtPremFilename</label>
                                         </object>
                                     </object>
                                     <object class="sizeritem">
                                         
<flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
-                                        <object class="wxTextCtrl" 
name="GuarMortalityFootnote"/>
+                                        <object class="wxTextCtrl" 
name="TgtPremFilename"/>
                                         <minsize>160,-1</minsize>
                                     </object>
                                 </object><!-- wxFlexGridSizer -->
diff --git a/posix_fhs.make b/posix_fhs.make
index 517b967..bd1df19 100644
--- a/posix_fhs.make
+++ b/posix_fhs.make
@@ -31,22 +31,9 @@ PERFORM :=
 platform_boost_libraries := \
   -lboost_filesystem-gcc \
 
-platform_xmlwrapp_libraries := \
-  -lxsltwrapp \
-  -lxmlwrapp \
-
 # The libraries referenced above may be used if desired, but are not
 # necessary because lmi compiles their source code to object files.
 platform_boost_libraries :=
-platform_xmlwrapp_libraries :=
-
-# '-lexslt'--see:
-#   http://mail.gnome.org/archives/xslt/2001-October/msg00133.html
-
-platform_gnome_xml_libraries := \
-  -lexslt \
-  $(shell xslt-config --libs) \
-  $(shell xml2-config --libs) \
 
 AR      := ar
 CC      := gcc
diff --git a/preferences_model.cpp b/preferences_model.cpp
index 7a7258a..086fcdb 100644
--- a/preferences_model.cpp
+++ b/preferences_model.cpp
@@ -26,6 +26,7 @@
 #include "alert.hpp"
 #include "configurable_settings.hpp"
 #include "miscellany.hpp"               // begins_with()
+#include "path_utility.hpp"             // remove_alien_msw_root()
 #include "ssize_lmi.hpp"
 #include "value_cast.hpp"
 
@@ -57,7 +58,7 @@ std::string generic_path(std::string const& s)
 #if defined LMI_MSW
     return fs::system_complete(fs::path(s)).string();
 #else  // !defined LMI_MSW
-    return s;
+    return remove_alien_msw_root(s).string();
 #endif // !defined LMI_MSW
 }
 
diff --git a/premium_tax.cpp b/premium_tax.cpp
index f9df537..e892c9d 100644
--- a/premium_tax.cpp
+++ b/premium_tax.cpp
@@ -358,32 +358,6 @@ double premium_tax::calculate_load(double payment, 
stratified_charges const& str
     return z;
 }
 
-/// Suggest updating rates each year.
-///
-/// AZ rates vary by calendar year:
-///   
https://insurance.az.gov/sites/default/files/documents/files/RegulatoryBulletin2016-02_20160705.pdf
-///   2017 0.0190
-///   2018 0.0185
-///   2019 0.0180
-///   2020 0.0175
-///   2021 0.0170
-///
-/// Without this assertion, it's too easy to forget to update this
-/// rate when building lmi in December for release in January. Each
-/// year, expunge the particular assertion that failed, after updating
-/// the AZ rate manually. It is better not to make the rate update
-/// itself automatically because the schedule of future rates may have
-/// changed in the meantime (and actually did, in the 20170508T1544Z
-/// commit). Expunge this block comment when the last assertion is
-/// expunged.
-///
-/// Implementation notes:
-///  - __DATE__[0] is month-name's first letter; D = December
-///  - __DATE__[10] is last digit of a four-digit year
-
-static_assert('D' != __DATE__[0] || '0' != __DATE__[10]);
-static_assert('D' != __DATE__[0] || '1' != __DATE__[10]);
-
 /// Premium-tax rates for life insurance without retaliation.
 ///
 /// A single table suffices for every domicile, because retaliation is
@@ -403,7 +377,7 @@ std::vector<double> const& 
premium_tax_rates_for_life_insurance()
     static int const n = 53;
     static double const d[n] =
         //   AL       AK       AZ       AR       CA       CO       CT
-        {0.0230,  tiered,  0.0175,  0.0250,  0.0235,  0.0200,  0.0175
+        {0.0230,  tiered,  0.0170,  0.0250,  0.0235,  0.0200,  0.0175
         //   DE       DC       FL       GA       HI       ID
         ,0.0200,  0.0175,  0.0175,  0.0225,  0.0275,  0.0150
         //   IL       IN       IA       KS       KY       LA       ME
diff --git a/product_data.cpp b/product_data.cpp
index e908d5e..2c86472 100644
--- a/product_data.cpp
+++ b/product_data.cpp
@@ -183,6 +183,7 @@ void product_data::ascribe_members()
 {
     ascribe("DatabaseFilename"           , &product_data::DatabaseFilename     
         );
     ascribe("FundFilename"               , &product_data::FundFilename         
         );
+    ascribe("LingoFilename"              , &product_data::LingoFilename        
         );
     ascribe("RoundingFilename"           , &product_data::RoundingFilename     
         );
     ascribe("TierFilename"               , &product_data::TierFilename         
         );
     ascribe("CvatCorridorFilename"       , &product_data::CvatCorridorFilename 
         );
@@ -205,8 +206,8 @@ void product_data::ascribe_members()
     ascribe("SubstdTblMultFilename"      , 
&product_data::SubstdTblMultFilename         );
     ascribe("CurrSpecAmtLoadFilename"    , 
&product_data::CurrSpecAmtLoadFilename       );
     ascribe("GuarSpecAmtLoadFilename"    , 
&product_data::GuarSpecAmtLoadFilename       );
-    ascribe("PolicyForm"                 , &product_data::PolicyForm           
         );
-    ascribe("PolicyFormAlternative"      , 
&product_data::PolicyFormAlternative         );
+    ascribe("PolicyForm"                 , &product_data::PolicyForm           
         ); // LINGO !! expunge
+    ascribe("PolicyFormAlternative"      , 
&product_data::PolicyFormAlternative         ); // LINGO !! expunge
     ascribe("PolicyMktgName"             , &product_data::PolicyMktgName       
         );
     ascribe("PolicyLegalName"            , &product_data::PolicyLegalName      
         );
     ascribe("InsCoShortName"             , &product_data::InsCoShortName       
         );
@@ -305,7 +306,6 @@ void product_data::ascribe_members()
     ascribe("FlexiblePremiumFootnote"    , 
&product_data::FlexiblePremiumFootnote       );
     ascribe("GuaranteedValuesFootnote"   , 
&product_data::GuaranteedValuesFootnote      );
     ascribe("CreditingRateFootnote"      , 
&product_data::CreditingRateFootnote         );
-    ascribe("DefnGuarGenAcctRate"        , &product_data::DefnGuarGenAcctRate  
         );
     ascribe("GrossRateFootnote"          , &product_data::GrossRateFootnote    
         );
     ascribe("NetRateFootnote"            , &product_data::NetRateFootnote      
         );
     ascribe("MecFootnote"                , &product_data::MecFootnote          
         );
@@ -359,6 +359,7 @@ void product_data::ascribe_members()
     ascribe("Fn1035Charge"               , &product_data::Fn1035Charge         
         );
     ascribe("FnMecExtraWarning"          , &product_data::FnMecExtraWarning    
         );
     ascribe("FnNotTaxAdvice"             , &product_data::FnNotTaxAdvice       
         );
+    ascribe("FnNotTaxAdvice2"            , &product_data::FnNotTaxAdvice2      
         );
     ascribe("FnImf"                      , &product_data::FnImf                
         );
     ascribe("FnCensus"                   , &product_data::FnCensus             
         );
     ascribe("FnDacTax"                   , &product_data::FnDacTax             
         );
@@ -372,6 +373,7 @@ void product_data::ascribe_members()
     ascribe("FnGuaranteedPremium"        , &product_data::FnGuaranteedPremium  
         );
     ascribe("FnOmnibusDisclaimer"        , &product_data::FnOmnibusDisclaimer  
         );
     ascribe("FnInitialDbo"               , &product_data::FnInitialDbo         
         );
+    ascribe("DefnGuarGenAcctRate"        , &product_data::DefnGuarGenAcctRate  
         );
     ascribe("DefnAV"                     , &product_data::DefnAV               
         );
     ascribe("DefnCSV"                    , &product_data::DefnCSV              
         );
     ascribe("DefnMec"                    , &product_data::DefnMec              
         );
@@ -615,6 +617,7 @@ sample::sample()
     // Names of lmi product files.
     item("DatabaseFilename")           = glossed_string("sample.database");
     item("FundFilename")               = glossed_string("sample.funds");
+    item("LingoFilename")              = glossed_string("sample.lingo");
     item("RoundingFilename")           = glossed_string("sample.rounding");
     item("TierFilename")               = glossed_string("sample.strata");
 
@@ -644,8 +647,8 @@ sample::sample()
     item("InsCoDomicile")              = glossed_string("WI");
 
     // Substitutable strings.
-    item("PolicyForm")                 = glossed_string("UL32768-NY");
-    item("PolicyFormAlternative")      = glossed_string("UL32768-X");
+    item("PolicyForm")                 = glossed_string("UL32768-NY"); // 
LINGO !! expunge
+    item("PolicyFormAlternative")      = glossed_string("UL32768-X");  // 
LINGO !! expunge
     item("PolicyMktgName")             = glossed_string("UL Supreme");
     item("PolicyLegalName")            = glossed_string("Flexible Premium 
Adjustable Life Insurance Policy");
     item("InsCoShortName")             = glossed_string("Superior Life");
@@ -697,6 +700,7 @@ sample::sample()
     item("Fn1035Charge")               = S_Fn1035Charge;
     item("FnMecExtraWarning")          = S_FnMecExtraWarning;
     item("FnNotTaxAdvice")             = S_FnNotTaxAdvice;
+    item("FnNotTaxAdvice2")            = ""; // Deliberately empty: shouldn't 
even exist.
     item("FnImf")                      = S_FnImf;
     item("FnCensus")                   = S_FnCensus;
     item("FnDacTax")                   = S_FnDacTax;
@@ -778,6 +782,7 @@ sample2::sample2()
     // Names of lmi product files.
     item("DatabaseFilename")           = glossed_string("sample.database");
     item("FundFilename")               = glossed_string("sample.funds");
+    item("LingoFilename")              = glossed_string("sample.lingo");
     item("RoundingFilename")           = glossed_string("sample.rounding");
     item("TierFilename")               = glossed_string("sample.strata");
 
@@ -809,6 +814,7 @@ sample2::sample2()
 
 sample2naic::sample2naic()
 {
+    item("DatabaseFilename")           = 
glossed_string("sample2naic.database");
 }
 
 sample2finra::sample2finra()
@@ -826,6 +832,80 @@ sample2gpp::sample2gpp()
     item("DatabaseFilename")           = glossed_string("sample2gpp.database");
 }
 
+static std::string const S_Poe0 =
+  "The \"Red Death\" had long devastated the country. No pestilence"
+  " had ever been so fatal, or so hideous. Blood was its Avatar and"
+  " its seal--the redness and the horror of blood. There were sharp"
+  " pains, and sudden dizziness, and then profuse bleeding at the"
+  " pores, with dissolution. The scarlet stains upon the body and"
+  " especially upon the face of the victim, were the pest ban which"
+  " shut him out from the aid and from the sympathy of his fellow-men."
+  " And the whole seizure, progress and termination of the disease,"
+  " were the incidents of half an hour.";
+static std::string const S_Poe1 =
+  "But the Prince Prospero was happy and dauntless and sagacious. When"
+  " his dominions were half depopulated, he summoned to his presence a"
+  " thousand hale and light-hearted friends from among the knights and"
+  " dames of his court, and with these retired to the deep seclusion"
+  " of one of his castellated abbeys. This was an extensive and"
+  " magnificent structure, the creation of the prince's own eccentric"
+  " yet august taste. A strong and lofty wall girdled it in. This wall"
+  " had gates of iron. The courtiers, having entered, brought furnaces"
+  " and massy hammers and welded the bolts. They resolved to leave"
+  " means neither of ingress nor egress to the sudden impulses of"
+  " despair or of frenzy from within. The abbey was amply provisioned."
+  " With such precautions the courtiers might bid defiance to contagion."
+  " The external world could take care of itself. In the meantime it"
+  " was folly to grieve, or to think. The prince had provided all the"
+  " appliances of pleasure. There were buffoons, there were"
+  " improvisatori, there were ballet-dancers, there were musicians,"
+  " there was Beauty, there was wine. All these and security were"
+  " within. Without was the \"Red Death\".";
+static std::string const S_Poe2 =
+  "It was towards the close of the fifth or sixth month of his"
+  " seclusion, and while the pestilence raged most furiously abroad,"
+  " that the Prince Prospero entertained his thousand friends at a"
+  " masked ball of the most unusual magnificence.";
+static std::string const S_Poe3 =
+  "It was a voluptuous scene, that masquerade. But first let me tell"
+  " of the rooms in which it was held. These were seven--an imperial"
+  " suite. In many palaces, however, such suites form a long and"
+  " straight vista, while the folding doors slide back nearly to the"
+  " walls on either hand, so that the view of the whole extent is"
+  " scarcely impeded. Here the case was very different, as might have"
+  " been expected from the duke's love of the _bizarre_. The apartments"
+  " were so irregularly disposed that the vision embraced but little"
+  " more than one at a time. There was a sharp turn at every twenty or"
+  " thirty yards, and at each turn a novel effect. To the right and"
+  " left, in the middle of each wall, a tall and narrow Gothic window"
+  " looked out upon a closed corridor which pursued the windings of the"
+  " suite. These windows were of stained glass whose color varied in"
+  " accordance with the prevailing hue of the decorations of the"
+  " chamber into which it opened. That at the eastern extremity was"
+  " hung, for example in blue--and vividly blue were its windows. The"
+  " second chamber was purple in its ornaments and tapestries, and here"
+  " the panes were purple. The third was green throughout, and so were"
+  " the casements. The fourth was furnished and lighted with orange--the"
+  " fifth with white--the sixth with violet. The seventh apartment was"
+  " closely shrouded in black velvet tapestries that hung all over the"
+  " ceiling and down the walls, falling in heavy folds upon a carpet of"
+  " the same material and hue. But in this chamber only, the color of"
+  " the windows failed to correspond with the decorations. The panes"
+  " here were scarlet--a deep blood color. Now in no one of the seven"
+  " apartments was there any lamp or candelabrum, amid the profusion of"
+  " golden ornaments that lay scattered to and fro or depended from the"
+  " roof. There was no light of any kind emanating from lamp or candle"
+  " within the suite of chambers. But in the corridors that followed the"
+  " suite, there stood, opposite to each window, a heavy tripod, bearing"
+  " a brazier of fire, that projected its rays through the tinted glass"
+  " and so glaringly illumined the room. And thus were produced a"
+  " multitude of gaudy and fantastic appearances. But in the western or"
+  " black chamber the effect of the fire-light that streamed upon the"
+  " dark hangings through the blood-tinted panes, was ghastly in the"
+  " extreme, and produced so wild a look upon the countenances of those"
+  " who entered, that there were few of the company bold enough to set"
+  " foot within its precincts at all.";
+
 /// This specimen product
 ///   https://lists.nongnu.org/archive/html/lmi/2018-09/msg00039.html
 /// | has deliberately overlong footnotes
@@ -834,83 +914,10 @@ sample2gpp::sample2gpp()
 sample2ipp::sample2ipp()
 {
     item("DatabaseFilename")           = glossed_string("sample2ipp.database");
-    item("IrrDbFootnote") = glossed_string
-        ("The \"Red Death\" had long devastated the country. No pestilence"
-         " had ever been so fatal, or so hideous. Blood was its Avatar and"
-         " its seal--the redness and the horror of blood. There were sharp"
-         " pains, and sudden dizziness, and then profuse bleeding at the"
-         " pores, with dissolution. The scarlet stains upon the body and"
-         " especially upon the face of the victim, were the pest ban which"
-         " shut him out from the aid and from the sympathy of his fellow-men."
-         " And the whole seizure, progress and termination of the disease,"
-         " were the incidents of half an hour."
-        );
-    item("IrrCsvFootnote") = glossed_string
-        ("But the Prince Prospero was happy and dauntless and sagacious. When"
-         " his dominions were half depopulated, he summoned to his presence a"
-         " thousand hale and light-hearted friends from among the knights and"
-         " dames of his court, and with these retired to the deep seclusion"
-         " of one of his castellated abbeys. This was an extensive and"
-         " magnificent structure, the creation of the prince's own eccentric"
-         " yet august taste. A strong and lofty wall girdled it in. This wall"
-         " had gates of iron. The courtiers, having entered, brought furnaces"
-         " and massy hammers and welded the bolts. They resolved to leave"
-         " means neither of ingress nor egress to the sudden impulses of"
-         " despair or of frenzy from within. The abbey was amply provisioned."
-         " With such precautions the courtiers might bid defiance to 
contagion."
-         " The external world could take care of itself. In the meantime it"
-         " was folly to grieve, or to think. The prince had provided all the"
-         " appliances of pleasure. There were buffoons, there were"
-         " improvisatori, there were ballet-dancers, there were musicians,"
-         " there was Beauty, there was wine. All these and security were"
-         " within. Without was the \"Red Death\"."
-        );
-    item("MortalityChargesFootnote") = glossed_string
-        ("It was towards the close of the fifth or sixth month of his"
-         " seclusion, and while the pestilence raged most furiously abroad,"
-         " that the Prince Prospero entertained his thousand friends at a"
-         " masked ball of the most unusual magnificence."
-        );
-    item("PolicyYearFootnote") = glossed_string
-        ("It was a voluptuous scene, that masquerade. But first let me tell"
-         " of the rooms in which it was held. These were seven--an imperial"
-         " suite. In many palaces, however, such suites form a long and"
-         " straight vista, while the folding doors slide back nearly to the"
-         " walls on either hand, so that the view of the whole extent is"
-         " scarcely impeded. Here the case was very different, as might have"
-         " been expected from the duke's love of the _bizarre_. The apartments"
-         " were so irregularly disposed that the vision embraced but little"
-         " more than one at a time. There was a sharp turn at every twenty or"
-         " thirty yards, and at each turn a novel effect. To the right and"
-         " left, in the middle of each wall, a tall and narrow Gothic window"
-         " looked out upon a closed corridor which pursued the windings of the"
-         " suite. These windows were of stained glass whose color varied in"
-         " accordance with the prevailing hue of the decorations of the"
-         " chamber into which it opened. That at the eastern extremity was"
-         " hung, for example in blue--and vividly blue were its windows. The"
-         " second chamber was purple in its ornaments and tapestries, and here"
-         " the panes were purple. The third was green throughout, and so were"
-         " the casements. The fourth was furnished and lighted with 
orange--the"
-         " fifth with white--the sixth with violet. The seventh apartment was"
-         " closely shrouded in black velvet tapestries that hung all over the"
-         " ceiling and down the walls, falling in heavy folds upon a carpet of"
-         " the same material and hue. But in this chamber only, the color of"
-         " the windows failed to correspond with the decorations. The panes"
-         " here were scarlet--a deep blood color. Now in no one of the seven"
-         " apartments was there any lamp or candelabrum, amid the profusion of"
-         " golden ornaments that lay scattered to and fro or depended from the"
-         " roof. There was no light of any kind emanating from lamp or candle"
-         " within the suite of chambers. But in the corridors that followed 
the"
-         " suite, there stood, opposite to each window, a heavy tripod, 
bearing"
-         " a brazier of fire, that projected its rays through the tinted glass"
-         " and so glaringly illumined the room. And thus were produced a"
-         " multitude of gaudy and fantastic appearances. But in the western or"
-         " black chamber the effect of the fire-light that streamed upon the"
-         " dark hangings through the blood-tinted panes, was ghastly in the"
-         " extreme, and produced so wild a look upon the countenances of those"
-         " who entered, that there were few of the company bold enough to set"
-         " foot within its precincts at all."
-        );
+    item("IrrDbFootnote")              = S_Poe0;
+    item("IrrCsvFootnote")             = S_Poe1;
+    item("MortalityChargesFootnote")   = S_Poe2;
+    item("PolicyYearFootnote")         = S_Poe3;
 }
 
 sample2xyz::sample2xyz()
diff --git a/product_data.hpp b/product_data.hpp
index 081669d..d681dbd 100644
--- a/product_data.hpp
+++ b/product_data.hpp
@@ -142,6 +142,7 @@ class LMI_SO product_data
     // Names of files that contain other product data.
     glossed_string DatabaseFilename;
     glossed_string FundFilename;
+    glossed_string LingoFilename;
     glossed_string RoundingFilename;
     glossed_string TierFilename;
 
@@ -168,8 +169,8 @@ class LMI_SO product_data
     glossed_string GuarSpecAmtLoadFilename;
 
     // Essential strings describing the policy and company.
-    glossed_string PolicyForm;
-    glossed_string PolicyFormAlternative;
+    glossed_string PolicyForm; // LINGO !! expunge
+    glossed_string PolicyFormAlternative; // LINGO !! expunge
     glossed_string PolicyMktgName;
     glossed_string PolicyLegalName;
     glossed_string InsCoShortName;
@@ -212,8 +213,6 @@ class LMI_SO product_data
     glossed_string UwClassRated;
     glossed_string UwClassUltra;
 
-    // TODO ?? Most of the following are missing from the GUI.
-
     // Ledger column definitions.
     glossed_string AccountValueFootnote;
     glossed_string AttainedAgeFootnote;
@@ -295,7 +294,6 @@ class LMI_SO product_data
     glossed_string FlexiblePremiumFootnote;
     glossed_string GuaranteedValuesFootnote;
     glossed_string CreditingRateFootnote;
-    glossed_string DefnGuarGenAcctRate;
     glossed_string GrossRateFootnote;
     glossed_string NetRateFootnote;
     glossed_string MecFootnote;
@@ -349,6 +347,7 @@ class LMI_SO product_data
     glossed_string Fn1035Charge;
     glossed_string FnMecExtraWarning;
     glossed_string FnNotTaxAdvice;
+    glossed_string FnNotTaxAdvice2;
     glossed_string FnImf;
     glossed_string FnCensus;
     glossed_string FnDacTax;
@@ -362,6 +361,7 @@ class LMI_SO product_data
     glossed_string FnGuaranteedPremium;
     glossed_string FnOmnibusDisclaimer;
     glossed_string FnInitialDbo;
+    glossed_string DefnGuarGenAcctRate;
     glossed_string DefnAV;
     glossed_string DefnCSV;
     glossed_string DefnMec;
@@ -369,7 +369,7 @@ class LMI_SO product_data
     glossed_string DefnSpecAmt;
 };
 
-void LMI_SO load(product_data      &, fs::path const&);
-void LMI_SO save(product_data const&, fs::path const&);
+LMI_SO void load(product_data      &, fs::path const&);
+LMI_SO void save(product_data const&, fs::path const&);
 
 #endif // product_data_hpp
diff --git a/product_file_test.cpp b/product_file_test.cpp
index 149b08b..4f589da 100644
--- a/product_file_test.cpp
+++ b/product_file_test.cpp
@@ -25,6 +25,7 @@
 #include "database.hpp"
 #include "dbdict.hpp"
 #include "fund_data.hpp"
+#include "lingo.hpp"
 #include "product_data.hpp"
 #include "rounding_rules.hpp"
 #include "stratified_charges.hpp"
@@ -57,12 +58,14 @@ class product_file_test
     static void assay_speed();
     static void read_database_file()   ;
     static void read_fund_file()       ;
+    static void read_lingo_file()      ;
     static void read_policy_file()     ;
     static void read_rounding_file()   ;
     static void read_stratified_file() ;
 
     static std::string database_filename_   ;
     static std::string fund_filename_       ;
+    static std::string lingo_filename_      ;
     static std::string policy_filename_     ;
     static std::string rounding_filename_   ;
     static std::string stratified_filename_ ;
@@ -70,6 +73,7 @@ class product_file_test
 
 std::string product_file_test::database_filename_   ;
 std::string product_file_test::fund_filename_       ;
+std::string product_file_test::lingo_filename_      ;
 std::string product_file_test::policy_filename_     ;
 std::string product_file_test::rounding_filename_   ;
 std::string product_file_test::stratified_filename_ ;
@@ -80,6 +84,7 @@ void product_file_test::get_filenames()
     product_data p(policy_filename_);
     database_filename_   = AddDataDir(p.datum("DatabaseFilename"));
     fund_filename_       = AddDataDir(p.datum("FundFilename"    ));
+    lingo_filename_      = AddDataDir(p.datum("LingoFilename"   ));
     rounding_filename_   = AddDataDir(p.datum("RoundingFilename"));
     stratified_filename_ = AddDataDir(p.datum("TierFilename"    ));
 }
@@ -92,6 +97,7 @@ void product_file_test::test_copying()
     product_data q(p);
     BOOST_TEST(database_filename_   == 
AddDataDir(q.datum("DatabaseFilename")));
     BOOST_TEST(fund_filename_       == AddDataDir(q.datum("FundFilename"    
)));
+    BOOST_TEST(lingo_filename_      == AddDataDir(q.datum("LingoFilename"   
)));
     BOOST_TEST(rounding_filename_   == 
AddDataDir(q.datum("RoundingFilename")));
     BOOST_TEST(stratified_filename_ == AddDataDir(q.datum("TierFilename"    
)));
 
@@ -133,33 +139,38 @@ void product_file_test::test_copying()
 }
 
 // This implementation:
-//   auto d = DBDictionary::read_via_cache(database_filename_);
+//   auto z = DBDictionary::read_via_cache(database_filename_);
 // would cause assay_speed() to report a much faster run time,
 // yet such a timing would have little significance.
 
 void product_file_test::read_database_file()
 {
-    DBDictionary d(database_filename_);
+    DBDictionary z(database_filename_);
 }
 
 void product_file_test::read_fund_file()
 {
-    FundData f(fund_filename_);
+    FundData z(fund_filename_);
+}
+
+void product_file_test::read_lingo_file()
+{
+    lingo z(lingo_filename_);
 }
 
 void product_file_test::read_policy_file()
 {
-    product_data p(policy_filename_);
+    product_data z(policy_filename_);
 }
 
 void product_file_test::read_rounding_file()
 {
-    rounding_rules r(rounding_filename_);
+    rounding_rules z(rounding_filename_);
 }
 
 void product_file_test::read_stratified_file()
 {
-    stratified_charges s(stratified_filename_);
+    stratified_charges z(stratified_filename_);
 }
 
 void product_file_test::assay_speed()
@@ -168,6 +179,7 @@ void product_file_test::assay_speed()
         << "  Speed tests..."
         << "\n  Read 'database'   : " << TimeAnAliquot(read_database_file  )
         << "\n  Read 'fund'       : " << TimeAnAliquot(read_fund_file      )
+        << "\n  Read 'lingo'      : " << TimeAnAliquot(read_lingo_file     )
         << "\n  Read 'policy'     : " << TimeAnAliquot(read_policy_file    )
         << "\n  Read 'rounding'   : " << TimeAnAliquot(read_rounding_file  )
         << "\n  Read 'stratified' : " << TimeAnAliquot(read_stratified_file)
diff --git a/progress_meter.hpp b/progress_meter.hpp
index e3520c1..47dff8b 100644
--- a/progress_meter.hpp
+++ b/progress_meter.hpp
@@ -198,7 +198,7 @@
 #include <memory>                       // unique_ptr
 #include <string>
 
-std::ostringstream& LMI_SO progress_meter_unit_test_stream();
+LMI_SO std::ostringstream& progress_meter_unit_test_stream();
 
 class LMI_SO progress_meter
 {
@@ -249,7 +249,7 @@ class LMI_SO progress_meter
     bool              was_cancelled_;
 };
 
-std::unique_ptr<progress_meter> LMI_SO create_progress_meter
+LMI_SO std::unique_ptr<progress_meter> create_progress_meter
     (int                               max_count
     ,std::string const&                title = std::string()
     ,progress_meter::enum_display_mode       = progress_meter::e_normal_display
@@ -261,6 +261,6 @@ typedef std::unique_ptr<progress_meter> 
(*progress_meter_creator_type)
     ,progress_meter::enum_display_mode
     );
 
-bool LMI_SO set_progress_meter_creator(progress_meter_creator_type);
+LMI_SO bool set_progress_meter_creator(progress_meter_creator_type);
 
 #endif // progress_meter_hpp
diff --git a/reg_d_group_narr_summary2.mst b/reg_d_group_narr_summary2.mst
index 2ef950d..063065b 100644
--- a/reg_d_group_narr_summary2.mst
+++ b/reg_d_group_narr_summary2.mst
@@ -82,7 +82,7 @@ SEPARATE ACCOUNT
 </p>
 
 <p>
-    {{FnNotTaxAdvice}}
+    {{FnNotTaxAdvice2}}
 </p>
 
 <p>
diff --git a/reg_d_indiv_cover_page.mst b/reg_d_indiv_cover_page.mst
index 1c3d698..21dc511 100644
--- a/reg_d_indiv_cover_page.mst
+++ b/reg_d_indiv_cover_page.mst
@@ -84,7 +84,7 @@ Date Prepared: {{DatePrepared}}
 
 <font size="-1">
 
-<!-- PDF !! HypotheticalRatesHeader -->
+<!-- PDF !! HypotheticalRatesHeader2 -->
 <p>
 The purpose of this illustration is to show how hypothetical rates
 of return will affect policy account value. These hypothetical
diff --git a/report_table.hpp b/report_table.hpp
index bbc21a0..aa81501 100644
--- a/report_table.hpp
+++ b/report_table.hpp
@@ -94,9 +94,9 @@ class LMI_SO table_column_info
     bool          const is_elastic_;
 };
 
-std::vector<int> LMI_SO apportion(std::vector<int> const& votes, int seats);
+LMI_SO std::vector<int> apportion(std::vector<int> const& votes, int seats);
 
-std::vector<int> LMI_SO set_column_widths
+LMI_SO std::vector<int> set_column_widths
     (std::vector<table_column_info> const& all_columns
     ,int                                   max_table_width
     ,int                                   desired_margin
diff --git a/round_to.hpp b/round_to.hpp
index 611286e..26c4ac9 100644
--- a/round_to.hpp
+++ b/round_to.hpp
@@ -255,7 +255,7 @@ RealType erroneous_rounding_function(RealType)
 template<typename RealType>
 class round_to
 {
-    static_assert(std::is_floating_point<RealType>::value);
+    static_assert(std::is_floating_point_v<RealType>);
 
   public:
     /// The default ctor only makes the class DefaultConstructible;
diff --git a/rounding_rules.hpp b/rounding_rules.hpp
index 1a402b2..2bd6e4f 100644
--- a/rounding_rules.hpp
+++ b/rounding_rules.hpp
@@ -155,7 +155,7 @@ class LMI_SO rounding_rules final
     rounding_parameters round_minutiae_          ;
 };
 
-void LMI_SO load(rounding_rules      &, fs::path const&);
-void LMI_SO save(rounding_rules const&, fs::path const&);
+LMI_SO void load(rounding_rules      &, fs::path const&);
+LMI_SO void save(rounding_rules const&, fs::path const&);
 
 #endif // rounding_rules_hpp
diff --git a/safely_dereference_as.hpp b/safely_dereference_as.hpp
index d0a5ac4..1c47638 100644
--- a/safely_dereference_as.hpp
+++ b/safely_dereference_as.hpp
@@ -68,7 +68,7 @@
 template<typename T, typename U>
 T& safely_dereference_as(U* u)
 {
-    static_assert(std::is_base_of<U,T>::value);
+    static_assert(std::is_base_of_v<U,T>);
     if(!u)
         {
         std::ostringstream oss;
diff --git a/sample.hpp b/sample.hpp
new file mode 100644
index 0000000..acdcb34
--- /dev/null
+++ b/sample.hpp
@@ -0,0 +1,439 @@
+// Parameters for a company's entire portfolio of products.
+//
+// Copyright (C) 2020 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
+//
+// https://savannah.nongnu.org/projects/lmi
+// email: <gchicares@sbcglobal.net>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+#ifndef sample_hpp
+#define sample_hpp
+
+#include "config.hpp"
+
+// For now, this file contains only an enumeration, but someday it may
+// include other information that applies to an entire portfolio.
+
+/// For the fictional Superior Life Insurance Company of Superior, WI.
+
+namespace superior
+{
+/// Enumerate lingo strings.
+///
+/// This is deliberately defined with enum-key 'enum' rather than
+/// 'enum class' or 'enum struct'. Because it is defined inside a
+/// namespace, with an enum-base, it is the same as an 'enum class'
+/// except that its enumerators decay to int as nature intended.
+/// Feature comparison:
+///
+///   this enum  enum class   desirable properties
+///   ---------  ----------   --------------------
+///      yes        yes       avoids polluting global namespace
+///      yes        yes       specifies underlying type
+///      yes         no       implicitly converts to int
+///
+/// Enumerator zero is reserved for an empty string because zero is
+/// the default value for database entities.
+
+enum lingo : int
+    {empty_string = 0
+
+    // Essential strings describing the policy and company.
+    ,policy_form_term
+    ,policy_form
+    ,policy_form_KS_KY
+    // LINGO !! reconsider this...
+    // These MixedCase terms seem better--it's easier to grep for a
+    // string that has no lower_case_with_underscores variant:
+//  ,PolicyForm_term
+//  ,PolicyForm
+    ,PolicyFormAlternative_term // LINGO !! expunge
+    ,PolicyFormAlternative // LINGO !! expunge
+    ,PolicyMktgName_term
+    ,PolicyMktgName
+    ,PolicyLegalName_term
+    ,PolicyLegalName
+    ,InsCoShortName_term
+    ,InsCoShortName
+    ,InsCoName_term
+    ,InsCoName
+    ,InsCoAddr_term
+    ,InsCoAddr
+    ,InsCoStreet_term
+    ,InsCoStreet
+    ,InsCoPhone_term
+    ,InsCoPhone
+    ,MainUnderwriter_term
+    ,MainUnderwriter
+    ,MainUnderwriterAddress_term
+    ,MainUnderwriterAddress
+    ,CoUnderwriter_term
+    ,CoUnderwriter
+    ,CoUnderwriterAddress_term
+    ,CoUnderwriterAddress
+
+    // Terms defined in the contract, which must be used for column
+    // headers, footnotes, etc. according to the illustration reg.
+    ,AvName_term
+    ,AvName
+    ,CsvName_term
+    ,CsvName
+    ,CsvHeaderName_term
+    ,CsvHeaderName
+    ,NoLapseProvisionName_term
+    ,NoLapseProvisionName
+    ,ContractName_term
+    ,ContractName
+    ,DboName_term
+    ,DboName
+    ,DboNameLevel_term
+    ,DboNameLevel
+    ,DboNameIncreasing_term
+    ,DboNameIncreasing
+    ,DboNameReturnOfPremium_term
+    ,DboNameReturnOfPremium
+    ,DboNameMinDeathBenefit_term
+    ,DboNameMinDeathBenefit
+    ,GenAcctName_term
+    ,GenAcctName
+    ,GenAcctNameElaborated_term
+    ,GenAcctNameElaborated
+    ,SepAcctName_term
+    ,SepAcctName
+    ,SpecAmtName_term
+    ,SpecAmtName
+    ,SpecAmtNameElaborated_term
+    ,SpecAmtNameElaborated
+
+    // Underwriting terms.
+    ,UwBasisMedical_term
+    ,UwBasisMedical
+    ,UwBasisParamedical_term
+    ,UwBasisParamedical
+    ,UwBasisNonmedical_term
+    ,UwBasisNonmedical
+    ,UwBasisSimplified_term
+    ,UwBasisSimplified
+    ,UwBasisGuaranteed_term
+    ,UwBasisGuaranteed
+    ,UwClassPreferred_term
+    ,UwClassPreferred
+    ,UwClassStandard_term
+    ,UwClassStandard
+    ,UwClassRated_term
+    ,UwClassRated
+    ,UwClassUltra_term
+    ,UwClassUltra
+
+    // Ledger column definitions.
+    ,AccountValueFootnote_term
+    ,AccountValueFootnote
+    ,AttainedAgeFootnote_term
+    ,AttainedAgeFootnote
+    ,CashSurrValueFootnote_term
+    ,CashSurrValueFootnote
+    ,DeathBenefitFootnote_term
+    ,DeathBenefitFootnote
+    ,InitialPremiumFootnote_term
+    ,InitialPremiumFootnote
+    ,NetPremiumFootnote_term
+    ,NetPremiumFootnote
+    ,GrossPremiumFootnote_term
+    ,GrossPremiumFootnote
+    ,OutlayFootnote_term
+    ,OutlayFootnote
+    ,PolicyYearFootnote_term
+    ,PolicyYearFootnote
+
+    // Terse rider names.
+    ,ADDTerseName_term
+    ,ADDTerseName
+    ,InsurabilityTerseName_term
+    ,InsurabilityTerseName
+    ,ChildTerseName_term
+    ,ChildTerseName
+    ,SpouseTerseName_term
+    ,SpouseTerseName
+    ,TermTerseName_term
+    ,TermTerseName
+    ,WaiverTerseName_term
+    ,WaiverTerseName
+    ,AccelBftRiderTerseName_term
+    ,AccelBftRiderTerseName
+    ,OverloanRiderTerseName_term
+    ,OverloanRiderTerseName
+
+    // Rider footnotes.
+    ,ADDFootnote_term
+    ,ADDFootnote
+    ,ChildFootnote_term
+    ,ChildFootnote
+    ,SpouseFootnote_term
+    ,SpouseFootnote
+    ,TermFootnote_term
+    ,TermFootnote
+    ,WaiverFootnote_term
+    ,WaiverFootnote
+    ,AccelBftRiderFootnote_term
+    ,AccelBftRiderFootnote
+    ,OverloanRiderFootnote_term
+    ,OverloanRiderFootnote
+
+    // Group quotes.
+    ,GroupQuoteShortProductName_term
+    ,GroupQuoteShortProductName
+    ,GroupQuoteIsNotAnOffer_term
+    ,GroupQuoteIsNotAnOffer
+    ,GroupQuoteRidersFooter_term
+    ,GroupQuoteRidersFooter
+    ,GroupQuotePolicyFormId_term
+    ,GroupQuotePolicyFormId
+    ,GroupQuoteStateVariations_term
+    ,GroupQuoteStateVariations
+    ,GroupQuoteProspectus_term
+    ,GroupQuoteProspectus
+    ,GroupQuoteUnderwriter_term
+    ,GroupQuoteUnderwriter
+    ,GroupQuoteBrokerDealer_term
+    ,GroupQuoteBrokerDealer
+    // Group plan type is one of:
+    //   -Mandatory: no individual selection of amounts; typically,
+    //     the employer pays the entire premium
+    //   -Voluntary: individual selection of amounts; typically, the
+    //      employee pays the premium; may be called "supplemental"
+    //      when it complements a (separate) "mandatory" plan
+    //   -Fusion: mandatory and supplemental combined; typically, the
+    //      employer and employee pay their respective premiums
+    ,GroupQuoteRubricMandatory_term
+    ,GroupQuoteRubricMandatory
+    ,GroupQuoteRubricVoluntary_term
+    ,GroupQuoteRubricVoluntary
+    ,GroupQuoteRubricFusion_term
+    ,GroupQuoteRubricFusion
+    ,GroupQuoteFooterMandatory_term
+    ,GroupQuoteFooterMandatory
+    ,GroupQuoteFooterVoluntary_term
+    ,GroupQuoteFooterVoluntary
+    ,GroupQuoteFooterFusion_term
+    ,GroupQuoteFooterFusion
+
+    // Premium-specific footnotes.
+    ,MinimumPremiumFootnote_term
+    ,MinimumPremiumFootnote
+    ,PremAllocationFootnote_term
+    ,PremAllocationFootnote
+
+    // Miscellaneous other footnotes.
+    ,InterestDisclaimer_term
+    ,InterestDisclaimer
+    ,GuarMortalityFootnote_term
+    ,GuarMortalityFootnote
+    ,ProductDescription_term
+    ,ProductDescription
+    ,StableValueFootnote_term
+    ,StableValueFootnote
+    ,NoVanishPremiumFootnote_term
+    ,NoVanishPremiumFootnote
+    ,RejectPremiumFootnote_term
+    ,RejectPremiumFootnote
+    ,ExpRatingFootnote_term
+    ,ExpRatingFootnote
+    ,MortalityBlendFootnote_term
+    ,MortalityBlendFootnote
+    ,HypotheticalRatesFootnote_term
+    ,HypotheticalRatesFootnote
+    ,SalesLoadRefundFootnote_term
+    ,SalesLoadRefundFootnote
+    ,NoLapseEverFootnote_term
+    ,NoLapseEverFootnote
+    ,NoLapseFootnote_term
+    ,NoLapseFootnote
+    ,CurrentValuesFootnote_term
+    ,CurrentValuesFootnote
+    ,DBOption1Footnote_term
+    ,DBOption1Footnote
+    ,DBOption2Footnote_term
+    ,DBOption2Footnote
+    ,DBOption3Footnote_term
+    ,DBOption3Footnote
+    ,MinDeathBenefitFootnote_term
+    ,MinDeathBenefitFootnote
+    ,ExpRatRiskChargeFootnote_term
+    ,ExpRatRiskChargeFootnote
+    ,ExchangeChargeFootnote1_term
+    ,ExchangeChargeFootnote1
+    ,FlexiblePremiumFootnote_term
+    ,FlexiblePremiumFootnote
+    ,GuaranteedValuesFootnote_term
+    ,GuaranteedValuesFootnote
+    ,CreditingRateFootnote_term
+    ,CreditingRateFootnote
+    ,GrossRateFootnote_term
+    ,GrossRateFootnote
+    ,NetRateFootnote_term
+    ,NetRateFootnote
+    ,MecFootnote_term
+    ,MecFootnote
+    ,GptFootnote_term
+    ,GptFootnote
+    ,MidpointValuesFootnote_term
+    ,MidpointValuesFootnote
+    ,SinglePremiumFootnote_term
+    ,SinglePremiumFootnote
+    ,MonthlyChargesFootnote_term
+    ,MonthlyChargesFootnote
+    ,UltCreditingRateFootnote_term
+    ,UltCreditingRateFootnote
+    ,UltCreditingRateHeader_term
+    ,UltCreditingRateHeader
+    ,MaxNaarFootnote_term
+    ,MaxNaarFootnote
+    ,PremTaxSurrChgFootnote_term
+    ,PremTaxSurrChgFootnote
+    ,PolicyFeeFootnote_term
+    ,PolicyFeeFootnote
+    ,AssetChargeFootnote_term
+    ,AssetChargeFootnote
+    ,InvestmentIncomeFootnote_term
+    ,InvestmentIncomeFootnote
+    ,IrrDbFootnote_term
+    ,IrrDbFootnote
+    ,IrrCsvFootnote_term
+    ,IrrCsvFootnote
+    ,MortalityChargesFootnote_term
+    ,MortalityChargesFootnote
+    ,LoanAndWithdrawalFootnote_term
+    ,LoanAndWithdrawalFootnote
+    ,LoanFootnote_term
+    ,LoanFootnote
+    ,ImprimaturPresale_term
+    ,ImprimaturPresale
+    ,ImprimaturPresaleComposite_term
+    ,ImprimaturPresaleComposite
+    ,ImprimaturInforce_term
+    ,ImprimaturInforce
+    ,ImprimaturInforceComposite_term
+    ,ImprimaturInforceComposite
+    ,StateMarketingImprimatur_term
+    ,StateMarketingImprimatur
+    ,NonGuaranteedFootnote_term
+    ,NonGuaranteedFootnote
+    ,NonGuaranteedFootnote1_term
+    ,NonGuaranteedFootnote1
+    ,NonGuaranteedFootnote1Tx_term
+    ,NonGuaranteedFootnote1Tx
+    ,FnMonthlyDeductions_term
+    ,FnMonthlyDeductions
+    ,SurrenderFootnote_term
+    ,SurrenderFootnote
+    ,PortabilityFootnote_term
+    ,PortabilityFootnote
+    ,FundRateFootnote_term
+    ,FundRateFootnote
+    ,IssuingCompanyFootnote_term
+    ,IssuingCompanyFootnote
+    ,SubsidiaryFootnote_term
+    ,SubsidiaryFootnote
+    ,PlacementAgentFootnote_term
+    ,PlacementAgentFootnote
+    ,MarketingNameFootnote_term
+    ,MarketingNameFootnote
+    ,GuarIssueDisclaimerNcSc_term
+    ,GuarIssueDisclaimerNcSc
+    ,GuarIssueDisclaimerMd_term
+    ,GuarIssueDisclaimerMd
+    ,GuarIssueDisclaimerTx_term
+    ,GuarIssueDisclaimerTx
+    ,IllRegCertAgent_term
+    ,IllRegCertAgent
+    ,IllRegCertAgentIl_term
+    ,IllRegCertAgentIl
+    ,IllRegCertAgentTx_term
+    ,IllRegCertAgentTx
+    ,IllRegCertClient_term
+    ,IllRegCertClient
+    ,IllRegCertClientIl_term
+    ,IllRegCertClientIl
+    ,IllRegCertClientTx_term
+    ,IllRegCertClientTx
+    ,FnMaturityAge_term
+    ,FnMaturityAge
+    ,FnPartialMortality_term
+    ,FnPartialMortality
+    ,FnProspectus_term
+    ,FnProspectus
+    ,FnInitialSpecAmt_term
+    ,FnInitialSpecAmt
+    ,FnInforceAcctVal_term
+    ,FnInforceAcctVal
+    ,FnInforceTaxBasis_term
+    ,FnInforceTaxBasis
+    ,Fn1035Charge_term
+    ,Fn1035Charge
+    ,FnMecExtraWarning_term
+    ,FnMecExtraWarning
+    ,FnNotTaxAdvice_term
+    ,FnNotTaxAdvice
+    ,FnNotTaxAdvice2_term
+    ,FnNotTaxAdvice2
+    ,FnImf_term
+    ,FnImf
+    ,FnCensus_term
+    ,FnCensus
+    ,FnDacTax_term
+    ,FnDacTax
+    ,FnDefnLifeIns_term
+    ,FnDefnLifeIns
+    ,FnBoyEoy_term
+    ,FnBoyEoy
+    ,FnGeneralAccount_term
+    ,FnGeneralAccount
+    ,FnPpMemorandum_term
+    ,FnPpMemorandum
+    ,FnPpAccreditedInvestor_term
+    ,FnPpAccreditedInvestor
+    ,FnPpLoads_term
+    ,FnPpLoads
+    ,FnProposalUnderwriting_term
+    ,FnProposalUnderwriting
+    ,FnGuaranteedPremium_term
+    ,FnGuaranteedPremium
+    ,FnOmnibusDisclaimer_term
+    ,FnOmnibusDisclaimer
+    ,FnInitialDbo_term
+    ,FnInitialDbo
+    ,DefnGuarGenAcctRate_term
+    ,DefnGuarGenAcctRate
+    ,DefnAV_term
+    ,DefnAV
+    ,DefnCSV_term
+    ,DefnCSV
+    ,DefnMec_term
+    ,DefnMec
+    ,DefnOutlay_term
+    ,DefnOutlay
+    ,DefnSpecAmt_term
+    ,DefnSpecAmt
+
+    // Esoterica.
+    ,Poe0
+    ,Poe1
+    ,Poe2
+    ,Poe3
+    };
+} // namespace superior
+
+#endif // sample_hpp
diff --git a/sequence_editor.png b/sequence_editor.png
new file mode 100644
index 0000000..135b009
Binary files /dev/null and b/sequence_editor.png differ
diff --git a/set_toolchain.sh b/set_toolchain.sh
index c45c6ad..f71c5d2 100755
--- a/set_toolchain.sh
+++ b/set_toolchain.sh
@@ -1,6 +1,6 @@
 #!/bin/sh this-script-must-be-sourced-not-run
 
-# Set $PATH, $WINEPATH, and $PERFORM based on $LMI_COMPILER and $LMI_TRIPLET.
+# Set $PATH variants and $PERFORM based on $LMI_COMPILER and $LMI_TRIPLET.
 
 # Copyright (C) 2019, 2020 Gregory W. Chicares.
 #
@@ -27,9 +27,9 @@
 # used in production if they were unset or null beforehand. They can
 # be overridden at the command line, e.g.:
 #
+#   LMI_COMPILER=gcc ; LMI_TRIPLET=x86_64-pc-linux-gnu ; . 
/opt/lmi/src/lmi/set_toolchain.sh
 #   LMI_COMPILER=gcc ; LMI_TRIPLET=i686-w64-mingw32    ; . 
/opt/lmi/src/lmi/set_toolchain.sh
 #   LMI_COMPILER=gcc ; LMI_TRIPLET=x86_64-w64-mingw32  ; . 
/opt/lmi/src/lmi/set_toolchain.sh
-#   LMI_COMPILER=gcc ; LMI_TRIPLET=x86_64-pc-linux-gnu ; . 
/opt/lmi/src/lmi/set_toolchain.sh
 #
 # Implemented as a function that runs and then erases itself, so that
 # sourcing this script changes the environment only as intended. This
@@ -61,8 +61,8 @@
 #
 # Supported values:
 #   LMI_COMPILER : gcc, clang
-#   LMI_TRIPLET  : i686-w64-mingw32, x86_64-w64-mingw32, x86_64-pc-linux-gnu
-# (clang and pc-linux-gnu are not yet tested).
+#   LMI_TRIPLET  : x86_64-pc-linux-gnu, i686-w64-mingw32, x86_64-w64-mingw32
+# (clang not yet tested).
 #
 # Examples:
 #
@@ -86,9 +86,10 @@
 foo()
 {
 local   lmi_build_type
-        lmi_build_type=$(/usr/share/libtool/build-aux/config.guess)
+        lmi_build_type=$(/usr/share/misc/config.guess)
 
 local      prefix="/opt/lmi"
+local      bindir="$prefix/bin"
 local localbindir="$prefix/local/${LMI_COMPILER}_${LMI_TRIPLET}/bin"
 local locallibdir="$prefix/local/${LMI_COMPILER}_${LMI_TRIPLET}/lib"
 
@@ -103,10 +104,11 @@ local 
locallibdir="$prefix/local/${LMI_COMPILER}_${LMI_TRIPLET}/lib"
 minimal_path=${MINIMAL_PATH:-"/usr/bin:/bin:/usr/sbin:/sbin"}
 export PATH="$localbindir":"$locallibdir":"$minimal_path"
 
-# It is okay to export these two variables unconditionally.
+# It is okay to export these variables unconditionally.
 
-export WINEPATH
+export LD_LIBRARY_PATH
 export PERFORM
+export WINEPATH
 
 # Are double quotes inside double quotes inside $() dubious? I.e.,
 #  " $( "is this string quoted?" ) "
@@ -124,10 +126,24 @@ export PERFORM
 #
 case "$lmi_build_type" in
     (*-*-linux*)
-        w0="$(winepath -w "$localbindir" | sed -e's/\\/\\\\/g')"
-        w1="$(winepath -w "$locallibdir" | sed -e's/\\/\\\\/g')"
-        export WINEPATH="$w0;$w1"
-        export  PERFORM="wine"
+        case "$LMI_TRIPLET" in
+            (x86_64-pc-linux-gnu)
+                # Using LD_LIBRARY_PATH is not ideal, but it does work.
+                LD_LIBRARY_PATH=.
+                LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$locallibdir"
+                LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$bindir"
+                # Nullify any leftover "wine" value.
+                PERFORM=
+                ;;
+            (*-*-mingw32)
+                # Nullify any leftover value from the native case above.
+                LD_LIBRARY_PATH=
+                PERFORM="wine"
+                w0="$(winepath -w "$localbindir" | sed -e's/\\/\\\\/g')"
+                w1="$(winepath -w "$locallibdir" | sed -e's/\\/\\\\/g')"
+                WINEPATH="$w0;$w1"
+                ;;
+        esac
         ;;
     (*) ;;
 esac
@@ -150,9 +166,9 @@ case "$LMI_COMPILER" in
 esac
 
 case "$LMI_TRIPLET" in
+    (x86_64-pc-linux-gnu) ;;
     (i686-w64-mingw32)    ;;
     (x86_64-w64-mingw32)  ;;
-    (x86_64-pc-linux-gnu) printf '%s\n' "GUI build not yet supported." > 
/dev/tty ;;
     (*)
         printf '%s\n' "Changed nothing because host triplet '$LMI_TRIPLET' is 
untested."
         return 3;
diff --git a/sigfpe.hpp b/sigfpe.hpp
index f42d132..12a1cac 100644
--- a/sigfpe.hpp
+++ b/sigfpe.hpp
@@ -26,9 +26,9 @@
 
 #include "so_attributes.hpp"
 
-void LMI_SO floating_point_error_handler(int);
+LMI_SO void floating_point_error_handler(int);
 
 // TODO ?? Make the unit test a separate module.
-void LMI_SO fpe_handler_test();
+LMI_SO void fpe_handler_test();
 
 #endif // sigfpe_hpp
diff --git a/skeleton.cpp b/skeleton.cpp
index 4686fb0..e344dc2 100644
--- a/skeleton.cpp
+++ b/skeleton.cpp
@@ -54,7 +54,7 @@
 #include "global_settings.hpp"
 #include "gpt_document.hpp"
 #include "gpt_view.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "icon_monger.hpp"
 #include "illustration_document.hpp"
 #include "illustration_view.hpp"
@@ -338,7 +338,8 @@ void Skeleton::InitDocManager()
         ,CLASSINFO(DatabaseView)
         );
 
-    // Apparently there's no way to edit a '.funds' file.
+    // There is intentionally no GUI editor for '.lingo' files.
+    // There's no GUI editor for '.funds' files either.
 
     new(wx) wxDocTemplate
         (doc_manager_
diff --git a/so_attributes.hpp b/so_attributes.hpp
index b8511df..50df5d4 100644
--- a/so_attributes.hpp
+++ b/so_attributes.hpp
@@ -108,27 +108,27 @@
 
 // Forward declaration macro.
 //
-// In general,
+// If a class defined with an attribute chosen by a macro:
 //   class ATTRIB foo {}
-// can be forward declared thus:
+// is to be forward declared, should the forward declaration specify
+// the attribute macro, or not? For some ancient msw compilers, this:
 //   class ATTRIB foo;
-// That worked for MinGW up to gcc-3.4.5; for MinGW-w64 gcc-4.9.1, it
-// elicits a warning, and ATTRIB must be dropped from the forward
-// declaration. No knowledge is claimed of the behavior of gcc
-// versions between these two, which lmi did not use. It is unknown
-// whether this difference represents deliberate evolution of gcc or
-// a MinGW-w64 regression, so both versions are preserved.
+// was apparently required, and it was accepted by mingw.org gcc up
+// to version 3.4.5 at least. However, for MinGW-w64 gcc since at
+// least version 4.9.1, it elicits a warning, and ATTRIB must be
+// dropped from the forward declaration, thus:
+//   class foo;
+// Here, the latter form is used by default, and the former form is
+// preserved in case it's ever needed again (below, with a jocular
+// conditional evoking ancient tools). See:
+//   https://lists.nongnu.org/archive/html/lmi/2020-10/msg00097.html
 
 #if defined LMI_USE_SO_ATTRIBUTES
-#   if defined __GNUC__
-#       if defined LMI_MINGW_W64
-#           define LMI_SO_FWD_DECL
-#       else  // !defined LMI_MINGW_W64
-#           define LMI_SO_FWD_DECL LMI_SO
-#       endif // !defined LMI_MINGW_W64
-#   else  // !defined __GNUC__
+#   if defined __BORLANDC__
 #       define LMI_SO_FWD_DECL LMI_SO
-#   endif // !defined __GNUC__
+#   else  // !defined __BORLANDC__
+#       define LMI_SO_FWD_DECL
+#   endif // !defined __BORLANDC__
 #else  // !defined LMI_USE_SO_ATTRIBUTES
 #   define LMI_SO_FWD_DECL
 #endif // !defined LMI_USE_SO_ATTRIBUTES
diff --git a/stratified_charges.hpp b/stratified_charges.hpp
index 071751c..6b91abb 100644
--- a/stratified_charges.hpp
+++ b/stratified_charges.hpp
@@ -208,11 +208,11 @@ class LMI_SO stratified_charges final
     stratified_entity TieredSDPremTax;
 };
 
-void LMI_SO load(stratified_charges      &, fs::path const&);
-void LMI_SO save(stratified_charges const&, fs::path const&);
+LMI_SO void load(stratified_charges      &, fs::path const&);
+LMI_SO void save(stratified_charges const&, fs::path const&);
 
-stratified_entity const& LMI_SO StatutoryAKPremTax();
-stratified_entity const& LMI_SO StatutoryDEPremTax();
-stratified_entity const& LMI_SO StatutorySDPremTax();
+LMI_SO stratified_entity const& StatutoryAKPremTax();
+LMI_SO stratified_entity const& StatutoryDEPremTax();
+LMI_SO stratified_entity const& StatutorySDPremTax();
 
 #endif // stratified_charges_hpp
diff --git a/stream_cast.hpp b/stream_cast.hpp
index e57d689..ddb4ebd 100644
--- a/stream_cast.hpp
+++ b/stream_cast.hpp
@@ -99,10 +99,10 @@ template<typename To, typename From>
 To stream_cast(From from, To = To())
 {
     static_assert
-        (   !std::is_arithmetic<From>::value
-        ||  !std::is_arithmetic<To  >::value
+        (   !std::is_arithmetic_v<From>
+        ||  !std::is_arithmetic_v<To  >
         );
-    static_assert(!std::is_pointer<To>::value);
+    static_assert(!std::is_pointer_v<To>);
 
     auto complain = [&](auto const& reason)
         {
diff --git a/system_command.hpp b/system_command.hpp
index d43fabb..e767f5a 100644
--- a/system_command.hpp
+++ b/system_command.hpp
@@ -30,7 +30,7 @@
 
 typedef void (*system_command_fp_type)(std::string const&);
 
-bool LMI_SO system_command_initialize(system_command_fp_type);
+LMI_SO bool system_command_initialize(system_command_fp_type);
 
 /// Wrapper for std::system() that throws on failure.
 ///
@@ -66,6 +66,6 @@ bool LMI_SO system_command_initialize(system_command_fp_type);
 /// that platform: it just makes it do what a posix platform would do
 /// without such complicated workarounds.
 
-void LMI_SO system_command(std::string const& command_line);
+LMI_SO void system_command(std::string const& command_line);
 
 #endif // system_command_hpp
diff --git a/test_coding_rules.cpp b/test_coding_rules.cpp
index 85b8d68..4b3bc13 100644
--- a/test_coding_rules.cpp
+++ b/test_coding_rules.cpp
@@ -22,7 +22,7 @@
 #include "assert_lmi.hpp"
 #include "boost_regex.hpp"
 #include "contains.hpp"
-#include "handle_exceptions.hpp"
+#include "handle_exceptions.hpp"        // report_exception()
 #include "istream_to_string.hpp"
 #include "main_common.hpp"
 #include "miscellany.hpp"               // begins_with(), split_into_lines()
@@ -194,6 +194,7 @@ file::file(std::string const& file_path)
         : ".inix"       == extension() ? e_xml_input
         : ".database"   == extension() ? e_xml_other
         : ".funds"      == extension() ? e_xml_other
+        : ".lingo"      == extension() ? e_xml_other
         : ".policy"     == extension() ? e_xml_other
         : ".rounding"   == extension() ? e_xml_other
         : ".strata"     == extension() ? e_xml_other
@@ -201,8 +202,9 @@ file::file(std::string const& file_path)
         : ".xrc"        == extension() ? e_xml_other
         : ".xsd"        == extension() ? e_xml_other
         : ".xsl"        == extension() ? e_xml_other
-        // phyloanalyze() tests inspect only file name
+        // phyloanalyze() tests inspect only file name [sort by enumerator]
         : phyloanalyze("^ChangeLog-")  ? e_binary
+        : phyloanalyze("^Speed_")      ? e_binary
         : phyloanalyze("^tags$")       ? e_expungible
         : phyloanalyze("^COPYING$")    ? e_gpl
         : phyloanalyze("^quoted_gpl")  ? e_gpl
@@ -714,6 +716,7 @@ void check_defect_markers(file const& f)
             &&  "IHS "         != z[1]
             &&  "INELEGANT "   != z[1]
             &&  "INPUT "       != z[1]
+            &&  "LINGO "       != z[1]
             &&  "MD5 "         != z[1]
             &&  "PDF "         != z[1]
             &&  "PORT "        != z[1]
diff --git a/test_coding_rules_test.sh b/test_coding_rules_test.sh
index 35ae0b2..d3fa399 100755
--- a/test_coding_rules_test.sh
+++ b/test_coding_rules_test.sh
@@ -29,6 +29,15 @@
 
 echo "Testing 'test_coding_rules'."
 
+# Directory where this script resides.
+
+srcdir=$(dirname "$(readlink --canonicalize "$0")")
+
+# Cannot recursively check script on path determined at runtime, so
+# a directive like 'source="$srcdir"' doesn't work.
+# shellcheck disable=SC1090
+. "$srcdir"/set_toolchain.sh
+
 rm --force eraseme*
 
 # Boilerplate required in most files.
@@ -371,16 +380,6 @@ touch another.unexpected.file
 
 # Compare observed to expected. Note that directory '.' is ignored.
 
-lmi_build_type=$(/usr/share/libtool/build-aux/config.guess)
-case "$lmi_build_type" in
-    (*-*-linux*)
-        PERFORM=wine
-        ;;
-    (*)
-        PERFORM=
-        ;;
-esac
-
 2>&1 $PERFORM ./test_coding_rules \
   . \
   a_nonexistent_file \
diff --git a/third_party/libxml2 b/third_party/libxml2
index bdec218..0b3c64d 160000
--- a/third_party/libxml2
+++ b/third_party/libxml2
@@ -1 +1 @@
-Subproject commit bdec2183f34b37ee89ae1d330c6ad2bb4d76605f
+Subproject commit 0b3c64d9f2f3e9ce1a98d8f19ee7a763c87e27d5
diff --git a/third_party/wx b/third_party/wx
new file mode 160000
index 0000000..6cdaedd
--- /dev/null
+++ b/third_party/wx
@@ -0,0 +1 @@
+Subproject commit 6cdaedd42ba59331b3dc4ead50e0bac76ae14c19
diff --git a/third_party/wxpdfdoc b/third_party/wxpdfdoc
new file mode 160000
index 0000000..1839b23
--- /dev/null
+++ b/third_party/wxpdfdoc
@@ -0,0 +1 @@
+Subproject commit 1839b231c5138edd40b752272631e2f1d5311456
diff --git a/third_party/xmlwrapp b/third_party/xmlwrapp
new file mode 160000
index 0000000..efb0542
--- /dev/null
+++ b/third_party/xmlwrapp
@@ -0,0 +1 @@
+Subproject commit efb0542106cee71ab17caae1f9b77ed7a56a6eb4
diff --git a/tn_range.hpp b/tn_range.hpp
index 1a14a5a..43ecb92 100644
--- a/tn_range.hpp
+++ b/tn_range.hpp
@@ -229,7 +229,7 @@ template<typename Number, typename Trammel>
 class tn_range final
     :public tn_range_base
 {
-    static_assert(std::is_base_of<trammel_base<Number>,Trammel>::value);
+    static_assert(std::is_base_of_v<trammel_base<Number>,Trammel>);
 
     friend class tn_range_test;
 
diff --git a/tn_range.tpp b/tn_range.tpp
index d4367d7..59661aa 100644
--- a/tn_range.tpp
+++ b/tn_range.tpp
@@ -30,6 +30,7 @@
 #include <limits>
 #include <ostream>
 #include <sstream>
+#include <type_traits>
 
 namespace
 {
@@ -53,7 +54,7 @@ namespace
     template
         <typename T
         ,bool=std::numeric_limits<T>::is_specialized
-        ,bool=std::is_floating_point<T>::value
+        ,bool=std::is_floating_point_v<T>
         >
     struct strictly_between_extrema_tester
     {};
@@ -108,7 +109,7 @@ namespace
     template<typename T>
     T signum(T t)
     {
-        static_assert(std::is_arithmetic<T>::value);
+        static_assert(std::is_arithmetic_v<T>);
         return (0 == t) ? 0 : std::signbit(t) ? -1 : 1;
     }
 
@@ -166,7 +167,7 @@ namespace
     ///   http://groups.google.com/groups?th=1b868327b241fb74
     ///   http://groups.google.com/groups?selm=3DF66B8D.F1C3D2C0%40sun.com
 
-    template<typename T, bool=std::is_floating_point<T>::value>
+    template<typename T, bool=std::is_floating_point_v<T>>
     struct is_exact_integer_tester
     {};
 
@@ -179,7 +180,7 @@ namespace
     template<typename T>
     struct is_exact_integer_tester<T,true>
     {
-        static_assert(std::is_floating_point<T>::value);
+        static_assert(std::is_floating_point_v<T>);
         bool operator()(T t)
             {
             // SOMEDAY !! nonstd::power() [SGI extension] may be
@@ -218,7 +219,7 @@ namespace
     template<typename T>
     T adjust_bound(T t, T direction)
     {
-        static_assert(std::is_floating_point<T>::value);
+        static_assert(std::is_floating_point_v<T>);
         if(is_exact_integer(t))
             {
             return t;
@@ -261,7 +262,7 @@ namespace
     template<typename T>
     struct bound_adjuster<T,-1>
     {
-        static_assert(std::is_floating_point<T>::value);
+        static_assert(std::is_floating_point_v<T>);
         T operator()(T t)
             {
             static T const extremum = -std::numeric_limits<T>::max();
@@ -272,7 +273,7 @@ namespace
     template<typename T>
     struct bound_adjuster<T,1>
     {
-        static_assert(std::is_floating_point<T>::value);
+        static_assert(std::is_floating_point_v<T>);
         T operator()(T t)
             {
             static T const extremum = std::numeric_limits<T>::max();
@@ -283,13 +284,13 @@ namespace
     template<typename T>
     T adjust_minimum(T t)
     {
-        return bound_adjuster<T,std::is_floating_point<T>::value ? -1 : 
0>()(t);
+        return bound_adjuster<T,std::is_floating_point_v<T> ? -1 : 0>()(t);
     }
 
     template<typename T>
     T adjust_maximum(T t)
     {
-        return bound_adjuster<T,std::is_floating_point<T>::value ? 1 : 0>()(t);
+        return bound_adjuster<T,std::is_floating_point_v<T> ? 1 : 0>()(t);
     }
 } // Unnamed namespace.
 
diff --git a/tn_range_test.cpp b/tn_range_test.cpp
index 80198fa..5254bc4 100644
--- a/tn_range_test.cpp
+++ b/tn_range_test.cpp
@@ -138,7 +138,7 @@ void tn_range_test::test_auxiliary_functions(char const* 
file, int line)
     T const minT = std::numeric_limits<T>::lowest();
 
     INVOKE_BOOST_TEST(!is_strictly_between_extrema(maxT), file, line);
-    if(!std::is_same<bool,typename std::remove_cv<T>::type>::value)
+    if(!std::is_same_v<bool,typename std::remove_cv<T>::type>)
         {
         INVOKE_BOOST_TEST( is_strictly_between_extrema<T>(1), file, line);
         }
diff --git a/tn_range_type_trammels.hpp b/tn_range_type_trammels.hpp
index 76dd1a0..2b301a4 100644
--- a/tn_range_type_trammels.hpp
+++ b/tn_range_type_trammels.hpp
@@ -109,7 +109,7 @@ template<typename T>
 class date_trammel
     :public trammel_base<T>
 {
-    static_assert(std::is_same<calendar_date,T>::value);
+    static_assert(std::is_same_v<calendar_date,T>);
 
     T nominal_minimum() const override {return gregorian_epoch();}
     T default_value()   const override {return today          ();}
diff --git a/tools/pete-2.1.1/Makefile b/tools/pete-2.1.1/Makefile
index 9037e14..b8dfaa4 100644
--- a/tools/pete-2.1.1/Makefile
+++ b/tools/pete-2.1.1/Makefile
@@ -21,7 +21,7 @@
 
 
################################################################################
 
-lmi_build_type := $(shell /usr/share/libtool/build-aux/config.guess)
+lmi_build_type := $(shell /usr/share/misc/config.guess)
 
 EXEEXT :=
 ifeq (cygwin,$(findstring cygwin,$(lmi_build_type)))
diff --git a/transume_toolchain.sh b/transume_toolchain.sh
index 672bda1..4980544 100755
--- a/transume_toolchain.sh
+++ b/transume_toolchain.sh
@@ -23,10 +23,16 @@
 
 # See 'GNUmakefile' for suggested use.
 
-. ./set_toolchain.sh
+# Directory where this script resides.
 
-printf '%s\n' "export LMI_COMPILER := $LMI_COMPILER"
-printf '%s\n' "export LMI_TRIPLET  := $LMI_TRIPLET"
-printf '%s\n' "export PATH         := $PATH"
-printf '%s\n' "export WINEPATH     := $WINEPATH"
-printf '%s\n' "export PERFORM      := $PERFORM"
+srcdir=$(dirname "$(readlink --canonicalize "$0")")
+
+# shellcheck disable=SC1090
+. "$srcdir"/set_toolchain.sh
+
+printf '%s\n' "export LMI_COMPILER    := $LMI_COMPILER"
+printf '%s\n' "export LMI_TRIPLET     := $LMI_TRIPLET"
+printf '%s\n' "export PATH            := $PATH"
+printf '%s\n' "export WINEPATH        := $WINEPATH"
+printf '%s\n' "export PERFORM         := $PERFORM"
+printf '%s\n' "export LD_LIBRARY_PATH := $LD_LIBRARY_PATH"
diff --git a/value_cast.hpp b/value_cast.hpp
index 5a6927a..39f291b 100644
--- a/value_cast.hpp
+++ b/value_cast.hpp
@@ -121,10 +121,13 @@ template<typename T>
 struct is_string
 {
     // Here, is_convertible means 'T' is convertible to std::string.
-    enum {value = std::is_convertible<T,std::string>::value};
+    enum {value = std::is_convertible_v<T,std::string>};
 };
 
 template<typename T>
+inline constexpr bool is_string_v = is_string<T>::value;
+
+template<typename T>
 void throw_if_null_pointer(T)
 {
 }
@@ -162,23 +165,23 @@ struct value_cast_choice
         {
         // Here, is_convertible means 'From' is convertible to 'To'.
         felicitously_convertible =
-                std::is_convertible<From,To>::value
-            &&!(std::is_array   <From>::value && std::is_same<bool,To>::value)
-            &&!(std::is_pointer <From>::value && std::is_same<bool,To>::value)
+                std::is_convertible_v<From,To>
+            &&!(std::is_array_v  <From> && std::is_same_v<bool,To>)
+            &&!(std::is_pointer_v<From> && std::is_same_v<bool,To>)
         };
 
     enum
         {
         both_numeric =
-                std::is_arithmetic<From>::value
-            &&  std::is_arithmetic<To  >::value
+                std::is_arithmetic_v<From>
+            &&  std::is_arithmetic_v<To  >
         };
 
     enum
         {
         one_numeric_one_string =
-                std::is_arithmetic<From>::value && is_string<To  >::value
-            ||  std::is_arithmetic<To  >::value && is_string<From>::value
+                std::is_arithmetic_v<From> && is_string_v<To  >
+            ||  std::is_arithmetic_v<To  > && is_string_v<From>
         };
 
     enum
@@ -229,7 +232,7 @@ struct value_cast_chooser<To,From,e_stream>
 template<typename To, typename From>
 To value_cast(From const& from)
 {
-    static_assert(!std::is_pointer<To>::value);
+    static_assert(!std::is_pointer_v<To>);
     return value_cast_chooser<To,From>()(from);
 }
 
diff --git a/value_cast_test.cpp b/value_cast_test.cpp
index 961b3b6..a158d79 100644
--- a/value_cast_test.cpp
+++ b/value_cast_test.cpp
@@ -59,20 +59,20 @@ int test_main(int, char*[])
     // These could be static assertions, but any failure would prevent
     // other tests from running.
 
-    BOOST_TEST( is_string<char               *>::value);
-    BOOST_TEST( is_string<char const         *>::value);
-    BOOST_TEST(!is_string<char       volatile*>::value);
-    BOOST_TEST(!is_string<char const volatile*>::value);
-
-    BOOST_TEST( is_string<std::string                >::value);
-    BOOST_TEST( is_string<std::string const          >::value);
-    BOOST_TEST(!is_string<std::string       volatile >::value);
-    BOOST_TEST(!is_string<std::string const volatile >::value);
-
-    BOOST_TEST( is_string<std::string               &>::value);
-    BOOST_TEST( is_string<std::string const         &>::value);
-    BOOST_TEST(!is_string<std::string       volatile&>::value);
-    BOOST_TEST(!is_string<std::string const volatile&>::value);
+    BOOST_TEST( is_string_v<char               *>);
+    BOOST_TEST( is_string_v<char const         *>);
+    BOOST_TEST(!is_string_v<char       volatile*>);
+    BOOST_TEST(!is_string_v<char const volatile*>);
+
+    BOOST_TEST( is_string_v<std::string                >);
+    BOOST_TEST( is_string_v<std::string const          >);
+    BOOST_TEST(!is_string_v<std::string       volatile >);
+    BOOST_TEST(!is_string_v<std::string const volatile >);
+
+    BOOST_TEST( is_string_v<std::string               &>);
+    BOOST_TEST( is_string_v<std::string const         &>);
+    BOOST_TEST(!is_string_v<std::string       volatile&>);
+    BOOST_TEST(!is_string_v<std::string const volatile&>);
 
     char const* ccp = "2.71828";
     char* cp = const_cast<char*>("3.14159");
diff --git a/verify_products.hpp b/verify_products.hpp
index 3d3d1ac..4160220 100644
--- a/verify_products.hpp
+++ b/verify_products.hpp
@@ -26,6 +26,6 @@
 
 #include "so_attributes.hpp"
 
-void LMI_SO verify_products();
+LMI_SO void verify_products();
 
 #endif // verify_products_hpp
diff --git a/version.hpp b/version.hpp
index f1b1803..c3807fd 100644
--- a/version.hpp
+++ b/version.hpp
@@ -22,6 +22,6 @@
 
 #include "config.hpp"
 
-#define LMI_VERSION "20200820T1333Z"
+#define LMI_VERSION "20201201T2250Z"
 
 #endif // version_hpp
diff --git a/view_ex.tpp b/view_ex.tpp
index 59b145a..19cdf8d 100644
--- a/view_ex.tpp
+++ b/view_ex.tpp
@@ -49,7 +49,7 @@
 template<typename ViewType>
 std::string ViewName()
 {
-    static_assert(std::is_base_of<wxView,ViewType>::value);
+    static_assert(std::is_base_of_v<wxView,ViewType>);
     return lmi::TypeInfo(typeid(ViewType)).Name();
 }
 
diff --git a/workhorse.make b/workhorse.make
index 43ff2f9..b45ffbc 100644
--- a/workhorse.make
+++ b/workhorse.make
@@ -153,6 +153,7 @@ else ifeq (4.9.2,$(gnu_cpp_version))
 else ifeq (6.3.0,$(gnu_cpp_version))
 else ifeq (7.2.0,$(gnu_cpp_version))
 else ifeq (7.3.0,$(gnu_cpp_version))
+else ifeq (8,$(gnu_cpp_version))
 else ifeq (8.1.0,$(gnu_cpp_version))
 else ifeq (8.2.0,$(gnu_cpp_version))
 else ifeq (8.3.0,$(gnu_cpp_version))
@@ -171,12 +172,13 @@ else ifeq (4.9.2,$(gnu_cxx_version))
 else ifeq (6.3.0,$(gnu_cxx_version))
 else ifeq (7.2.0,$(gnu_cxx_version))
 else ifeq (7.3.0,$(gnu_cxx_version))
+else ifeq (8,$(gnu_cxx_version))
 else ifeq (8.1.0,$(gnu_cxx_version))
 else ifeq (8.2.0,$(gnu_cxx_version))
 else ifeq (8.3.0,$(gnu_cxx_version))
 else ifeq (9,$(gnu_cxx_version))
 else ifeq (9.3.0,$(gnu_cxx_version))
-else ifeq (10,$(gnu_cpp_version))
+else ifeq (10,$(gnu_cxx_version))
 else ifeq (10.0,$(gnu_cxx_version))
 else
   $(warning Untested $(GNU_CXX) version '$(gnu_cxx_version)')
@@ -184,6 +186,21 @@ endif
 
 
################################################################################
 
+# xml library settings.
+
+# Flags for all other xml libraries are provided by *-config scripts,
+# but '-lexslt' is a special case--see:
+#   https://mail.gnome.org/archives/xslt/2001-October/msg00133.html
+#   https://lists.nongnu.org/archive/html/lmi/2020-10/msg00066.html
+
+xml_libraries := \
+  $(shell xmlwrapp-config --libs) \
+  -lexslt \
+  $(shell xslt-config --libs) \
+  $(shell xml2-config --libs) \
+
+################################################################################
+
 # wx settings.
 
 wx_dir := $(localbindir)
@@ -303,7 +320,6 @@ lmi_include_directories := \
   $(srcdir) \
   $(srcdir)/tools/pete-2.1.1 \
   $(overriding_include_directories) \
-  /opt/lmi/third_party/src \
 
 sys_include_directories := \
   $(compiler_include_directory) \
@@ -418,16 +434,18 @@ else ifneq (,$(filter $(gcc_version), 7.2.0 7.3.0))
   gcc_version_specific_warnings := \
 
   cxx_standard := -fno-ms-extensions -frounding-math -std=c++17
-else ifneq (,$(filter $(gcc_version), 8.1.0 8.2.0 8.3.0 9.3.0 10.0))
+else ifneq (,$(filter $(gcc_version), 8 8.1.0 8.2.0 8.3.0 9 9.3.0 10 10.0))
   gcc_version_specific_warnings := \
 
   ifeq (x86_64-w64-mingw32,$(findstring x86_64-w64-mingw32,$(LMI_TRIPLET)))
 # See:
 #   https://lists.nongnu.org/archive/html/lmi/2019-03/msg00026.html
+#   https://lists.nongnu.org/archive/html/lmi/2020-12/msg00000.html
+#   https://lists.nongnu.org/archive/html/lmi/2020-12/msg00002.html
     tutelary_flag := -fomit-frame-pointer
   endif
 
-  ifneq (,$(filter $(gcc_version), 10.0))
+  ifneq (,$(filter $(gcc_version), 10 10.0))
     gcc_cxx_warnings += -Wredundant-tags -Wvolatile
   endif
 
@@ -574,6 +592,7 @@ $(boost_regex_objects): gcc_common_extra_warnings += \
   -Wno-shadow \
   -Wno-switch-enum \
   -Wno-unused-macros \
+  -Wno-unused-result \
   -Wno-useless-cast \
   -Wno-zero-as-null-pointer-constant \
 
@@ -740,8 +759,7 @@ $(product_file_sources): tutelary_flag += 
$(product_file_flags)
 
 REQUIRED_LIBS := \
   $(platform_boost_libraries) \
-  $(platform_xmlwrapp_libraries) \
-  $(platform_gnome_xml_libraries) \
+  $(xml_libraries) \
 
 wx_ldflags = \
   $(wx_library_paths) $(wx_libraries) \
@@ -810,7 +828,9 @@ ifeq (3.4.5,$(gcc_version))
 endif
 
 ifneq (,$(USE_SO_ATTRIBUTES))
-  LDFLAGS += -Wl,--disable-auto-import -static-libstdc++
+  ifeq (mingw32,$(findstring mingw32,$(LMI_TRIPLET)))
+    LDFLAGS += -Wl,--disable-auto-import -static-libstdc++
+  endif
   actually_used_lmi_so_attributes = -DLMI_USE_SO_ATTRIBUTES 
$(lmi_so_attributes)
 endif
 
@@ -1078,6 +1098,7 @@ shared_data_files = \
   sample.dat \
   sample*.database \
   sample*.funds \
+  sample*.lingo \
   sample.ndx \
   sample*.policy \
   sample*.rounding \
@@ -1188,7 +1209,7 @@ extra_fardel_checksummed_files = \
 
 fardel_checksummed_files = \
   $(extra_fardel_checksummed_files) \
-  *.dat *.database *.funds *.ndx *.policy *.rounding *.strata *.xst \
+  *.dat *.database *.funds *.lingo *.ndx *.policy *.rounding *.strata *.xst \
   expiry \
   lmi_md5sum$(EXEEXT) \
 
@@ -1330,6 +1351,11 @@ cli_selftest:
        @$(PERFORM) ./lmi_cli_shared$(EXEEXT) $(self_test_options) > /dev/null
        @$(PERFORM) ./lmi_cli_shared$(EXEEXT) $(self_test_options)
 
+.PHONY: cli_timing
+cli_timing: lmi_cli_shared$(EXEEXT)
+       @$(PERFORM) ./lmi_cli_shared$(EXEEXT) $(self_test_options) \
+         >$(srcdir)/Speed_$(LMI_COMPILER)_$(LMI_TRIPLET)
+
 cli_test-sample.ill: special_emission :=
 cli_test-sample.cns: special_emission := emit_composite_only
 
@@ -1571,6 +1597,16 @@ clean_edg:
 
 
################################################################################
 
+# Report gcc version.
+#
+# Intended for use in shell scripts thus:
+#   gcc_version=$(make show_gcc_version)
+# so no newline is printed.
+
+.PHONY: show_gcc_version
+show_gcc_version:
+       @printf "$(gcc_version)"
+
 # Display selected variables.
 
 .PHONY: show_flags
diff --git a/wx_utility.hpp b/wx_utility.hpp
index b669ec2..b7870d0 100644
--- a/wx_utility.hpp
+++ b/wx_utility.hpp
@@ -95,10 +95,10 @@ void Connect
     ,wxEvtHandler*   event_sink = nullptr
     )
 {
-    static_assert(std::is_same<void,Return>::value);
-    static_assert(std::is_base_of<wxEvtHandler,Class>::value);
+    static_assert(std::is_same_v<void,Return>);
+    static_assert(std::is_base_of_v<wxEvtHandler,Class>);
     typedef typename std::remove_reference<Argument>::type argument_type;
-    static_assert(std::is_base_of<wxEvent,argument_type>::value);
+    static_assert(std::is_base_of_v<wxEvent,argument_type>);
 
     if(!object)
         {
diff --git a/xml_serializable.tpp b/xml_serializable.tpp
index 7eba420..c71060b 100644
--- a/xml_serializable.tpp
+++ b/xml_serializable.tpp
@@ -43,8 +43,8 @@ xml_serializable<T>::~xml_serializable()
     // Assert that static_cast<T cv&> doesn't engender undefined
     // behavior, and that class T provides the expected operator[]()
     // and member_names() functions.
-    static_assert(std::is_base_of<xml_serializable <T>,T>::value);
-    static_assert(std::is_base_of<MemberSymbolTable<T>,T>::value);
+    static_assert(std::is_base_of_v<xml_serializable <T>,T>);
+    static_assert(std::is_base_of_v<MemberSymbolTable<T>,T>);
 }
 
 template<typename T>
@@ -187,7 +187,7 @@ void xml_serializable<T>::immit_members_into(xml::element& 
root) const
 template<typename X, typename Y>
 inline Y sfinae_cast
     (X const& x
-    ,typename std::enable_if<std::is_same<X,Y>::value>::type* = nullptr
+    ,typename std::enable_if<std::is_same_v<X,Y>>::type* = nullptr
     )
 {
     return x;
@@ -196,7 +196,7 @@ inline Y sfinae_cast
 template<typename X, typename Y>
 inline Y sfinae_cast
     (X const&
-    ,typename std::enable_if<!std::is_same<X,Y>::value>::type* = nullptr
+    ,typename std::enable_if<!std::is_same_v<X,Y>>::type* = nullptr
     )
 {
     alarum() << "Impermissible type conversion." << LMI_FLUSH;
diff --git a/xml_serialize.hpp b/xml_serialize.hpp
index cbfacbc..7bfe608 100644
--- a/xml_serialize.hpp
+++ b/xml_serialize.hpp
@@ -25,13 +25,17 @@
 #include "config.hpp"
 
 #include "assert_lmi.hpp"
+#include "ssize_lmi.hpp"
 #include "value_cast.hpp"
 #include "xml_lmi.hpp"
 
 #include <xmlwrapp/nodes_view.h>
 
+#include <map>
 #include <string>
 #include <type_traits>
+#include <unordered_map>
+#include <utility>                      // pair
 #include <vector>
 
 /// Serialization to and from xml.
@@ -56,8 +60,6 @@ namespace xml_serialize
 template<typename T>
 struct xml_io
 {
-    static_assert(!std::is_enum<T>::value); // Prefer mc_enum.
-
     static void to_xml(xml::element& e, T const& t)
     {
         e.set_text_content(value_cast<std::string>(t).c_str());
@@ -69,7 +71,49 @@ struct xml_io
     }
 };
 
-/// Serialization for sequences [23.1.1].
+/// Serialization for std::pair.
+
+template<typename P>
+struct xml_pair_io
+{
+    using T1 = typename P::first_type;
+    using T2 = typename P::second_type;
+
+    static_assert(std::is_same_v<P,std::pair<T1,T2>>);
+
+    static void to_xml(xml::element& parent, P const& p)
+    {
+        parent.clear();
+
+        // This is equivalent to calling set_element(), except that
+        // the parent element has imperatively been cleared.
+        xml::element e1("first");
+        xml_io<T1>::to_xml(e1, p.first);
+        parent.push_back(e1);
+
+        xml::element e2("second");
+        xml_io<T2>::to_xml(e2, p.second);
+        parent.push_back(e2);
+    }
+
+    static void from_xml(xml::element const& parent, P& p)
+    {
+        auto const& view_first {parent.elements("first")};
+        LMI_ASSERT(1 == lmi::ssize(view_first));
+        xml_io<T1>::from_xml(*view_first.begin(), p.first);
+
+        auto const& view_second {parent.elements("second")};
+        LMI_ASSERT(1 == lmi::ssize(view_second));
+        xml_io<T2>::from_xml(*view_second.begin(), p.second);
+    }
+};
+
+template<typename T1, typename T2>
+struct xml_io<std::pair<T1,T2>>
+  :public xml_pair_io<std::pair<T1,T2>>
+{};
+
+/// Serialization for sequence containers.
 ///
 /// Derive publicly from this to use its implementation when
 /// specializing class template xml_io for a particular sequence.
@@ -78,36 +122,37 @@ struct xml_io
 /// (and non-element nodes) that might have been added manually,
 /// e.g., as documentation.
 ///
-/// C++11 has no way to assert that T is a Sequence; for the nonce,
-/// no other Sequence being used, assert that it's a vector.
+/// C++17 has no assertable "SequenceContainer" concept; for the
+/// nonce, no other Sequence being used, assert that C is a vector.
 
-template<typename T>
+template<typename C>
 struct xml_sequence_io
 {
-    typedef typename T::value_type item_t;
-    static_assert(std::is_same<T,std::vector<item_t>>::value);
+    using T = typename C::value_type;
 
-    static void to_xml(xml::element& e, T const& t)
+    static_assert(std::is_same_v<C,std::vector<T>>);
+
+    static void to_xml(xml::element& parent, C const& c)
     {
-        e.clear();
-        for(auto const& i : t)
+        parent.clear();
+        for(auto const& i : c)
             {
             // This is not equivalent to calling set_element():
             // multiple <item> elements are expressly permitted.
-            xml::element z("item");
-            xml_io<item_t>::to_xml(z, i);
-            e.push_back(z);
+            xml::element e("item");
+            xml_io<T>::to_xml(e, i);
+            parent.push_back(e);
             }
     }
 
-    static void from_xml(xml::element const& e, T& t)
+    static void from_xml(xml::element const& parent, C& c)
     {
-        t.clear();
-        for(auto const& i : e.elements("item"))
+        c.clear();
+        for(auto const& i : parent.elements("item"))
             {
-            item_t z;
-            xml_io<item_t>::from_xml(i, z);
-            t.push_back(z);
+            T t;
+            xml_io<T>::from_xml(i, t);
+            c.push_back(t);
             }
     }
 };
@@ -117,6 +162,73 @@ struct xml_io<std::vector<T>>
   :public xml_sequence_io<std::vector<T>>
 {};
 
+/// Serialization for associative-pair containers.
+///
+/// Derive publicly from this to use its implementation when
+/// specializing class template xml_io for a particular sequence.
+///
+/// from_xml() reads only <item> elements, ignoring other elements
+/// (and non-element nodes) that might have been added manually,
+/// e.g., as documentation.
+///
+/// C++ calls std::set and its brethren "associative", even though
+/// they associate a key with...nothing. This implementation is for
+/// containers that associate a key with something. C++20 has no
+/// Concept for this; for the nonce, assert that it's a std::map or
+/// a std::unordered_map.
+
+template<typename C>
+struct xml_pair_container_io
+{
+    using K = typename C::key_type;
+    using T = typename C::mapped_type;
+    // A key value cannot be read into 'K const'; therefore,
+    // 'V' is not the same as 'C::value_type', which is:
+    //        std::pair<K const, T>
+    using V = std::pair<K,T>;
+
+    static_assert
+        (  std::is_same_v<C,std::map<K,T>>
+        || std::is_same_v<C,std::unordered_map<K,T>>
+        );
+
+    static void to_xml(xml::element& parent, C const& c)
+    {
+        parent.clear();
+        for(auto const& i : c)
+            {
+            // This is not equivalent to calling set_element():
+            // multiple <item> elements are expressly permitted.
+            xml::element e("item");
+            xml_io<V>::to_xml(e, i);
+            parent.push_back(e);
+            }
+    }
+
+    static void from_xml(xml::element const& parent, C& c)
+    {
+        c.clear();
+        // It would be good to call std::unordered_map::reserve()
+        // upstream if the number of elements is known.
+        for(auto const& i : parent.elements("item"))
+            {
+            V v;
+            xml_io<V>::from_xml(i, v);
+            c.insert(v);
+            }
+    }
+};
+
+template<typename K, typename T>
+struct xml_io<std::map<K,T>>
+  :public xml_pair_container_io<std::map<K,T>>
+{};
+
+template<typename K, typename T>
+struct xml_io<std::unordered_map<K,T>>
+  :public xml_pair_container_io<std::unordered_map<K,T>>
+{};
+
 /// Serialize a datum into a subelement of the given xml element.
 ///
 /// Precondition: parent has no element with the given tagname.
@@ -126,9 +238,9 @@ template<typename T>
 void set_element(xml::element& parent, std::string const& name, T const& t)
 {
     LMI_ASSERT(parent.end() == parent.find(name.c_str()));
-    xml::element z(name.c_str());
-    xml_io<T>::to_xml(z, t);
-    parent.push_back(z);
+    xml::element e(name.c_str());
+    xml_io<T>::to_xml(e, t);
+    parent.push_back(e);
 }
 
 /// Deserialize a datum from a subelement of the given xml element.
diff --git a/xml_serialize_test.cpp b/xml_serialize_test.cpp
index c86c6d0..9144a61 100644
--- a/xml_serialize_test.cpp
+++ b/xml_serialize_test.cpp
@@ -27,27 +27,40 @@
 #include "test_tools.hpp"
 #include "timer.hpp"
 
+#include <map>
 #include <string>
+#include <unordered_map>
+#include <utility>                      // pair
 #include <vector>
 
-// All /write.*/ functions save xml to this string.
+// All /write.*/ functions save xml to this string, and
+// all /read.*/ functions read from it.
 
 std::string dom_string;
 
 // Repetition count for /mete.*/ functions, tuned for speed and accuracy.
 
-int const number_of_elements = 20;
+int const number_of_iterations = 20;
 
-// /[dsv]0/: constant values for /write.*/ functions.
-// /[dsv]1/: variables for /read.*/ functions.
+using omap = std::          map<std::string, float>;
+using umap = std::unordered_map<int        , float>;
 
-double           const d0(2.718281828459045235360);
-std::string      const s0("string with ampersand & embedded spaces");
-std::vector<int> const v0 {10, 2, 4}; // Be a pepper...
+// /[dspvou]0/: constant values for /write.*/ functions.
+// /[dspvou]1/: variables for /read.*/ functions.
 
-double                 d1;
-std::string            s1;
-std::vector<int>       v1;
+double             const d0(2.718281828459045235360);
+std::string        const s0("string with ampersand & embedded spaces");
+std::pair<int,int> const p0 {17, 19};
+std::vector<int>   const v0 {10, 2, 4}; // Be a pepper...
+omap               const o0 {{"a",  1.1f}, {"b",  2.2f}, {"c",  3.3f}};
+umap               const u0 {{1, 101.01f}, {2, 202.02f}, {3, 303.03f}};
+
+double                   d1;
+std::string              s1;
+std::pair<int,int>       p1;
+std::vector<int>         v1;
+omap                     o1;
+umap                     u1;
 
 void write()
 {
@@ -55,7 +68,10 @@ void write()
     xml::element& root = document.root_node();
     xml_serialize::set_element(root, "d", d0);
     xml_serialize::set_element(root, "s", s0);
+    xml_serialize::set_element(root, "p", p0);
     xml_serialize::set_element(root, "v", v0);
+    xml_serialize::set_element(root, "o", o0);
+    xml_serialize::set_element(root, "u", u0);
     dom_string = document.str();
 }
 
@@ -65,7 +81,10 @@ void read()
     xml::element const& root = parser.root_node("eraseme");
     xml_serialize::get_element(root, "d", d1);
     xml_serialize::get_element(root, "s", s1);
+    xml_serialize::get_element(root, "p", p1);
     xml_serialize::get_element(root, "v", v1);
+    xml_serialize::get_element(root, "o", o1);
+    xml_serialize::get_element(root, "u", u1);
 }
 
 void write_erroneous()
@@ -84,7 +103,10 @@ void read_erroneous()
     xml::element const& root = parser.root_node("eraseme");
     xml_serialize::get_element(root, "d", d1);
     xml_serialize::get_element(root, "s", s1);
+    xml_serialize::get_element(root, "p", p1);
     xml_serialize::get_element(root, "v", v1);
+    xml_serialize::get_element(root, "o", o1);
+    xml_serialize::get_element(root, "u", u1);
     xml_serialize::get_element(root, "f", f1); // Error: no <f> element.
 }
 
@@ -92,7 +114,7 @@ void read_erroneous()
 // except that they don't actually do anything: they serve only to
 // measure overhead.
 
-void mete_write()
+void mete_write_0()
 {
     xml_lmi::xml_document document("eraseme");
     xml::element& root = document.root_node();
@@ -100,7 +122,7 @@ void mete_write()
     dom_string = document.str();
 }
 
-void mete_read()
+void mete_read_0()
 {
     xml_lmi::dom_parser parser(dom_string.c_str(), dom_string.size());
     xml::element const& root = parser.root_node("eraseme");
@@ -110,71 +132,47 @@ void mete_read()
 // These /mete_._[write|read]/ functions are like write() and read()
 // except that they each test a single datatype repeatedly.
 
-void mete_s_write()
+template<typename T>
+void mete_write(char const* name, T const& data)
 {
     xml_lmi::xml_document document("eraseme");
     xml::element& root = document.root_node();
-    for(int j = 0; j < number_of_elements; ++j)
+    for(int j = 0; j < number_of_iterations; ++j)
         {
-        root.erase("s");
-        xml_serialize::set_element(root, "s", s0);
+        root.erase(name);
+        xml_serialize::set_element(root, name, data);
         }
     dom_string = document.str();
 }
 
-void mete_s_read()
+template<typename T>
+void mete_read(char const* name, T& data)
 {
     xml_lmi::dom_parser parser(dom_string.c_str(), dom_string.size());
     xml::element const& root = parser.root_node("eraseme");
-    for(int j = 0; j < number_of_elements; ++j)
+    for(int j = 0; j < number_of_iterations; ++j)
         {
-        xml_serialize::get_element(root, "s", s1);
+        xml_serialize::get_element(root, name, data);
         }
 }
 
-void mete_d_write()
-{
-    xml_lmi::xml_document document("eraseme");
-    xml::element& root = document.root_node();
-    for(int j = 0; j < number_of_elements; ++j)
-        {
-        root.erase("d");
-        xml_serialize::set_element(root, "d", d0);
-        }
-    dom_string = document.str();
-}
+void mete_write_d() {mete_write("d", d0);}
+void mete_read_d()  {mete_read ("d", d1);}
 
-void mete_d_read()
-{
-    xml_lmi::dom_parser parser(dom_string.c_str(), dom_string.size());
-    xml::element const& root = parser.root_node("eraseme");
-    for(int j = 0; j < number_of_elements; ++j)
-        {
-        xml_serialize::get_element(root, "d", d1);
-        }
-}
+void mete_write_s() {mete_write("s", s0);}
+void mete_read_s()  {mete_read ("s", s1);}
 
-void mete_v_write()
-{
-    xml_lmi::xml_document document("eraseme");
-    xml::element& root = document.root_node();
-    for(int j = 0; j < number_of_elements; ++j)
-        {
-        root.erase("v");
-        xml_serialize::set_element(root, "v", v0);
-        }
-    dom_string = document.str();
-}
+void mete_write_p() {mete_write("p", p0);}
+void mete_read_p()  {mete_read ("p", p1);}
 
-void mete_v_read()
-{
-    xml_lmi::dom_parser parser(dom_string.c_str(), dom_string.size());
-    xml::element const& root = parser.root_node("eraseme");
-    for(int j = 0; j < number_of_elements; ++j)
-        {
-        xml_serialize::get_element(root, "v", v1);
-        }
-}
+void mete_write_v() {mete_write("v", v0);}
+void mete_read_v()  {mete_read ("v", v1);}
+
+void mete_write_o() {mete_write("o", o0);}
+void mete_read_o()  {mete_read ("o", o1);}
+
+void mete_write_u() {mete_write("u", u0);}
+void mete_read_u()  {mete_read ("u", u1);}
 
 int test_main(int, char*[])
 {
@@ -186,12 +184,29 @@ int test_main(int, char*[])
     // documentation for value_cast<>().
     BOOST_TEST(d0 == d1);
     BOOST_TEST_EQUAL(d0, d1);
+
     BOOST_TEST(s0 == s1);
     BOOST_TEST_EQUAL(s0, s1);
-    // BOOST_TEST_EQUAL(v0, v1); // No--couldn't display if not equal.
+
+    // BOOST_TEST_EQUAL() inserts unequal values into an ostream, so
+    // it can only be used with streamable types (as above).
+
+    BOOST_TEST(p0 == p1);
+
+    // For Containers, test both
+    //   P: c0 == c1
+    //   Q: c0.size() == c1.size()
+    // even though P implies Q, because Q AND ~P is easy to detect.
+
     BOOST_TEST(v0 == v1);
     BOOST_TEST_EQUAL(v0.size(), v1.size());
 
+    BOOST_TEST(o0 == o1);
+    BOOST_TEST_EQUAL(o0.size(), o1.size());
+
+    BOOST_TEST(u0 == u1);
+    BOOST_TEST_EQUAL(u0.size(), u1.size());
+
     std::string found
         ("Assertion 'parent.end() == parent.find(name.c_str())' failed."
         );
@@ -201,14 +216,20 @@ int test_main(int, char*[])
     BOOST_TEST_THROW(read_erroneous(), std::runtime_error, not_found);
 
     std::cout << "  Speed tests...\n";
-    std::cout << "  Write   : " << TimeAnAliquot(mete_write  ) << '\n';
-    std::cout << "  Read    : " << TimeAnAliquot(mete_read   ) << '\n';
-    std::cout << "  Write s : " << TimeAnAliquot(mete_s_write) << '\n';
-    std::cout << "  Read  s : " << TimeAnAliquot(mete_s_read ) << '\n';
-    std::cout << "  Write d : " << TimeAnAliquot(mete_d_write) << '\n';
-    std::cout << "  Read  d : " << TimeAnAliquot(mete_d_read ) << '\n';
-    std::cout << "  Write v : " << TimeAnAliquot(mete_v_write) << '\n';
-    std::cout << "  Read  v : " << TimeAnAliquot(mete_v_read ) << '\n';
+    std::cout << "  Write empty : " << TimeAnAliquot(mete_write_0) << '\n';
+    std::cout << "  Read  empty : " << TimeAnAliquot(mete_read_0 ) << '\n';
+    std::cout << "  Write d     : " << TimeAnAliquot(mete_write_d) << '\n';
+    std::cout << "  Read  d     : " << TimeAnAliquot(mete_read_d ) << '\n';
+    std::cout << "  Write s     : " << TimeAnAliquot(mete_write_s) << '\n';
+    std::cout << "  Read  s     : " << TimeAnAliquot(mete_read_s ) << '\n';
+    std::cout << "  Write p     : " << TimeAnAliquot(mete_write_p) << '\n';
+    std::cout << "  Read  p     : " << TimeAnAliquot(mete_read_p ) << '\n';
+    std::cout << "  Write v     : " << TimeAnAliquot(mete_write_v) << '\n';
+    std::cout << "  Read  v     : " << TimeAnAliquot(mete_read_v ) << '\n';
+    std::cout << "  Write o     : " << TimeAnAliquot(mete_write_o) << '\n';
+    std::cout << "  Read  o     : " << TimeAnAliquot(mete_read_o ) << '\n';
+    std::cout << "  Write u     : " << TimeAnAliquot(mete_write_u) << '\n';
+    std::cout << "  Read  u     : " << TimeAnAliquot(mete_read_u ) << '\n';
     std::cout << std::endl;
 
     return 0;
diff --git a/xml_xslt_wrapp.cpp b/xml_xslt_wrapp.cpp
deleted file mode 100644
index b4a5b0d..0000000
--- a/xml_xslt_wrapp.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-// Include xmlwrapp and xsltwrapp sources.
-//
-// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 
2019, 2020 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
-//
-// https://savannah.nongnu.org/projects/lmi
-// email: <gchicares@sbcglobal.net>
-// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
-
-#include "pchfile.hpp"
-
-#if defined __GNUC__ && !defined __clang__
-#   pragma GCC diagnostic ignored "-Wextra-semi"
-#   pragma GCC diagnostic ignored "-Wnull-dereference"
-#   pragma GCC diagnostic ignored "-Wsuggest-override"
-#   pragma GCC diagnostic ignored "-Wswitch-enum"
-#   pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
-#endif // defined __GNUC__ && !defined __clang__
-
-#define HAVE_BOOST_POOL_SINGLETON_POOL_HPP
-
-#include "libxml/ait_impl.cxx"
-#include "libxml/attributes.cxx"
-#include "libxml/document.cxx"
-#include "libxml/dtd_impl.cxx"
-#include "libxml/errors.cxx"
-#include "libxml/event_parser.cxx"
-#include "libxml/init.cxx"
-#include "libxml/node.cxx"
-#include "libxml/node_iterator.cxx"
-#include "libxml/node_manip.cxx"
-#include "libxml/nodes_view.cxx"
-#include "libxml/relaxng.cxx"
-#include "libxml/schema.cxx"
-#include "libxml/tree_parser.cxx"
-#include "libxml/utility.cxx"
-#include "libxml/xpath.cxx"
-#include "libxslt/init.cxx"
-#include "libxslt/stylesheet.cxx"
-
-#undef HAVE_BOOST_POOL_SINGLETON_POOL_HPP
diff --git a/xmlwrapp-0.9.0.md5sums b/xmlwrapp-0.9.0.md5sums
deleted file mode 100644
index e875f48..0000000
--- a/xmlwrapp-0.9.0.md5sums
+++ /dev/null
@@ -1,45 +0,0 @@
-e9f53a414a8b87c19b9aaa967d118b39 *include/xmlwrapp/_cbfo.h
-e5198c69b9160f894144c27f7944f006 *include/xmlwrapp/attributes.h
-c0e31c21ee73adc551d44066a05cb56e *include/xmlwrapp/document.h
-81f2eb808ba0a08dfdf7e504148e48e1 *include/xmlwrapp/errors.h
-472be44813eefa0c2678d756a0ad8553 *include/xmlwrapp/event_parser.h
-10265ab866c1ae2f5dd2294cc07fe814 *include/xmlwrapp/export.h
-aaf6d29222f1bc492971c491e8674094 *include/xmlwrapp/init.h
-1a7abea141d786bf01eb8308e3dc4a13 *include/xmlwrapp/node.h
-621d3c9e99183cb4f0e699a196b2ae06 *include/xmlwrapp/nodes_view.h
-5c7ca8cfae5f13c463ba98b4f697fd39 *include/xmlwrapp/relaxng.h
-b1c92c9f772f9d15409239c95ffda7fa *include/xmlwrapp/schema.h
-0128a792eedd93e54c4279fbf0be747d *include/xmlwrapp/tree_parser.h
-f9a370ac25212f412df21cdb6e86338c *include/xmlwrapp/version.h
-8f828c6963aee1218b6c24e44a8c04bd *include/xmlwrapp/xmlwrapp.h
-9345a4883fb176b91565767f16431567 *include/xmlwrapp/xpath.h
-3f5f7ec654e831101f292c38b0d96822 *include/xsltwrapp/init.h
-acb3d40057869a5d5cb9761f666b3ec5 *include/xsltwrapp/stylesheet.h
-175cb6ca0c4b7c520eeb7db2f81ffe15 *include/xsltwrapp/xsltwrapp.h
-c9d06b9b82de6f8e619c849735ae51d3 *src/libxml/ait_impl.cxx
-aabe59ecc4a15a3f2fc33687f653bafb *src/libxml/ait_impl.h
-ce964eccb3ae135e4cd3cedccb400c19 *src/libxml/attributes.cxx
-08a95a96dae987ff57f7fdb7ff26622a *src/libxml/cpp11.h
-78bbc34f5704d3f685c3529b039fff10 *src/libxml/document.cxx
-4b0e309695a7edf96aef3b8340f30b1d *src/libxml/dtd_impl.cxx
-52a30d8e4839d4862ea5d6beb8e88ce8 *src/libxml/dtd_impl.h
-4c6b35c0fc36ece0394279f3fbecc4fe *src/libxml/errors.cxx
-3b4d2010ef66b0e0095315e154af0230 *src/libxml/errors_impl.h
-e5e1b3adee3f1cf531d73a1ebe21ce25 *src/libxml/event_parser.cxx
-05d595123a29b81794743f8109a5b84d *src/libxml/init.cxx
-489be726d29bf128bcaca6edf439b8b5 *src/libxml/node.cxx
-ea265506d61407be3941365a50d19cda *src/libxml/node_iterator.cxx
-69bd398ab48c4b287e43cf64e048dbda *src/libxml/node_iterator.h
-d67208460998a4758c0975051f89f146 *src/libxml/node_manip.cxx
-889caa6bab85a23ee264a7b81b5909d4 *src/libxml/node_manip.h
-7d053e87fa8ee74db74d48ba499729a7 *src/libxml/nodes_view.cxx
-d8b81745f1ae877d28bd6c7f2d11f73c *src/libxml/pimpl_base.h
-1d4982b515658958409235e1d64e912c *src/libxml/relaxng.cxx
-d7f910f4338ecf6ce5dd87c3c4925d1c *src/libxml/schema.cxx
-281189ffd81c03b45b79590be1e1c926 *src/libxml/tree_parser.cxx
-8f68498087e4b89ea1b32e71adfcdc21 *src/libxml/utility.cxx
-3e1ce5c708657b9c3c74d61a71afb186 *src/libxml/utility.h
-fff84ff7d49ea953c11f158bc0c64fa3 *src/libxml/xpath.cxx
-473b990a598670b0f7f0106548a30252 *src/libxslt/init.cxx
-ebb49a9d004f52bed42e5510ce54bb9b *src/libxslt/result.h
-955a8b16ded31ce18d9854ffb75abf02 *src/libxslt/stylesheet.cxx



reply via email to

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