diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ce_product_name.hpp ./ce_product_name.hpp
--- /lmi/checkouts/current/lmi/ce_product_name.hpp	2010-01-10 15:39:30.039906000 +0000
+++ ./ce_product_name.hpp	2010-03-04 15:37:03.021633100 +0000
@@ -43,7 +43,7 @@
 /// Because there is no enum to map to, there is no 'm' for "Mapped"
 /// at the beginning of the class's or file's name.
 ///
-/// Valid values are the base names of policy ('.pol') files found
+/// Valid values are the base names of policy ('.xpol') files found
 /// in the (configurable) data directory. They are read only once and
 /// cached, not because of any measured improvement in run time, but
 /// in order to keep the type from mutating with unknown consequences.
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/configure.ac ./configure.ac
--- /lmi/checkouts/current/lmi/configure.ac	2010-02-21 11:18:46.601025000 +0000
+++ ./configure.ac	2010-03-04 15:37:03.021633100 +0000
@@ -124,6 +124,20 @@
              esac],
              lmi_cgicc_option=no)
 
+AC_ARG_ENABLE(legacy-formats,
+             [AC_HELP_STRING([--disable-legacy-formats],
+                             [don't build support for legacy file formats])],
+             [case "x${enableval}" in
+                   x) legacy_option=no ;;
+                xyes) legacy_option=yes ;;
+                 xno) legacy_option=no ;;
+                   *) AC_MSG_ERROR(bad value ${enableval} for --enable-legacy-formats) ;;
+             esac], [legacy_option=yes])
+
+if test "x$legacy_option" = "xno"; then
+    AC_DEFINE(LMI_NO_LEGACY_FORMATS, [1], [Define if you don't need support for legacy file formats])
+fi
+
 dnl Pass standard options to wx.
 WX_STANDARD_OPTIONS([debug,shared,toolkit,wxshared])
 
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/dbnames.hpp ./dbnames.hpp
--- /lmi/checkouts/current/lmi/dbnames.hpp	2010-01-10 15:39:30.039906000 +0000
+++ ./dbnames.hpp	2010-03-07 00:15:12.000000000 +0000
@@ -30,6 +30,8 @@
 
 #include <vector>
 
+// See 'dbnames.xpp' for the definition of each entity.
+
 enum DatabaseNames
     {DB_FIRST
 
@@ -42,8 +44,8 @@
         ,DB_AllowFullUW
         ,DB_AllowSimpUW
         ,DB_AllowGuarUW
-        ,DB_SmokeOrTobacco       // DATABASE !! Move to '.pol'
-        ,DB_PrefOrSelect         // DATABASE !! Move to '.pol'
+        ,DB_SmokeOrTobacco       // DATABASE !! Move to '.policy'
+        ,DB_PrefOrSelect         // DATABASE !! Move to '.policy'
         ,DB_AllowPreferredClass
         ,DB_AllowUltraPrefClass
 
@@ -432,14 +434,7 @@
         ,DB_PrimaryHurdle
         ,DB_SecondaryHurdle
 
-    ,DB_LAST    // Adding a new item? Insert directly above *only*.
-    // That way, old databases remain compatible with new code, and any
-    // error in using a new item will occur when the new item is used
-    // instead of where a renumbered old item is used--that should make
-    // such errors much easier to track down and repair. We can re-sort
-    // additions into categories when preparing a major release.
-    //
-    // See 'dbnames.xpp' for the definition of each entity.
+    ,DB_LAST
     };
 
 struct db_names
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ihs_basicval.cpp ./ihs_basicval.cpp
--- /lmi/checkouts/current/lmi/ihs_basicval.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./ihs_basicval.cpp	2010-03-04 15:37:03.037257800 +0000
@@ -397,7 +397,7 @@
             {
             // Allow hardcoded number of funds < Funds.GetNumberOfFunds
             // so an accurate fund average can be calculated (based
-            // on the funds in the *.fnd file), even though the inputs
+            // on the funds in the *.xfnd file), even though the inputs
             // class may not accommodate that many funds. If j falls
             // outside the range of yare_input_.FundAllocations, use a
             // weight of zero.
@@ -409,11 +409,11 @@
         else if(j < static_cast<int>(yare_input_.FundAllocations.size()))
             {
             // TODO ?? Can this be correct? Shouldn't we be looking to
-            // the .fnd file rather than the input class?
+            // the .xfnd file rather than the input class?
             //
             // Allow hardcoded number of funds < Funds.GetNumberOfFunds
             // so an accurate fund average can be calculated (based
-            // on the funds in the *.fnd file), even though the inputs
+            // on the funds in the *.xfnd file), even though the inputs
             // class may not accommodate that many funds. If j falls
             // outside the range of yare_input_.FundAllocations, use a
             // weight of zero.
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ihs_dbdict.cpp ./ihs_dbdict.cpp
--- /lmi/checkouts/current/lmi/ihs_dbdict.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./ihs_dbdict.cpp	2010-03-15 17:35:08.000000000 +0000
@@ -35,12 +35,15 @@
 #include "mc_enum_type_enums.hpp"
 #include "miscellany.hpp"
 #include "oecumenic_enumerations.hpp"
+#include "xml_serialize.hpp"
 
 #include <boost/filesystem/convenience.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/filesystem/operations.hpp>
 #include <boost/filesystem/path.hpp>
 
+#include <xmlwrapp/document.h>
+
 #include <limits>
 #include <sstream>
 
@@ -65,6 +68,44 @@
 {
 }
 
+namespace xml_serialize
+{
+template<>
+struct xml_io<TDBValue>
+{
+    static void to_xml  (xml::node& out, TDBValue const& in) {in.write(out);}
+    static void from_xml(TDBValue& out, xml::node const& in) {out.read(in); }
+};
+
+/// Specialize xml_io<> for dict_map instead of using some generic
+/// std::map serialization, because the key would be stored
+/// redundantly: it's already part of TDBValue.
+
+template<>
+struct xml_io<dict_map>
+{
+    static void to_xml(xml::node& out, dict_map const& in)
+    {
+        for(dict_map::const_iterator i = in.begin(); i != in.end(); ++i)
+            {
+            set_element(out, "value", i->second);
+            }
+    }
+
+    static void from_xml(xml::node const& in, dict_map& out)
+    {
+        out.clear();
+        xml::const_nodes_view items = in.elements("value");
+        for(xml::const_nodes_view::iterator i = items.begin(); i != items.end(); ++i)
+            {
+            TDBValue v;
+            xml_serialize::from_xml(*i, v);
+            out[v.GetKey()] = v;
+            }
+    }
+};
+} // namespace xml_serialize
+
 //============================================================================
 void DBDictionary::Init(std::string const& NewFilename)
 {
@@ -90,45 +131,22 @@
     CachedFilename = NewFilename;
     dictionary.erase(dictionary.begin(), dictionary.end());
 
-    JRPS::JrPs_ifpstream ips
-        (NewFilename.c_str()
-        );
-    if(!ips)
-        {
-        BadFile(NewFilename, "could not be found.");
-        }
-    int n;
-    ips >> n;
-    if(NumberOfEntries != n)
+    xml_lmi::dom_parser parser(NewFilename);
+    xml::element const& root = parser.root_node("database");
+
+    xml_serialize::get_element(root, "dictionary", dictionary);
+
+    if(NumberOfEntries != static_cast<int>(dictionary.size()))
         {
         std::ostringstream oss;
         oss
             << "is not up to date or is corrupted."
             << " It should contain " << NumberOfEntries
-            << " elements, but it actually contains " << n
+            << " elements, but it actually contains " << dictionary.size()
             << " elements."
             ;
         BadFile(NewFilename, oss.str());
         }
-    for(int j = 0; j < n; j++)
-        {
-        TDBValue* temp;
-        ips >> temp;
-        if(0 == temp)
-            {
-            std::ostringstream oss;
-            oss
-                << "is not up to date or is corrupted."
-                << " Its element number " << j
-                << ", which is '" << GetDBNames()[j].ShortName
-                << "', cannot be read."
-                ;
-            BadFile(NewFilename, oss.str());
-            break;
-            }
-        dictionary[temp->GetKey()] = *temp;
-        delete temp;
-        }
 }
 
 //============================================================================
@@ -161,17 +179,6 @@
 //============================================================================
 void DBDictionary::WriteDB(std::string const& filename)
 {
-    JRPS::JrPs_ofpstream ops
-        (filename.c_str()
-        ,JRPS::JrPs_pstream::xxtrunc | JRPS::JrPs_pstream::xxcreat
-        );
-    if(!ops)
-        {
-        fatal_error()
-            << "Cannot open database file '" << filename << "'."
-            << LMI_FLUSH
-            ;
-        }
     if(NumberOfEntries != static_cast<int>(dictionary.size()))
         {
         fatal_error()
@@ -189,10 +196,17 @@
             }
         fatal_error() << LMI_FLUSH;
         }
-    ops << dictionary.size();
-    for(unsigned int j = 0; j < dictionary.size(); j++)
+
+    xml::document document("database");
+    xml::element& root = document.get_root_node();
+    xml_serialize::set_element(root, "dictionary", dictionary);
+
+    if(!document.save_to_file(filename.c_str()))
         {
-        ops << &dictionary[j];
+        fatal_error()
+            << "Cannot open database file '" << filename << "'."
+            << LMI_FLUSH
+            ;
         }
 }
 
@@ -631,7 +645,7 @@
     Add(TDBValue(DB_ExpRatIBNRMult      , 6.0));
     Add(TDBValue(DB_ExpRatAmortPeriod   , 4.0));
 
-    WriteDB(AddDataDir("sample.db4"));
+    WriteDB(AddDataDir("sample.xdb4"));
 }
 
 //============================================================================
@@ -642,7 +656,7 @@
     fs::directory_iterator end_i;
     for(; i != end_i; ++i)
         {
-        if(is_directory(*i) || ".db4" != fs::extension(*i))
+        if(is_directory(*i) || ".xdb4" != fs::extension(*i))
             {
             continue;
             }
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ihs_dbvalue.cpp ./ihs_dbvalue.cpp
--- /lmi/checkouts/current/lmi/ihs_dbvalue.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./ihs_dbvalue.cpp	2010-03-15 17:34:22.000000000 +0000
@@ -34,60 +34,17 @@
 #include "math_functors.hpp" // greater_of(), lesser_of
 #include "print_matrix.hpp"
 #include "value_cast.hpp"
+#include "xml_serialize.hpp"
 
 #include <algorithm>
 #include <functional>
 #include <istream>
-#include <limits>       // numeric_limits<>
+#include <iterator>          // std::advance
+#include <limits>            // std::numeric_limits
+#include <map>
 #include <numeric>
 #include <ostream>
 
-#ifndef stlstrm_hpp
-#define stlstrm_hpp
-
-// This misbegotten thing used to be a distinct header, but now we've
-// extirpated it everywhere else. TODO ?? Stop using it here too.
-
-// Stream STL containers with Joshua Rowe's object streaming.
-
-#include "ihs_fpios.hpp"
-namespace JRPS = JOSHUA_ROWE_PERSISTENT_STREAMS;
-
-#include <cassert>
-#include <iostream>
-#include <string>
-#include <vector>
-
-template<class T>
-JRPS::JrPs_ipstream& operator>> (JRPS::JrPs_ipstream& ips, std::vector<T>& x)
-{
-    x.erase(x.begin(), x.end());
-    typename std::vector<T>::size_type vector_size;
-    ips >> vector_size;
-    x.reserve(vector_size);
-    typename std::vector<T>::value_type z;
-    for(typename std::vector<T>::size_type j = 0; j < vector_size; j++)
-        {
-        ips >> z;
-        x.push_back(z);
-        }
-    assert(vector_size == x.size());
-    return ips;
-}
-
-template<class T>
-JRPS::JrPs_opstream& operator<< (JRPS::JrPs_opstream& ops, std::vector<T> const& x)
-{
-    ops << x.size();
-    for(typename std::vector<T>::const_iterator i = x.begin(); i < x.end(); i++)
-        {
-        ops << *i;
-        }
-    return ops;
-}
-
-#endif // stlstrm_hpp
-
 static int const ScalarDims[TDBValue::e_number_of_axes] = {1, 1, 1, 1, 1, 1, 1};
 static int const MaxPossibleElements = std::numeric_limits<int>::max();
 
@@ -187,10 +144,9 @@
 
 //============================================================================
 TDBValue::TDBValue(TDBValue const& obj)
-    :JRPS::JrPs_pstreamable()
-    ,key(obj.key)
-    ,axis_lengths(obj.axis_lengths)
-    ,data_values(obj.data_values)
+    :key          (obj.key)
+    ,axis_lengths (obj.axis_lengths)
+    ,data_values  (obj.data_values)
 {
 }
 
@@ -692,87 +648,82 @@
     return z.write(os);
 }
 
-// Streaming implementation
+// Serialization implementation
 
-TDBValue::TDBValue(JRPS::JrPs_pstreamableInit)
-    :key(0)
-    ,axis_lengths(e_number_of_axes)
+namespace
 {
-}
-
-JRPS::JrPs_pstreamable* TDBValue::jrps_build()
+inline char const* db_name_from_index(int key)
 {
-    return new TDBValue(JRPS::JrPs_pstreamableinit);
+    return GetDBNames()[key].ShortName;
 }
 
-JRPS::JrPs_pstreamreg RegTDBValue
-    ("TDBValue"
-    ,TDBValue::jrps_build
-    ,JRPS_PSTREAM_DELTA(TDBValue)
-    );
-
-// TODO ?? Couldn't templates handle this?
-JRPS::JrPs_opstream& operator<< (JRPS::JrPs_opstream& os, TDBValue const* p)
+// Separate out the initialization; then provide a simple
+// (inline?) accessor using map_lookup().
+//
+int db_name_to_index(std::string const& short_name)
 {
-    return os << (JRPS::JrPs_pstreamable const*)p;
-}
+    typedef std::map<std::string, int> name_to_key_map;
 
-JRPS::JrPs_ipstream& operator>> (JRPS::JrPs_ipstream& is, TDBValue*& p)
-{
-    return is >> (void const*&)p;
-}
+    static name_to_key_map static_mapping;
 
-void* TDBValue::read(JRPS::JrPs_ipstream& is)
-{
-    int version;
-    is >> version;
-    if(version < StreamingVersion)
+    if(static_mapping.empty())
+        {
+        std::vector<db_names> const& names = GetDBNames();
+        for(int i = 0; i < DB_LAST; ++i)
+            {
+            static_mapping[names[i].ShortName] = i;
+            }
+        }
+
+    name_to_key_map::const_iterator i = static_mapping.find(short_name);
+    if(static_mapping.end() == i)
         {
         fatal_error()
-            << "Program supports input versions up to "
-            << StreamingVersion
-            << " but input file is version "
-            << version
-            << " ."
+            << "Value '"
+            << short_name
+            << "' is invalid database name."
             << LMI_FLUSH
             ;
         }
 
-    is >> key;
-    is >> axis_lengths;
-    is >> extra_axes_values;
-    is >> extra_axes_names;
-    is >> data_values;
-
-    LMI_ASSERT(getndata() == static_cast<int>(data_values.size()));
-    LMI_ASSERT
-        (   0 < static_cast<int>(data_values.size())
-        &&      static_cast<int>(data_values.size()) < MaxPossibleElements
-        );
-
-    return this;
+    return i->second;
 }
+} // Unnamed namespace.
 
-void TDBValue::write(JRPS::JrPs_opstream& os) const
+void TDBValue::read(xml::element const& n)
 {
-    os << StreamingVersion;
+    using namespace xml_serialize;
+axis_lengths.clear();
+    // This is the only place DatabaseNames value is serialized. Adding
+    // "proper" support for it as a xml_io<> specialization would be
+    // complicated (but see 'ihs_rnddata.cpp'--this ought to be an
+    // mc_enum type). It doesn't seem worth the extra complications in
+    // xml_serialize code, so we do the conversion manually instead, for other
+    // code's simplicity sake.
+    std::string short_name;
+    get_element<std::string>(n, "key", short_name);
+    key = db_name_to_index(short_name);
+//    key = db_name_to_index(get_element<std::string>(n, "key"));
+    get_element(n, "axis_lengths", axis_lengths);
+    get_element(n, "extra_axes_values", extra_axes_values);
+    get_element(n, "extra_axes_names", extra_axes_names);
+    get_element(n, "data_values", data_values);
 
     LMI_ASSERT(getndata() == static_cast<int>(data_values.size()));
     LMI_ASSERT
         (   0 < static_cast<int>(data_values.size())
         &&      static_cast<int>(data_values.size()) < MaxPossibleElements
         );
-    AreAllAxesOK();
-
-    os << key;
-    os << axis_lengths;
-    os << extra_axes_values;
-    os << extra_axes_names;
-    os << data_values;
 }
 
-char const* TDBValue::streamableName() const
+void TDBValue::write(xml::element& n) const
 {
-    return "TDBValue";
+    using namespace xml_serialize;
+
+    set_element(n, "key", db_name_from_index(key));
+    set_element(n, "axis_lengths", axis_lengths);
+    set_element(n, "extra_axes_values", extra_axes_values);
+    set_element(n, "extra_axes_names", extra_axes_names);
+    set_element(n, "data_values", data_values);
 }
 
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ihs_dbvalue.hpp ./ihs_dbvalue.hpp
--- /lmi/checkouts/current/lmi/ihs_dbvalue.hpp	2010-01-10 15:39:30.039906000 +0000
+++ ./ihs_dbvalue.hpp	2010-03-13 17:14:40.000000000 +0000
@@ -32,9 +32,7 @@
 
 #include "dbindex.hpp"
 #include "so_attributes.hpp"
-
-#include "ihs_fpios.hpp"
-namespace JRPS = JOSHUA_ROWE_PERSISTENT_STREAMS;
+#include "xml_lmi_fwd.hpp"
 
 #include <iosfwd>
 #include <string>
@@ -49,11 +47,13 @@
     ,e_Incremental
     };
 
+namespace xml_serialize {template<typename T> struct xml_io;}
+
 class LMI_SO TDBValue
-    :private JRPS::JrPs_pstreamable
 {
     friend std::istream& operator>>(std::istream&, TDBValue&);
     friend std::ostream& operator<<(std::ostream&, TDBValue const&);
+    friend class xml_serialize::xml_io<TDBValue>;
 
   public:
     // Separate enumerators here facilitate compile-time assertions
@@ -122,6 +122,8 @@
     void ParanoidCheck()                      const;
     bool AreAllAxesOK()                       const;
     void FixupIndex(std::vector<double>& idx) const;
+    void read (xml::element const&);
+    void write(xml::element&) const;
 
     int  key;        // Database dictionary key
 
@@ -152,23 +154,9 @@
     std::vector<double>      extra_axes_values;
     std::vector<e_IdxType>   extra_axes_types;
 
-// The following sections don't follow the normal order for access
-// specifiers. Grouping them together here facilitates their
-// expunction as soon as we get rid of 'ihs_[f]pios.?pp'.
-
-  public:
-    static JRPS::JrPs_pstreamable* jrps_build();
-    friend JRPS::JrPs_ipstream& operator>> (JRPS::JrPs_ipstream&, TDBValue*&);
-    friend JRPS::JrPs_opstream& operator<< (JRPS::JrPs_opstream&, TDBValue const*);
-
-  protected:
-    virtual void*   read(JRPS::JrPs_ipstream&);
-    virtual void    write(JRPS::JrPs_opstream&) const;
-
-  private:
-    TDBValue(JRPS::JrPs_pstreamableInit);
-    virtual char const* streamableName() const;
+#ifndef LMI_NO_LEGACY_FORMATS
     enum {StreamingVersion = 1};
+#endif // !LMI_NO_LEGACY_FORMATS
 };
 
 /*
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ihs_funddata.cpp ./ihs_funddata.cpp
--- /lmi/checkouts/current/lmi/ihs_funddata.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./ihs_funddata.cpp	2010-03-15 14:17:22.000000000 +0000
@@ -22,8 +22,6 @@
 // $Id: ihs_funddata.cpp 4729 2010-01-10 15:39:30Z chicares $
 
 // This class describes funds: their names and investment mgmt fees.
-// TODO ?? An extension other than .fnd would be preferable: msw uses
-// .fnd for "find"
 
 #ifdef __BORLANDC__
 #   include "pchfile.hpp"
@@ -36,6 +34,11 @@
 #include "assert_lmi.hpp"
 #include "data_directory.hpp"
 #include "platform_dependent.hpp" // access()
+#include "xml_serialize.hpp"
+
+#include <boost/filesystem/convenience.hpp>
+
+#include <xmlwrapp/document.h>
 
 #include <fstream>
 
@@ -65,6 +68,33 @@
 }
 
 //============================================================================
+namespace xml_serialize
+{
+    template<>
+    struct xml_io<FundInfo>
+    {
+        static void to_xml(xml::node& out, FundInfo const& in)
+        {
+            set_element(out, "scalar_imf", in.ScalarIMF());
+            set_element(out, "short_name", in.ShortName());
+            set_element(out, "long_name",  in.LongName());
+        }
+
+        static void from_xml(xml::node const& in, FundInfo& out)
+        {
+            double simf;
+            std::string sname, lname;
+
+            get_element(in, "scalar_imf", simf);
+            get_element(in, "short_name", sname);
+            get_element(in, "long_name",  lname);
+
+            out = FundInfo(simf, sname, lname);
+        }
+    };
+} // namespace xml_serialize
+
+//============================================================================
 FundData::FundData()
 {
 }
@@ -81,17 +111,9 @@
 }
 
 //============================================================================
-void FundData::Read(std::string const& a_Filename)
+#if 0
+void FundData::ReadLegacy(std::string const& a_Filename)
 {
-    if(access(a_Filename.c_str(), R_OK))
-        {
-        fatal_error()
-            << "File '"
-            << a_Filename
-            << "' is required but could not be found. Try reinstalling."
-            << LMI_FLUSH
-            ;
-        }
     std::ifstream is(a_Filename.c_str());
 
     LMI_ASSERT(0 == FundInfo_.size());
@@ -121,26 +143,31 @@
         FundInfo_.push_back(f);
         }
 }
+#endif // 0
 
-//============================================================================
-void FundData::Write(std::string const& a_Filename)
+void FundData::Read(std::string const& a_Filename)
 {
-    std::ofstream os(a_Filename.c_str());
-
-    std::vector<FundInfo>::const_iterator i = FundInfo_.begin();
-    for(;i != FundInfo_.end(); i++)
+    if(access(a_Filename.c_str(), R_OK))
         {
-        os
-            << i->ScalarIMF_
-            << '\t'
-            << i->ShortName_
-            << '\t'
-            << i->LongName_
-            << '\n'
+        fatal_error()
+            << "File '"
+            << a_Filename
+            << "' is required but could not be found. Try reinstalling."
+            << LMI_FLUSH
             ;
         }
 
-    if(!os.good())
+    xml_lmi::dom_parser parser(a_Filename);
+    xml_serialize::xml_io<std::vector<FundInfo> >::from_xml(parser.root_node("fund_data"), FundInfo_);
+}
+
+//============================================================================
+void FundData::Write(std::string const& a_Filename)
+{
+    xml::document document("fund_data");
+    xml_serialize::to_xml(document.get_root_node(), FundInfo_);
+
+    if(!document.save_to_file(a_Filename.c_str()))
         {
         fatal_error()
             << "Unable to write fund file '"
@@ -162,6 +189,6 @@
             ,"Money Market Fund"
             )
         );
-    foo.Write(AddDataDir("sample.fnd"));
+    foo.Write(AddDataDir("sample.xfnd"));
 }
 
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ihs_proddata.cpp ./ihs_proddata.cpp
--- /lmi/checkouts/current/lmi/ihs_proddata.cpp	2010-01-20 20:30:51.857855000 +0000
+++ ./ihs_proddata.cpp	2010-03-11 20:04:16.000000000 +0000
@@ -42,6 +42,7 @@
 #include "assert_lmi.hpp"
 #include "data_directory.hpp"
 #include "platform_dependent.hpp" // access()
+//#include "xml_serialize.hpp"
 
 #include <boost/filesystem/convenience.hpp>
 #include <boost/filesystem/path.hpp>
@@ -70,257 +71,325 @@
 {
     fs::path path(a_Filename);
     LMI_ASSERT(a_Filename == path.leaf());
-    path = fs::change_extension(path, ".pol");
+    path = fs::change_extension(path, ".xpol");
+//    path = fs::change_extension(path, ".pol");
     Read(AddDataDir(path.string()));
 }
 
-//============================================================================
-void TProductData::Read(std::string const& a_Filename)
+#include "value_cast.hpp"
+#include "xml_lmi.hpp"
+
+#if 0
+    template<typename T>
+    void set_element(xml::element& root, char const* name, T const& value)
+    {
+        xml::element node(name);
+        node.push_back(xml::node(xml::node::text(value_cast<std::string>(value).c_str())));
+        root.push_back(node);
+    }
+
+    template<typename T>
+    void get_element(xml::element const& root, char const* name, T& value)
+    {
+        xml::node::const_iterator i = root.find(name);
+        if(root.end() == i)
+            {
+            fatal_error()
+                << "Required element '"
+                << name
+                << "' is missing."
+                << LMI_FLUSH
+                ;
+            }
+        value = value_cast<T>(xml_lmi::get_content(*i));
+    }
+#endif // 0
+namespace detail
 {
-    if(access(a_Filename.c_str(), R_OK))
-        {
-        fatal_error()
-            << "File '"
-            << a_Filename
-            << "' is required but could not be found. Try reinstalling."
-            << LMI_FLUSH
-            ;
-        }
-    std::ifstream is(a_Filename.c_str());
+void set_element(xml::element& parent, std::string const& name, std::string const& value);
+std::string get_element(xml::element const& parent, std::string const& name);
+} // Namespace detail.
 
-    std::getline(is, DatabaseFilename,              '\n');
-    std::getline(is, FundFilename,                  '\n');
-    std::getline(is, CorridorFilename,              '\n');
-    std::getline(is, CurrCOIFilename,               '\n');
-    std::getline(is, GuarCOIFilename,               '\n');
-    std::getline(is, WPFilename,                    '\n');
-    std::getline(is, ADDFilename,                   '\n');
-    std::getline(is, ChildRiderFilename,            '\n');
-    std::getline(is, CurrSpouseRiderFilename,       '\n');
-    std::getline(is, GuarSpouseRiderFilename,       '\n');
-    std::getline(is, CurrTermFilename,              '\n');
-    std::getline(is, GuarTermFilename,              '\n');
-    std::getline(is, TableYFilename,                '\n');
-    std::getline(is, PremTaxFilename,               '\n');
-    std::getline(is, TAMRA7PayFilename,             '\n');
-    std::getline(is, TgtPremFilename,               '\n');
-    std::getline(is, IRC7702Filename,               '\n');
-    std::getline(is, Gam83Filename,                 '\n');
-    std::getline(is, SubstdTblMultFilename,         '\n');
-    std::getline(is, CurrSpecAmtLoadFilename,       '\n');
-    std::getline(is, GuarSpecAmtLoadFilename,       '\n');
-    std::getline(is, RoundingFilename,              '\n');
-    std::getline(is, TierFilename,                  '\n');
-    std::getline(is, PolicyForm,                    '\n');
-    std::getline(is, PolicyMktgName,                '\n');
-    std::getline(is, PolicyLegalName,               '\n');
-    std::getline(is, InsCoShortName,                '\n');
-    std::getline(is, InsCoName,                     '\n');
-    std::getline(is, InsCoAddr,                     '\n');
-    std::getline(is, InsCoStreet,                   '\n');
-    std::getline(is, InsCoPhone,                    '\n');
-    std::getline(is, InsCoDomicile,                 '\n');
-    std::getline(is, MainUnderwriter,               '\n');
-    std::getline(is, MainUnderwriterAddress,        '\n');
-    std::getline(is, CoUnderwriter,                 '\n');
-    std::getline(is, CoUnderwriterAddress,          '\n');
-    std::getline(is, AvName,                        '\n');
-    std::getline(is, CsvName,                       '\n');
-    std::getline(is, CsvHeaderName,                 '\n');
-    std::getline(is, NoLapseProvisionName,          '\n');
-    std::getline(is, InterestDisclaimer,            '\n');
-    std::getline(is, GuarMortalityFootnote,         '\n');
-    std::getline(is, AccountValueFootnote,          '\n');
-    std::getline(is, AttainedAgeFootnote,           '\n');
-    std::getline(is, CashSurrValueFootnote,         '\n');
-    std::getline(is, DeathBenefitFootnote,          '\n');
-    std::getline(is, InitialPremiumFootnote,        '\n');
-    std::getline(is, NetPremiumFootnote,            '\n');
-    std::getline(is, OutlayFootnote,                '\n');
-    std::getline(is, PolicyYearFootnote,            '\n');
-    std::getline(is, ADDFootnote,                   '\n');
-    std::getline(is, ChildFootnote,                 '\n');
-    std::getline(is, SpouseFootnote,                '\n');
-    std::getline(is, TermFootnote,                  '\n');
-    std::getline(is, WaiverFootnote,                '\n');
-    std::getline(is, MinimumPremiumFootnote,        '\n');
-    std::getline(is, PremAllocationFootnote,        '\n');
-    std::getline(is, ProductDescription,            '\n');
-    std::getline(is, StableValueFootnote,           '\n');
-    std::getline(is, NoVanishPremiumFootnote,       '\n');
-    std::getline(is, RejectPremiumFootnote,         '\n');
-    std::getline(is, ExpRatingFootnote,             '\n');
-    std::getline(is, MortalityBlendFootnote,        '\n');
-    std::getline(is, HypotheticalRatesFootnote,     '\n');
-    std::getline(is, SalesLoadRefundFootnote,       '\n');
-    std::getline(is, NoLapseFootnote,               '\n');
-    std::getline(is, MarketValueAdjFootnote,        '\n');
-    std::getline(is, ExchangeChargeFootnote0,       '\n');
-    std::getline(is, CurrentValuesFootnote,         '\n');
-    std::getline(is, DBOption1Footnote,             '\n');
-    std::getline(is, DBOption2Footnote,             '\n');
-    std::getline(is, ExpRatRiskChargeFootnote,      '\n');
-    std::getline(is, ExchangeChargeFootnote1,       '\n');
-    std::getline(is, FlexiblePremiumFootnote,       '\n');
-    std::getline(is, GuaranteedValuesFootnote,      '\n');
-    std::getline(is, CreditingRateFootnote,         '\n');
-    std::getline(is, MecFootnote,                   '\n');
-    std::getline(is, MidpointValuesFootnote,        '\n');
-    std::getline(is, SinglePremiumFootnote,         '\n');
-    std::getline(is, MonthlyChargesFootnote,        '\n');
-    std::getline(is, UltCreditingRateFootnote,      '\n');
-    std::getline(is, MaxNaarFootnote,               '\n');
-    std::getline(is, PremTaxSurrChgFootnote,        '\n');
-    std::getline(is, PolicyFeeFootnote,             '\n');
-    std::getline(is, AssetChargeFootnote,           '\n');
-    std::getline(is, InvestmentIncomeFootnote,      '\n');
-    std::getline(is, IrrDbFootnote,                 '\n');
-    std::getline(is, IrrCsvFootnote,                '\n');
-    std::getline(is, MortalityChargesFootnote,      '\n');
-    std::getline(is, LoanAndWithdrawalFootnote,     '\n');
-    std::getline(is, PresaleTrackingNumber,         '\n');
-    std::getline(is, CompositeTrackingNumber,       '\n');
-    std::getline(is, InforceTrackingNumber,         '\n');
-    std::getline(is, InforceCompositeTrackingNumber,'\n');
-    std::getline(is, InforceNonGuaranteedFootnote0, '\n');
-    std::getline(is, InforceNonGuaranteedFootnote1, '\n');
-    std::getline(is, InforceNonGuaranteedFootnote2, '\n');
-    std::getline(is, InforceNonGuaranteedFootnote3, '\n');
-    std::getline(is, NonGuaranteedFootnote,         '\n');
-    std::getline(is, MonthlyChargesPaymentFootnote, '\n');
+namespace detail
+{
+void set_element(xml::element& parent, std::string const& name, std::string const& value)
+{
+    xml::element node(name.c_str());
+    node.push_back(xml::node(xml::node::text(value_cast<std::string>(value).c_str())));
+    parent.push_back(node);
+}
 
-    bool okay = is.good();
-    if(!okay)
+// Undesirable string copy...
+std::string get_element(xml::element const& parent, std::string const& name)
+{
+    xml::node::const_iterator i = parent.find(name.c_str());
+    if(parent.end() == i)
         {
         fatal_error()
-            << "Unexpected end of product data file '"
-            << a_Filename
-            << "'. Try reinstalling."
+            << "Required element '"
+            << name
+            << "' is missing."
             << LMI_FLUSH
             ;
         }
-    std::string dummy;
-    is >> dummy;
-    okay = is.eof();
-    if(!okay)
+#if 0
+        value = value_cast<T>(xml_lmi::get_content(*i));
+#endif // 0
+    return xml_lmi::get_content(*i);
+}
+} // Namespace detail.
+
+    template<typename T>
+    void set_element(xml::element& parent, std::string const& name, T const& value)
+    {
+        detail::set_element(parent, name, value_cast<std::string>(value));
+    }
+
+    template<typename T>
+    void get_element(xml::element const& parent, std::string const& name, T& value)
+    {
+        value = value_cast<T>(detail::get_element(parent, name));
+    }
+
+//============================================================================
+void TProductData::Read(std::string const& a_Filename)
+{
+    if(access(a_Filename.c_str(), R_OK))
         {
         fatal_error()
-            << "Data past expected end of product data file '"
+            << "File '"
             << a_Filename
-            << "'. Try reinstalling."
+            << "' is required but could not be found. Try reinstalling."
             << LMI_FLUSH
             ;
         }
+
+    xml_lmi::dom_parser parser(a_Filename);
+    xml::element const& root = parser.root_node("product");
+
+    #define GET_PROP(name) get_element(root, #name, name)
+
+    GET_PROP(DatabaseFilename);
+    GET_PROP(FundFilename);
+    GET_PROP(CorridorFilename);
+    GET_PROP(CurrCOIFilename);
+    GET_PROP(GuarCOIFilename);
+    GET_PROP(WPFilename);
+    GET_PROP(ADDFilename);
+    GET_PROP(ChildRiderFilename);
+    GET_PROP(CurrSpouseRiderFilename);
+    GET_PROP(GuarSpouseRiderFilename);
+    GET_PROP(CurrTermFilename);
+    GET_PROP(GuarTermFilename);
+    GET_PROP(TableYFilename);
+    GET_PROP(PremTaxFilename);
+    GET_PROP(TAMRA7PayFilename);
+    GET_PROP(TgtPremFilename);
+    GET_PROP(IRC7702Filename);
+    GET_PROP(Gam83Filename);
+    GET_PROP(SubstdTblMultFilename);
+    GET_PROP(CurrSpecAmtLoadFilename);
+    GET_PROP(GuarSpecAmtLoadFilename);
+    GET_PROP(RoundingFilename);
+    GET_PROP(TierFilename);
+    GET_PROP(PolicyForm);
+    GET_PROP(PolicyMktgName);
+    GET_PROP(PolicyLegalName);
+    GET_PROP(InsCoShortName);
+    GET_PROP(InsCoName);
+    GET_PROP(InsCoAddr);
+    GET_PROP(InsCoStreet);
+    GET_PROP(InsCoPhone);
+    GET_PROP(InsCoDomicile);
+    GET_PROP(MainUnderwriter);
+    GET_PROP(MainUnderwriterAddress);
+    GET_PROP(CoUnderwriter);
+    GET_PROP(CoUnderwriterAddress);
+    GET_PROP(AvName);
+    GET_PROP(CsvName);
+    GET_PROP(CsvHeaderName);
+    GET_PROP(NoLapseProvisionName);
+    GET_PROP(InterestDisclaimer);
+    GET_PROP(GuarMortalityFootnote);
+    GET_PROP(AccountValueFootnote);
+    GET_PROP(AttainedAgeFootnote);
+    GET_PROP(CashSurrValueFootnote);
+    GET_PROP(DeathBenefitFootnote);
+    GET_PROP(InitialPremiumFootnote);
+    GET_PROP(NetPremiumFootnote);
+    GET_PROP(OutlayFootnote);
+    GET_PROP(PolicyYearFootnote);
+    GET_PROP(ADDFootnote);
+    GET_PROP(ChildFootnote);
+    GET_PROP(SpouseFootnote);
+    GET_PROP(TermFootnote);
+    GET_PROP(WaiverFootnote);
+    GET_PROP(MinimumPremiumFootnote);
+    GET_PROP(PremAllocationFootnote);
+    GET_PROP(ProductDescription);
+    GET_PROP(StableValueFootnote);
+    GET_PROP(NoVanishPremiumFootnote);
+    GET_PROP(RejectPremiumFootnote);
+    GET_PROP(ExpRatingFootnote);
+    GET_PROP(MortalityBlendFootnote);
+    GET_PROP(HypotheticalRatesFootnote);
+    GET_PROP(SalesLoadRefundFootnote);
+    GET_PROP(NoLapseFootnote);
+    GET_PROP(MarketValueAdjFootnote);
+    GET_PROP(ExchangeChargeFootnote0);
+    GET_PROP(CurrentValuesFootnote);
+    GET_PROP(DBOption1Footnote);
+    GET_PROP(DBOption2Footnote);
+    GET_PROP(ExpRatRiskChargeFootnote);
+    GET_PROP(ExchangeChargeFootnote1);
+    GET_PROP(FlexiblePremiumFootnote);
+    GET_PROP(GuaranteedValuesFootnote);
+    GET_PROP(CreditingRateFootnote);
+    GET_PROP(MecFootnote);
+    GET_PROP(MidpointValuesFootnote);
+    GET_PROP(SinglePremiumFootnote);
+    GET_PROP(MonthlyChargesFootnote);
+    GET_PROP(UltCreditingRateFootnote);
+    GET_PROP(MaxNaarFootnote);
+    GET_PROP(PremTaxSurrChgFootnote);
+    GET_PROP(PolicyFeeFootnote);
+    GET_PROP(AssetChargeFootnote);
+    GET_PROP(InvestmentIncomeFootnote);
+    GET_PROP(IrrDbFootnote);
+    GET_PROP(IrrCsvFootnote);
+    GET_PROP(MortalityChargesFootnote);
+    GET_PROP(LoanAndWithdrawalFootnote);
+    GET_PROP(PresaleTrackingNumber);
+    GET_PROP(CompositeTrackingNumber);
+    GET_PROP(InforceTrackingNumber);
+    GET_PROP(InforceCompositeTrackingNumber);
+    GET_PROP(InforceNonGuaranteedFootnote0);
+    GET_PROP(InforceNonGuaranteedFootnote1);
+    GET_PROP(InforceNonGuaranteedFootnote2);
+    GET_PROP(InforceNonGuaranteedFootnote3);
+    GET_PROP(NonGuaranteedFootnote);
+    GET_PROP(MonthlyChargesPaymentFootnote);
+
+    #undef GET_PROP
 }
 
 //============================================================================
 void TProductData::Write(std::string const& a_Filename) const
 {
-    std::ofstream os(a_Filename.c_str());
-
-    os << DatabaseFilename              << '\n';
-    os << FundFilename                  << '\n';
-    os << CorridorFilename              << '\n';
-    os << CurrCOIFilename               << '\n';
-    os << GuarCOIFilename               << '\n';
-    os << WPFilename                    << '\n';
-    os << ADDFilename                   << '\n';
-    os << ChildRiderFilename            << '\n';
-    os << CurrSpouseRiderFilename       << '\n';
-    os << GuarSpouseRiderFilename       << '\n';
-    os << CurrTermFilename              << '\n';
-    os << GuarTermFilename              << '\n';
-    os << TableYFilename                << '\n';
-    os << PremTaxFilename               << '\n';
-    os << TAMRA7PayFilename             << '\n';
-    os << TgtPremFilename               << '\n';
-    os << IRC7702Filename               << '\n';
-    os << Gam83Filename                 << '\n';
-    os << SubstdTblMultFilename         << '\n';
-    os << CurrSpecAmtLoadFilename       << '\n';
-    os << GuarSpecAmtLoadFilename       << '\n';
-    os << RoundingFilename              << '\n';
-    os << TierFilename                  << '\n';
-    os << PolicyForm                    << '\n';
-    os << PolicyMktgName                << '\n';
-    os << PolicyLegalName               << '\n';
-    os << InsCoShortName                << '\n';
-    os << InsCoName                     << '\n';
-    os << InsCoAddr                     << '\n';
-    os << InsCoStreet                   << '\n';
-    os << InsCoPhone                    << '\n';
-    os << InsCoDomicile                 << '\n';
-    os << MainUnderwriter               << '\n';
-    os << MainUnderwriterAddress        << '\n';
-    os << CoUnderwriter                 << '\n';
-    os << CoUnderwriterAddress          << '\n';
-    os << AvName                        << '\n';
-    os << CsvName                       << '\n';
-    os << CsvHeaderName                 << '\n';
-    os << NoLapseProvisionName          << '\n';
-    os << InterestDisclaimer            << '\n';
-    os << GuarMortalityFootnote         << '\n';
-    os << AccountValueFootnote          << '\n';
-    os << AttainedAgeFootnote           << '\n';
-    os << CashSurrValueFootnote         << '\n';
-    os << DeathBenefitFootnote          << '\n';
-    os << InitialPremiumFootnote        << '\n';
-    os << NetPremiumFootnote            << '\n';
-    os << OutlayFootnote                << '\n';
-    os << PolicyYearFootnote            << '\n';
-    os << ADDFootnote                   << '\n';
-    os << ChildFootnote                 << '\n';
-    os << SpouseFootnote                << '\n';
-    os << TermFootnote                  << '\n';
-    os << WaiverFootnote                << '\n';
-    os << MinimumPremiumFootnote        << '\n';
-    os << PremAllocationFootnote        << '\n';
-    os << ProductDescription            << '\n';
-    os << StableValueFootnote           << '\n';
-    os << NoVanishPremiumFootnote       << '\n';
-    os << RejectPremiumFootnote         << '\n';
-    os << ExpRatingFootnote             << '\n';
-    os << MortalityBlendFootnote        << '\n';
-    os << HypotheticalRatesFootnote     << '\n';
-    os << SalesLoadRefundFootnote       << '\n';
-    os << NoLapseFootnote               << '\n';
-    os << MarketValueAdjFootnote        << '\n';
-    os << ExchangeChargeFootnote0       << '\n';
-    os << CurrentValuesFootnote         << '\n';
-    os << DBOption1Footnote             << '\n';
-    os << DBOption2Footnote             << '\n';
-    os << ExpRatRiskChargeFootnote      << '\n';
-    os << ExchangeChargeFootnote1       << '\n';
-    os << FlexiblePremiumFootnote       << '\n';
-    os << GuaranteedValuesFootnote      << '\n';
-    os << CreditingRateFootnote         << '\n';
-    os << MecFootnote                   << '\n';
-    os << MidpointValuesFootnote        << '\n';
-    os << SinglePremiumFootnote         << '\n';
-    os << MonthlyChargesFootnote        << '\n';
-    os << UltCreditingRateFootnote      << '\n';
-    os << MaxNaarFootnote               << '\n';
-    os << PremTaxSurrChgFootnote        << '\n';
-    os << PolicyFeeFootnote             << '\n';
-    os << AssetChargeFootnote           << '\n';
-    os << InvestmentIncomeFootnote      << '\n';
-    os << IrrDbFootnote                 << '\n';
-    os << IrrCsvFootnote                << '\n';
-    os << MortalityChargesFootnote      << '\n';
-    os << LoanAndWithdrawalFootnote     << '\n';
-    os << PresaleTrackingNumber         << '\n';
-    os << CompositeTrackingNumber       << '\n';
-    os << InforceTrackingNumber         << '\n';
-    os << InforceCompositeTrackingNumber<< '\n';
-    os << InforceNonGuaranteedFootnote0 << '\n';
-    os << InforceNonGuaranteedFootnote1 << '\n';
-    os << InforceNonGuaranteedFootnote2 << '\n';
-    os << InforceNonGuaranteedFootnote3 << '\n';
-    os << NonGuaranteedFootnote         << '\n';
-    os << MonthlyChargesPaymentFootnote << '\n';
-
-    if(!os.good())
-        {
+//    xml::document doc("product"); // Discuss with VS....
+//    xml::element& root = doc.get_root_node();
+    xml_lmi::xml_document document("product");
+    xml::element& root = document.root_node();
+
+    #define ADD_PROP(name) set_element(root, #name, name)
+
+    ADD_PROP(DatabaseFilename);
+    ADD_PROP(FundFilename);
+    ADD_PROP(CorridorFilename);
+    ADD_PROP(CurrCOIFilename);
+    ADD_PROP(GuarCOIFilename);
+    ADD_PROP(WPFilename);
+    ADD_PROP(ADDFilename);
+    ADD_PROP(ChildRiderFilename);
+    ADD_PROP(CurrSpouseRiderFilename);
+    ADD_PROP(GuarSpouseRiderFilename);
+    ADD_PROP(CurrTermFilename);
+    ADD_PROP(GuarTermFilename);
+    ADD_PROP(TableYFilename);
+    ADD_PROP(PremTaxFilename);
+    ADD_PROP(TAMRA7PayFilename);
+    ADD_PROP(TgtPremFilename);
+    ADD_PROP(IRC7702Filename);
+    ADD_PROP(Gam83Filename);
+    ADD_PROP(SubstdTblMultFilename);
+    ADD_PROP(CurrSpecAmtLoadFilename);
+    ADD_PROP(GuarSpecAmtLoadFilename);
+    ADD_PROP(RoundingFilename);
+    ADD_PROP(TierFilename);
+    ADD_PROP(PolicyForm);
+    ADD_PROP(PolicyMktgName);
+    ADD_PROP(PolicyLegalName);
+    ADD_PROP(InsCoShortName);
+    ADD_PROP(InsCoName);
+    ADD_PROP(InsCoAddr);
+    ADD_PROP(InsCoStreet);
+    ADD_PROP(InsCoPhone);
+    ADD_PROP(InsCoDomicile);
+    ADD_PROP(MainUnderwriter);
+    ADD_PROP(MainUnderwriterAddress);
+    ADD_PROP(CoUnderwriter);
+    ADD_PROP(CoUnderwriterAddress);
+    ADD_PROP(AvName);
+    ADD_PROP(CsvName);
+    ADD_PROP(CsvHeaderName);
+    ADD_PROP(NoLapseProvisionName);
+    ADD_PROP(InterestDisclaimer);
+    ADD_PROP(GuarMortalityFootnote);
+    ADD_PROP(AccountValueFootnote);
+    ADD_PROP(AttainedAgeFootnote);
+    ADD_PROP(CashSurrValueFootnote);
+    ADD_PROP(DeathBenefitFootnote);
+    ADD_PROP(InitialPremiumFootnote);
+    ADD_PROP(NetPremiumFootnote);
+    ADD_PROP(OutlayFootnote);
+    ADD_PROP(PolicyYearFootnote);
+    ADD_PROP(ADDFootnote);
+    ADD_PROP(ChildFootnote);
+    ADD_PROP(SpouseFootnote);
+    ADD_PROP(TermFootnote);
+    ADD_PROP(WaiverFootnote);
+    ADD_PROP(MinimumPremiumFootnote);
+    ADD_PROP(PremAllocationFootnote);
+    ADD_PROP(ProductDescription);
+    ADD_PROP(StableValueFootnote);
+    ADD_PROP(NoVanishPremiumFootnote);
+    ADD_PROP(RejectPremiumFootnote);
+    ADD_PROP(ExpRatingFootnote);
+    ADD_PROP(MortalityBlendFootnote);
+    ADD_PROP(HypotheticalRatesFootnote);
+    ADD_PROP(SalesLoadRefundFootnote);
+    ADD_PROP(NoLapseFootnote);
+    ADD_PROP(MarketValueAdjFootnote);
+    ADD_PROP(ExchangeChargeFootnote0);
+    ADD_PROP(CurrentValuesFootnote);
+    ADD_PROP(DBOption1Footnote);
+    ADD_PROP(DBOption2Footnote);
+    ADD_PROP(ExpRatRiskChargeFootnote);
+    ADD_PROP(ExchangeChargeFootnote1);
+    ADD_PROP(FlexiblePremiumFootnote);
+    ADD_PROP(GuaranteedValuesFootnote);
+    ADD_PROP(CreditingRateFootnote);
+    ADD_PROP(MecFootnote);
+    ADD_PROP(MidpointValuesFootnote);
+    ADD_PROP(SinglePremiumFootnote);
+    ADD_PROP(MonthlyChargesFootnote);
+    ADD_PROP(UltCreditingRateFootnote);
+    ADD_PROP(MaxNaarFootnote);
+    ADD_PROP(PremTaxSurrChgFootnote);
+    ADD_PROP(PolicyFeeFootnote);
+    ADD_PROP(AssetChargeFootnote);
+    ADD_PROP(InvestmentIncomeFootnote);
+    ADD_PROP(IrrDbFootnote);
+    ADD_PROP(IrrCsvFootnote);
+    ADD_PROP(MortalityChargesFootnote);
+    ADD_PROP(LoanAndWithdrawalFootnote);
+    ADD_PROP(PresaleTrackingNumber);
+    ADD_PROP(CompositeTrackingNumber);
+    ADD_PROP(InforceTrackingNumber);
+    ADD_PROP(InforceCompositeTrackingNumber);
+    ADD_PROP(InforceNonGuaranteedFootnote0);
+    ADD_PROP(InforceNonGuaranteedFootnote1);
+    ADD_PROP(InforceNonGuaranteedFootnote2);
+    ADD_PROP(InforceNonGuaranteedFootnote3);
+    ADD_PROP(NonGuaranteedFootnote);
+    ADD_PROP(MonthlyChargesPaymentFootnote);
+
+    #undef ADD_PROP
+
+    document.save(a_Filename);
+#if 0
+    if(!document.save(a_Filename))
+        { // Unreachable...
         fatal_error()
             << "Unable to write product data file '"
             << a_Filename
@@ -328,6 +397,7 @@
             << LMI_FLUSH
             ;
         }
+#endif // 0
 }
 
 //============================================================================
@@ -432,11 +502,11 @@
     foo.NonGuaranteedFootnote          = "";
     foo.MonthlyChargesPaymentFootnote  = "";
 
-    foo.DatabaseFilename = "sample.db4";
-    foo.FundFilename     = "sample.fnd";
-    foo.RoundingFilename = "sample.rnd";
-    foo.TierFilename     = "sample.tir";
+    foo.DatabaseFilename = "sample.xdb4";
+    foo.FundFilename     = "sample.xfnd";
+    foo.RoundingFilename = "sample.xrnd";
+    foo.TierFilename     = "sample.xtir";
 
-    foo.Write(AddDataDir("sample.pol"));
+    foo.Write(AddDataDir("sample.xpol"));
 }
 
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ihs_rnddata.cpp ./ihs_rnddata.cpp
--- /lmi/checkouts/current/lmi/ihs_rnddata.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./ihs_rnddata.cpp	2010-03-15 14:17:30.000000000 +0000
@@ -32,7 +32,12 @@
 
 #include "alert.hpp"
 #include "data_directory.hpp"
+#include "mc_enum.hpp"
+#include "mc_enum_types.hpp"
 #include "platform_dependent.hpp" // access()
+#include "xml_serialize.hpp"
+
+#include <xmlwrapp/document.h>
 
 #include <fstream>
 
@@ -65,8 +70,32 @@
     return dynamic_cast<rounding_rules&>(*this);
 }
 
+namespace xml_serialize
+{
+    template<>
+    struct xml_io< round_to<double> >
+    {
+        static void to_xml(xml::node& out, round_to<double> const& in)
+        {
+            set_element(out, "decimals",                    in.decimals() );
+            set_element(out, "style"   , mce_rounding_style(in.style   ()));
+        }
+
+        static void from_xml(xml::node const& in, round_to<double>& out)
+        {
+            int decimals;
+            mce_rounding_style style;
+            get_element(in, "decimals", decimals);
+            get_element(in, "style"   , style   );
+            out = round_to<double>(decimals, style.value());
+        }
+    };
+} // namespace xml_serialize
+
+#if 0
 namespace
 {
+    // for legacy file format, see ReadLegacy() below
     inline std::istream& operator>>(std::istream& is, round_to<double>& r)
         {
         int decimals;
@@ -77,25 +106,11 @@
         r = round_to<double>(decimals, style);
         return is;
         }
-    inline std::ostream& operator<<(std::ostream& os, round_to<double> const& r)
-        {
-        os << r.decimals() << '\n';
-        os << r.style() << '\n';
-        return os;
-        }
 } // Unnamed namespace.
 
 //============================================================================
-void StreamableRoundingRules::Read(std::string const& a_Filename)
+void StreamableRoundingRules::ReadLegacy(std::string const& a_Filename)
 {
-    if(access(a_Filename.c_str(), R_OK))
-        {
-        fatal_error()
-            << "File '"
-            << a_Filename
-            << "' is required but could not be found. Try reinstalling."
-            ;
-        }
     std::ifstream is(a_Filename.c_str());
 
     is >> round_specamt_;
@@ -136,28 +151,64 @@
             ;
         }
 }
+#endif // 0
+
+//============================================================================
+void StreamableRoundingRules::Read(std::string const& a_Filename)
+{
+    if(access(a_Filename.c_str(), R_OK))
+        {
+        fatal_error()
+            << "File '"
+            << a_Filename
+            << "' is required but could not be found. Try reinstalling."
+            ;
+        }
+
+    xml_lmi::dom_parser parser(a_Filename);
+    xml::element const& root = parser.root_node("rounding");
+
+    using namespace xml_serialize;
+    get_element(root, "specamt",          round_specamt_);
+    get_element(root, "death_benefit",    round_death_benefit_);
+    get_element(root, "naar",             round_naar_);
+    get_element(root, "coi_rate",         round_coi_rate_);
+    get_element(root, "coi_charge",       round_coi_charge_);
+    get_element(root, "gross_premium",    round_gross_premium_);
+    get_element(root, "net_premium",      round_net_premium_);
+    get_element(root, "interest_rate",    round_interest_rate_);
+    get_element(root, "interest_credit",  round_interest_credit_);
+    get_element(root, "withdrawal",       round_withdrawal_);
+    get_element(root, "loan",             round_loan_);
+    get_element(root, "corridor_factor",  round_corridor_factor_);
+    get_element(root, "surrender_charge", round_surrender_charge_);
+    get_element(root, "irr",              round_irr_);
+}
 
 //============================================================================
 void StreamableRoundingRules::Write(std::string const& a_Filename)
 {
-    std::ofstream os(a_Filename.c_str());
+    xml::document document("rounding");
+    xml::element& root = document.get_root_node();
+
+    using namespace xml_serialize;
 
-    os << round_specamt_;
-    os << round_death_benefit_;
-    os << round_naar_;
-    os << round_coi_rate_;
-    os << round_coi_charge_;
-    os << round_gross_premium_;
-    os << round_net_premium_;
-    os << round_interest_rate_;
-    os << round_interest_credit_;
-    os << round_withdrawal_;
-    os << round_loan_;
-    os << round_corridor_factor_;
-    os << round_surrender_charge_;
-    os << round_irr_;
+    set_element(root, "specamt",          round_specamt_);
+    set_element(root, "death_benefit",    round_death_benefit_);
+    set_element(root, "naar",             round_naar_);
+    set_element(root, "coi_rate",         round_coi_rate_);
+    set_element(root, "coi_charge",       round_coi_charge_);
+    set_element(root, "gross_premium",    round_gross_premium_);
+    set_element(root, "net_premium",      round_net_premium_);
+    set_element(root, "interest_rate",    round_interest_rate_);
+    set_element(root, "interest_credit",  round_interest_credit_);
+    set_element(root, "withdrawal",       round_withdrawal_);
+    set_element(root, "loan",             round_loan_);
+    set_element(root, "corridor_factor",  round_corridor_factor_);
+    set_element(root, "surrender_charge", round_surrender_charge_);
+    set_element(root, "irr",              round_irr_);
 
-    if(!os.good())
+    if(!document.save_to_file(a_Filename.c_str()))
         {
         fatal_error()
             << "Unable to write rounding file '"
@@ -172,6 +223,6 @@
 void StreamableRoundingRules::WriteRndFiles()
 {
     StreamableRoundingRules sample;
-    sample.Write(AddDataDir("sample.rnd"));
+    sample.Write(AddDataDir("sample.xrnd"));
 }
 
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/ihs_rnddata.hpp ./ihs_rnddata.hpp
--- /lmi/checkouts/current/lmi/ihs_rnddata.hpp	2010-01-10 15:39:30.039906000 +0000
+++ ./ihs_rnddata.hpp	2010-03-07 20:21:36.000000000 +0000
@@ -45,13 +45,11 @@
 
     rounding_rules const& get_rounding_rules();
 
-  protected:
-    void Init(std::string const& a_Filename);
-    void Read(std::string const& a_Filename);
-
   private:
     StreamableRoundingRules();
 
+    void Init(std::string const& a_Filename);
+    void Read(std::string const& a_Filename);
     void Write(std::string const& a_Filename);
 };
 
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/main_wx.cpp ./main_wx.cpp
--- /lmi/checkouts/current/lmi/main_wx.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./main_wx.cpp	2010-03-07 00:16:38.000000000 +0000
@@ -362,9 +362,9 @@
     new(wx) wxDocTemplate
         (doc_manager_
         ,"Database"
-        ,"*.db4"
+        ,"*.xdb4"
         ,""
-        ,"db4"
+        ,"xdb4"
         ,"Database document"
         ,"Database view"
         ,CLASSINFO(DatabaseDocument)
@@ -374,9 +374,9 @@
     new(wx) wxDocTemplate
         (doc_manager_
         ,"Policy"
-        ,"*.pol"
+        ,"*.xpol"
         ,""
-        ,"pol"
+        ,"xpol"
         ,"Policy document"
         ,"Policy view"
         ,CLASSINFO(PolicyDocument)
@@ -386,9 +386,9 @@
     new(wx) wxDocTemplate
         (doc_manager_
         ,"Rounding"
-        ,"*.rnd"
+        ,"*.xrnd"
         ,""
-        ,"rnd"
+        ,"xrnd"
         ,"Rounding document"
         ,"Rounding view"
         ,CLASSINFO(RoundingDocument)
@@ -398,9 +398,9 @@
     new(wx) wxDocTemplate
         (doc_manager_
         ,"Tier"
-        ,"*.tir"
+        ,"*.xtir"
         ,""
-        ,"tir"
+        ,"xtir"
         ,"Tier document"
         ,"Tier view"
         ,CLASSINFO(TierDocument)
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/my_db.cpp ./my_db.cpp
--- /lmi/checkouts/current/lmi/my_db.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./my_db.cpp	2010-03-04 15:37:03.115381300 +0000
@@ -53,7 +53,7 @@
     Add(TDBValue(DB_GuarPolFee, 10.00));
     // etc.
 // Not necessary for 'sample' product only, because it's built in.
-//  WriteDB(AddDataDir("sample.db4"));
+//  WriteDB(AddDataDir("sample.xdb4"));
   }
   // Another policy form....
 }
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/my_fund.cpp ./my_fund.cpp
--- /lmi/checkouts/current/lmi/my_fund.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./my_fund.cpp	2010-03-04 15:37:03.115381300 +0000
@@ -50,14 +50,14 @@
     // Sample product.
     FundData foo;
 // Not necessary for 'sample' product only, because it's built in.
-//    foo->Write(AddDataDir("sample.fnd"));
+//    foo->Write(AddDataDir("sample.xfnd"));
     }
 #if 0 // Template for other products.
     {
     // Another product.
     FundData foo;
     foo.FundInfo_.push_back(FundInfo(70, "Short Name", "Long Fund Name"));
-    foo.Write(AddDataDir("another_product.fnd"));
+    foo.Write(AddDataDir("another_product.xfnd"));
     }
 #endif // 0
 }
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/my_prod.cpp ./my_prod.cpp
--- /lmi/checkouts/current/lmi/my_prod.cpp	2010-01-20 20:30:51.857855000 +0000
+++ ./my_prod.cpp	2010-03-04 15:37:03.115381300 +0000
@@ -151,12 +151,12 @@
     foo.MonthlyChargesPaymentFootnote  = "";
 
     // Sample policy form.
-    foo.DatabaseFilename  = "sample.db4";
-    foo.FundFilename      = "sample.fnd";
-    foo.RoundingFilename  = "sample.rnd";
-    foo.TierFilename      = "sample.tir";
+    foo.DatabaseFilename  = "sample.xdb4";
+    foo.FundFilename      = "sample.xfnd";
+    foo.RoundingFilename  = "sample.xrnd";
+    foo.TierFilename      = "sample.xtir";
 
-    foo.Write(AddDataDir("sample.pol"));
+    foo.Write(AddDataDir("sample.xpol"));
 
     // Another policy form....
 }
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/my_rnd.cpp ./my_rnd.cpp
--- /lmi/checkouts/current/lmi/my_rnd.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./my_rnd.cpp	2010-03-04 15:37:03.115381300 +0000
@@ -68,7 +68,7 @@
     sample.round_surrender_charge_= round_to<double>(2, r_to_nearest);
     sample.round_irr_             = round_to<double>(5, r_downward  );
 
-    sample.Write(AddDataDir("sample.rnd"));
+    sample.Write(AddDataDir("sample.xrnd"));
 
     // Another policy form....
 }
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/my_tier.cpp ./my_tier.cpp
--- /lmi/checkouts/current/lmi/my_tier.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./my_tier.cpp	2010-03-04 15:37:03.115381300 +0000
@@ -56,7 +56,7 @@
     foo.raw_entity(e_curr_sepacct_load_tiered_by_assets   ).limits_.push_back(DBL_MAX);
 
 // Not necessary for 'sample' product only, because it's built in.
-//    foo.write(AddDataDir("sample.tir"));
+//    foo.write(AddDataDir("sample.xtir"));
 
     // Another policy form....
 }
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/objects.make ./objects.make
--- /lmi/checkouts/current/lmi/objects.make	2010-03-16 01:57:53.995290000 +0000
+++ ./objects.make	2010-03-13 11:49:30.000000000 +0000
@@ -19,7 +19,7 @@
 # email: <gchicares@sbcglobal.net>
 # snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
-# $Id: objects.make 4783 2010-03-16 01:57:53Z chicares $
+# $Id: objects.make 4729 2010-01-10 15:39:30Z chicares $
 
 ################################################################################
 
@@ -278,12 +278,10 @@
   ihs_database.o \
   ihs_dbdict.o \
   ihs_dbvalue.o \
-  ihs_fpios.o \
   ihs_funddata.o \
   ihs_irc7702.o \
   ihs_irc7702a.o \
   ihs_mortal.o \
-  ihs_pios.o \
   ihs_proddata.o \
   ihs_rnddata.o \
   md5.o \
@@ -391,10 +389,8 @@
   ihs_database.o \
   ihs_dbdict.o \
   ihs_dbvalue.o \
-  ihs_fpios.o \
   ihs_funddata.o \
   ihs_mortal.o \
-  ihs_pios.o \
   ihs_proddata.o \
   ihs_rnddata.o \
   input.o \
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/product_names.cpp ./product_names.cpp
--- /lmi/checkouts/current/lmi/product_names.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./product_names.cpp	2010-03-04 15:37:03.131006000 +0000
@@ -44,7 +44,7 @@
     fs::directory_iterator end_i;
     for(; i != end_i; ++i)
         {
-        if(is_directory(*i) || ".pol" != fs::extension(*i))
+        if(is_directory(*i) || (".xpol" != fs::extension(*i) && ".pol" != fs::extension(*i)))
             {
             continue;
             }
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/product_names.hpp ./product_names.hpp
--- /lmi/checkouts/current/lmi/product_names.hpp	2010-01-10 15:39:30.039906000 +0000
+++ ./product_names.hpp	2010-03-04 15:37:03.131006000 +0000
@@ -29,7 +29,7 @@
 #include <string>
 #include <vector>
 
-/// Base names of policy ('.pol') files found in data directory.
+/// Base names of policy ('.xpol') files found in data directory.
 /// They are read only once and cached: see documentation for
 /// class ce_product_name.
 
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/stratified_charges.cpp ./stratified_charges.cpp
--- /lmi/checkouts/current/lmi/stratified_charges.cpp	2010-01-10 15:39:30.039906000 +0000
+++ ./stratified_charges.cpp	2010-03-15 14:17:36.000000000 +0000
@@ -34,6 +34,12 @@
 #include "miscellany.hpp"         // minmax<T>()
 #include "platform_dependent.hpp" // access()
 #include "stratified_algorithms.hpp"
+#include "xml_serialize.hpp"
+
+#include <boost/filesystem/convenience.hpp>
+#include <boost/static_assert.hpp>
+
+#include <xmlwrapp/document.h>
 
 #include <algorithm>
 #include <cfloat>                 // DBL_MAX
@@ -114,7 +120,8 @@
 }
 
 //============================================================================
-void stratified_entity::read(std::istream& is)
+#if 0
+void stratified_entity::read_legacy(std::istream& is)
 {
     std::vector<double>::size_type vector_size;
     std::vector<double>::value_type z;
@@ -143,39 +150,29 @@
 }
 
 //============================================================================
-void stratified_entity::write(std::ostream& os) const
+std::istream& operator>>(std::istream& is, stratified_entity& z)
 {
-    assert_validity();
-
-    typedef std::vector<double>::const_iterator svdci;
-
-    os << values_.size() << " ";
-    for(svdci i = values_.begin(); i < values_.end(); ++i)
-        {
-        os << (*i) << " ";
-        }
-    os << '\n';
-
-    os << limits_.size() << " ";
-    for(svdci i = limits_.begin(); i < limits_.end(); ++i)
-        {
-        os << (*i) << " ";
-        }
-    os << '\n';
+    z.read_legacy(is);
+    return is;
 }
+#endif // 0
 
 //============================================================================
-std::istream& operator>>(std::istream& is, stratified_entity& z)
+void stratified_entity::read(xml::element const& node)
 {
-    z.read(is);
-    return is;
+    xml_serialize::get_element(node, "values", values_);
+    xml_serialize::get_element(node, "limits", limits_);
+
+    assert_validity();
 }
 
 //============================================================================
-std::ostream& operator<<(std::ostream& os, stratified_entity const& z)
+void stratified_entity::write(xml::element& node) const
 {
-    z.write(os);
-    return os;
+    assert_validity();
+
+    xml_serialize::set_element(node, "values", values_);
+    xml_serialize::set_element(node, "limits", limits_);
 }
 
 // Class stratified_charges implementation.
@@ -459,6 +456,58 @@
 }
 
 //============================================================================
+namespace
+{
+    char const* e_stratified_nodes[] =
+        {"stratified_first"
+
+        ,"topic_premium_banded"
+        ,"curr_sepacct_load_banded_by_premium"
+        ,"guar_sepacct_load_banded_by_premium"
+
+        ,"topic_asset_tiered"
+        ,"curr_m_and_e_tiered_by_assets"
+        ,"guar_m_and_e_tiered_by_assets"
+        ,"asset_based_comp_tiered_by_assets"
+        ,"investment_mgmt_fee_tiered_by_assets"
+        ,"curr_sepacct_load_tiered_by_assets"
+        ,"guar_sepacct_load_tiered_by_assets"
+
+        ,"topic_tiered_premium_tax"
+        ,"tiered_ak_premium_tax"
+        ,"tiered_de_premium_tax"
+        ,"tiered_sd_premium_tax"
+
+        ,"stratified_last"
+        };
+
+    BOOST_STATIC_ASSERT(e_stratified_last+1 == sizeof e_stratified_nodes / sizeof(char const*));
+} // anonymous namespace
+
+namespace xml_serialize
+{
+    template<>
+    struct xml_io<stratified_entity>
+    {
+        static void to_xml(xml::node& out, stratified_entity const& in)
+        {
+            in.write(out);
+        }
+
+        static void from_xml(xml::node const& in, stratified_entity& out)
+        {
+            out.read(in);
+        }
+    };
+} // namespace xml_serialize
+
+//============================================================================
+void stratified_charges::read_entity(xml::element const& node, e_stratified e)
+{
+    xml_serialize::get_element(node, e_stratified_nodes[e], raw_entity(e));
+}
+
+//============================================================================
 void stratified_charges::read(std::string const& filename)
 {
     if(access(filename.c_str(), R_OK))
@@ -471,6 +520,25 @@
             ;
         }
 
+    xml_lmi::dom_parser parser(filename);
+    xml::element const& root = parser.root_node("tier");
+
+    read_entity(root, e_curr_sepacct_load_banded_by_premium  );
+    read_entity(root, e_guar_sepacct_load_banded_by_premium  );
+    read_entity(root, e_curr_m_and_e_tiered_by_assets        );
+    read_entity(root, e_guar_m_and_e_tiered_by_assets        );
+    read_entity(root, e_asset_based_comp_tiered_by_assets    );
+    read_entity(root, e_investment_mgmt_fee_tiered_by_assets );
+    read_entity(root, e_curr_sepacct_load_tiered_by_assets   );
+    read_entity(root, e_guar_sepacct_load_tiered_by_assets   );
+    read_entity(root, e_tiered_ak_premium_tax                );
+    read_entity(root, e_tiered_de_premium_tax                );
+    read_entity(root, e_tiered_sd_premium_tax                );
+}
+
+#if 0
+void stratified_charges::read_legacy(std::string const& filename)
+{
     std::ifstream is(filename.c_str());
 
     is >> raw_entity(e_curr_sepacct_load_banded_by_premium  );
@@ -507,25 +575,33 @@
             ;
         }
 }
+#endif // 0
+
+//============================================================================
+void stratified_charges::write_entity(xml::element& node, e_stratified e) const
+{
+    xml_serialize::set_element(node, e_stratified_nodes[e], raw_entity(e));
+}
 
 //============================================================================
 void stratified_charges::write(std::string const& filename) const
 {
-    std::ofstream os(filename.c_str());
+    xml::document document("tier");
+    xml::element& root = document.get_root_node();
 
-    os << raw_entity(e_curr_sepacct_load_banded_by_premium  );
-    os << raw_entity(e_guar_sepacct_load_banded_by_premium  );
-    os << raw_entity(e_curr_m_and_e_tiered_by_assets        );
-    os << raw_entity(e_guar_m_and_e_tiered_by_assets        );
-    os << raw_entity(e_asset_based_comp_tiered_by_assets    );
-    os << raw_entity(e_investment_mgmt_fee_tiered_by_assets );
-    os << raw_entity(e_curr_sepacct_load_tiered_by_assets   );
-    os << raw_entity(e_guar_sepacct_load_tiered_by_assets   );
-    os << raw_entity(e_tiered_ak_premium_tax                );
-    os << raw_entity(e_tiered_de_premium_tax                );
-    os << raw_entity(e_tiered_sd_premium_tax                );
+    write_entity(root, e_curr_sepacct_load_banded_by_premium  );
+    write_entity(root, e_guar_sepacct_load_banded_by_premium  );
+    write_entity(root, e_curr_m_and_e_tiered_by_assets        );
+    write_entity(root, e_guar_m_and_e_tiered_by_assets        );
+    write_entity(root, e_asset_based_comp_tiered_by_assets    );
+    write_entity(root, e_investment_mgmt_fee_tiered_by_assets );
+    write_entity(root, e_curr_sepacct_load_tiered_by_assets   );
+    write_entity(root, e_guar_sepacct_load_tiered_by_assets   );
+    write_entity(root, e_tiered_ak_premium_tax                );
+    write_entity(root, e_tiered_de_premium_tax                );
+    write_entity(root, e_tiered_sd_premium_tax                );
 
-    if(!os.good())
+    if(!document.save_to_file(filename.c_str()))
         {
         fatal_error()
             << "Unable to write stratified-data file '"
@@ -581,7 +657,7 @@
     foo.raw_entity(e_tiered_sd_premium_tax                ).limits_.push_back(100000.0);
     foo.raw_entity(e_tiered_sd_premium_tax                ).limits_.push_back(DBL_MAX);
 
-    foo.write(AddDataDir("sample.tir"));
+    foo.write(AddDataDir("sample.xtir"));
 }
 
 /// Determine whether a double is in effect the highest representable.
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/stratified_charges.hpp ./stratified_charges.hpp
--- /lmi/checkouts/current/lmi/stratified_charges.hpp	2010-01-10 15:39:30.039906000 +0000
+++ ./stratified_charges.hpp	2010-03-08 13:47:28.000000000 +0000
@@ -29,6 +29,7 @@
 #include "mc_enum_type_enums.hpp"
 #include "obstruct_slicing.hpp"
 #include "so_attributes.hpp"
+#include "xml_lmi_fwd.hpp"
 
 #include <iosfwd>
 #include <map>
@@ -74,8 +75,8 @@
         );
     ~stratified_entity();
 
-    void read (std::istream&);
-    void write(std::ostream&) const;
+    void read (xml::element const& node);
+    void write(xml::element&) const;
 
   private:
     void assert_validity() const;
@@ -149,8 +150,10 @@
 
     void initialize_dictionary();
 
-    void read (std::string const& filename);
-    void write(std::string const& filename) const;
+    void read        (std::string const& filename);
+    void write       (std::string const& filename) const;
+    void read_entity (xml::element const& node, e_stratified);
+    void write_entity(xml::element& node, e_stratified) const;
 
     double banded_curr_sepacct_load
         (double assets
diff -u3 -x ChangeLog -x xml_lmi.cpp -x xml_lmi.hpp -x xml_serialize.hpp -x xml_serialize_test.cpp /lmi/checkouts/current/lmi/workhorse.make ./workhorse.make
--- /lmi/checkouts/current/lmi/workhorse.make	2010-01-14 17:55:28.239636000 +0000
+++ ./workhorse.make	2010-03-15 23:38:46.000000000 +0000
@@ -853,6 +853,17 @@
 	@$(CP) --preserve --update $(help_files) $(data_dir)
 ifeq (,$(USE_SO_ATTRIBUTES))
 	@cd $(data_dir); $(bin_dir)/product_files$(EXEEXT)
+	@cd $(data_dir); for z in *.db4 *.fnd *.pol *.rnd *.tir; do mv $$z $${z/./.x}; done
+	@cd $(data_dir); for z in *.xpol; do sed -i $$z \
+	    -e'/DatabaseFilename/s/\.db4/.xdb4/' \
+	    -e'/FundFilename/s/\.fnd/.xfnd/' \
+	    -e'/RoundingFilename/s/\.rnd/.xrnd/' \
+	    -e'/TierFilename/s/\.tir/.xtir/' \
+	    ; done
+	@cd $(data_dir); for z in *.xdb4; do sed -i $$z \
+	    -e'/833333333333333/s/833333333333333</83333333333333333</' \
+	    -e'/997539797523562/s/997539797523562</9975397975235616</' \
+	    ; done
 else
 	@$(ECHO) "Can't build product_files$(EXEEXT) with USE_SO_ATTRIBUTES."
 endif
@@ -871,12 +882,12 @@
   qx_ins.dat \
   qx_ins.ndx \
   sample.dat \
-  sample.db4 \
-  sample.fnd \
+  sample.xdb4 \
+  sample.xfnd \
   sample.ndx \
-  sample.pol \
-  sample.rnd \
-  sample.tir \
+  sample.xpol \
+  sample.xrnd \
+  sample.xtir \
 
 .PHONY: archive_shared_data_files
 archive_shared_data_files:
@@ -960,7 +971,7 @@
 # one file of each given type.
 
 fardel_checksummed_files = \
-  *.dat *.db4 *.fnd *.ndx *.pol *.rnd *.tir \
+  *.dat *.xdb4 *.xfnd *.ndx *.xpol *.xrnd *.xtir \
   configurable_settings.xml \
   expiry \
   md5sum$(EXEEXT) \
@@ -999,12 +1010,12 @@
 .PHONY: test
 test: $(test_targets)
 
-# Some test targets require 'sample.pol' to exist even though they
+# Some test targets require 'sample.xpol' to exist even though they
 # don't actually read its contents.
 
-$(test_targets): sample.pol
+$(test_targets): sample.xpol
 
-sample.pol:
+sample.xpol:
 	@$(TOUCH) $@
 
 ################################################################################
Only in .: xml_formats_20100316.patch
