lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [5380] Mark some taxation issues


From: Greg Chicares
Subject: [lmi-commits] [5380] Mark some taxation issues
Date: Wed, 25 Jan 2012 15:19:23 +0000

Revision: 5380
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5380
Author:   chicares
Date:     2012-01-25 15:19:23 +0000 (Wed, 25 Jan 2012)
Log Message:
-----------
Mark some taxation issues

Modified Paths:
--------------
    lmi/trunk/ihs_acctval.cpp
    lmi/trunk/ihs_avmly.cpp
    lmi/trunk/ihs_basicval.cpp
    lmi/trunk/ihs_irc7702.cpp
    lmi/trunk/ihs_irc7702.hpp
    lmi/trunk/ihs_irc7702a.cpp
    lmi/trunk/ihs_irc7702a.hpp

Modified: lmi/trunk/ihs_acctval.cpp
===================================================================
--- lmi/trunk/ihs_acctval.cpp   2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_acctval.cpp   2012-01-25 15:19:23 UTC (rev 5380)
@@ -460,6 +460,7 @@
         ,InvariantValues().SpecAmt[0]
         );
     // It is at best superfluous to do this for every basis.
+    // TAXATION !! Don't do that then.
     Irc7702_->Initialize7702
         (InvariantValues().SpecAmt[0] + InvariantValues().TermSpecAmt[0]
         ,InvariantValues().SpecAmt[0] + InvariantValues().TermSpecAmt[0]
@@ -472,7 +473,7 @@
 
     // This is notionally called once per *current*-basis run
     // and actually called once per run, with calculations suppressed
-    // for all other bases. TODO ?? How should we handle MEC-avoid
+    // for all other bases. TODO ?? TAXATION !! How should we handle MEC-avoid
     // solves on bases other than current?
 
     InvariantValues().InforceYear  = yare_input_.InforceYear;
@@ -504,7 +505,8 @@
     if(0 == InforceYear && 0 == InforceMonth)
         {
         // No need to initialize 'pmts_7702a' in this case.
-        // This assumes the term rider can be treated as death benefit.
+        // TAXATION !! This assumes the term rider can be treated as death 
benefit.
+        // TAXATION !! DATABASE !! That should be a database flag.
         bfts_7702a.push_back
             (   InvariantValues().SpecAmt[0]
             +   InvariantValues().TermSpecAmt[0]
@@ -520,6 +522,10 @@
             ,std::back_inserter(pmts_7702a)
             );
         // Specamt history starts at policy year zero and must be offset.
+        // TAXATION !! That's wrong, because contract-year history cannot
+        // generally be obtained from policy-year history by any integral
+        // offset; but doesn't LDB provide all the information required,
+        // if only it were used in preference to this?
         int const offset = duration_ceiling
             (yare_input_.EffectiveDate
             ,yare_input_.LastMaterialChangeDate
@@ -533,7 +539,7 @@
     double lowest_death_benefit = yare_input_.InforceLeastDeathBenefit;
     if(0 == InforceYear && 0 == InforceMonth)
         {
-        lowest_death_benefit = bfts_7702a.front();
+        lowest_death_benefit = bfts_7702a.front(); // TAXATION !! See 
above--use input LDB instead.
         }
     Irc7702A_->Initialize7702A
         (mce_run_gen_curr_sep_full != RunBasis_
@@ -545,11 +551,13 @@
         ,yare_input_.InforceContractYear
         ,yare_input_.InforceContractMonth
         ,yare_input_.InforceAvBeforeLastMc
-        ,lowest_death_benefit
+        ,lowest_death_benefit // TAXATION !! See above--use input LDB instead.
         ,pmts_7702a
         ,bfts_7702a
         );
 
+    //  TAXATION !! Move this before 7702 and 7702A stuff, to make it
+    // harder to overlook.
     daily_interest_accounting = contains
         (yare_input_.Comments
         ,"idiosyncrasy_daily_interest_accounting"
@@ -587,7 +595,7 @@
 {
     // These inforce things belong in input struct.
     // TODO ?? The list is not complete; others will be required:
-    // payment history; surrender charges; DCV history?
+    // payment history; surrender charges; DCV history? TAXATION !! Resolve 
this.
     InforceYear                 = yare_input_.InforceYear                    ;
     InforceMonth                = yare_input_.InforceMonth                   ;
     InforceAVGenAcct            = yare_input_.InforceGeneralAccountValue     ;
@@ -604,7 +612,7 @@
     Month                       = InforceMonth;
     CoordinateCounters();
 
-    DB7702A                     = 0.0;  // TODO ?? This seems silly.
+    DB7702A                     = 0.0;  // TODO ?? TAXATION !! This seems 
silly.
 
     AVRegLn                     = InforceAVRegLn;
     AVPrfLn                     = InforceAVPrfLn;
@@ -895,7 +903,7 @@
 
     PremiumTax_->start_new_year();
     // Skip this in an incomplete initial inforce year.
-    // Premium tax should perhaps be handled similarly.
+    // TAXATION !! Premium tax should perhaps be handled similarly.
     if(Year != InforceYear || 0 == InforceMonth)
         {
         Irc7702_ ->UpdateBOY7702();
@@ -1495,6 +1503,9 @@
 */
     YearsTotLoadTgt         = Loads_->target_total_load     (GenBasis_)[Year];
     YearsTotLoadExc         = Loads_->excess_total_load     (GenBasis_)[Year];
+    // TAXATION !! This '_lowest_premium_tax' approach needs to be
+    // reworked: there should be an option (at least) to use the
+    // current tax rates.
     YearsTotLoadTgtLowestPremtax = 
Loads_->target_premium_load_7702_lowest_premium_tax()[Year];
     YearsTotLoadExcLowestPremtax = 
Loads_->excess_premium_load_7702_lowest_premium_tax()[Year];
     YearsPremLoadTgt        = Loads_->target_premium_load   (GenBasis_)[Year];

Modified: lmi/trunk/ihs_avmly.cpp
===================================================================
--- lmi/trunk/ihs_avmly.cpp     2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_avmly.cpp     2012-01-25 15:19:23 UTC (rev 5380)
@@ -121,8 +121,9 @@
     TxTakeWD();
 
     TxTestGPT();
-    // TODO ?? Doesn't this mean dumpins and 1035s get ignored?
+    // TODO ?? TAXATION !! Doesn't this mean dumpins and 1035s get ignored?
     LMI_ASSERT(0.0 <= Dcv);
+    // TAXATION !! Is it really useful to comment the arguments here?
     Irc7702A_->UpdateBft7702A
         (Dcv
         ,DBReflectingCorr + TermDB // DB7702A
@@ -153,7 +154,7 @@
           + GetRefundableSalesLoad()
 //          + std::max(0.0, ExpRatReserve) // This would be added if it 
existed.
         );
-// TODO ?? Use CashValueFor7702() instead?
+// TODO ?? TAXATION !! Use CashValueFor7702() instead?
     double max_necessary_premium = Irc7702A_->MaxNecessaryPremium
         (Dcv
         ,AnnualTargetPrem
@@ -169,18 +170,22 @@
         ,kludge_account_value
         );
 
-    // Saved for monthly detail report only.
+    // Saved for monthly detail report only. TAXATION !! Then are
+    // these still needed...perhaps in order to report their values
+    // prior to accepting any payment?
     NetMaxNecessaryPremium   = Irc7702A_->DebugGetNetMaxNecPm  ();
     GrossMaxNecessaryPremium = Irc7702A_->DebugGetGrossMaxNecPm();
 
     TxAscertainDesiredPayment();
     TxLimitPayment(max_non_mec_premium);
 
+    // TAXATION !! This line recognizes a withdrawal for 7702A;
+    // shouldn't there be similar code here for GPT?
     if(0 == Month)
         {
         Irc7702A_->UpdatePmt7702A
             (Dcv
-            ,-NetWD
+            ,-NetWD // TAXATION !! This should be gross, not net.
             ,false
             ,AnnualTargetPrem
             ,YearsTotLoadTgtLowestPremtax
@@ -557,13 +562,15 @@
 //        return;
 //        }
 
+// TAXATION !! This condition, or a similar one, guards several GPT calls,
+// but not all (ProcessAdjustableEvent(), e.g.); should this be made uniform?
 // TODO ?? Perhaps this condition should be:
 //    if(!SolvingForGuarPremium && Solving || mce_run_gen_curr_sep_full == 
RunBasis_)
     if(Solving || mce_run_gen_curr_sep_full == RunBasis_)
         {
         if(!SolvingForGuarPremium)
             {
-            double fake_cum_pmt = 0.0; // TODO ?? Needs work.
+            double fake_cum_pmt = 0.0; // TODO ?? TAXATION !! Needs work.
             Irc7702_->ProcessGptPmt(Year, GrossPmts[Month], fake_cum_pmt);
             }
         // Limit external 1035 first, then internal, as necessary to avoid
@@ -603,13 +610,13 @@
     DBReflectingCorr = 0.0;
     TxSetDeathBft();
     TxSetTermAmt();
-    // TODO ?? Should 1035 exchanges be handled somewhere else?
+    // TODO ?? TAXATION !! Should 1035 exchanges be handled somewhere else?
     HOPEFULLY(0.0 == Dcv);
     Irc7702A_->Update1035Exch7702A
         (Dcv
         ,NetPmts[Month]
         ,ActualSpecAmt + TermSpecAmt
-//        ,DBReflectingCorr + TermDB
+//        ,DBReflectingCorr + TermDB // TAXATION !! Alternate if 7702A benefit 
is DB?
         );
 
     if(HoneymoonActive)
@@ -883,7 +890,10 @@
     OldSA = ActualSpecAmt + TermSpecAmt;
     OldDB = DBReflectingCorr + TermDB;
 
-    // TODO ?? CVAT only?
+    // TODO ?? CVAT only? TAXATION !! Consider whether and how 7702A
+    // functions should be guarded generally, with due regard to the
+    // definitional test chosen. This function probably should be
+    // called for GPT as well as CVAT.
     Irc7702A_->UpdateBOM7702A(Month);
 }
 
@@ -1060,7 +1070,7 @@
 
     ChangeSpecAmtBy(YearsSpecAmt - ActualSpecAmt);
 
-    // TODO ?? Should 7702 or 7702A processing be done here?
+    // TODO ?? TAXATION !! Should 7702 or 7702A processing be done here?
 }
 
 //============================================================================
@@ -1076,6 +1086,11 @@
  80000 guar
 if forceout needed, it will be higher for curr--OK
 but position could be reversed for variable policy with bad curr performance
+
+TAXATION !! Revisit those issues. Furthermore, should forceout really
+vary by basis? Probably not if it shows up only in an "outlay" column
+that's shared by all bases...but then what about the variable scenario
+mentioned above?
 */
 
     if(mce_gpt != DefnLifeIns_ || mce_run_gen_curr_sep_full != RunBasis_)
@@ -1127,6 +1142,7 @@
     //
     mcenum_dbopt_7702 const new_dbopt(effective_dbopt_7702(YearsDBOpt, 
Equiv7702DBO3));
     mcenum_dbopt_7702 const old_dbopt(effective_dbopt_7702(OldDBOpt  , 
Equiv7702DBO3));
+    // TAXATION !! This may require revision if DB is treated as the 7702 
benefit.
     bool adj_event =
             (
                 !materially_equal(OldSA, ActualSpecAmt + TermSpecAmt)
@@ -1136,7 +1152,8 @@
         ;
     if(adj_event)
         {
-        // TODO ?? Perhaps we should pass 'A' of 'A+B-C' for validation.
+        // TODO ?? TAXATION !! Perhaps we should pass 'A' of 'A+B-C' for 
validation.
+        // Or maybe not, because we can't match it if there was a plan change.
         Irc7702_->ProcessAdjustableEvent
             (Year
             ,DBReflectingCorr + TermDB
@@ -1150,7 +1167,7 @@
         }
 
     GptForceout = Irc7702_->Forceout();
-    // TODO ?? On other bases, nothing is forced out, and payments aren't 
limited.
+    // TODO ?? TAXATION !! On other bases, nothing is forced out, and payments 
aren't limited.
     process_distribution(GptForceout);
     YearsTotalGptForceout += GptForceout;
 
@@ -1167,7 +1184,7 @@
         Irc7702A_->InduceMaterialChange();
         }
 
-    // TODO ?? GPT--perform only if current basis?
+    // TODO ?? TAXATION !! GPT--perform only if current basis?
     OldDBOpt = YearsDBOpt;
 }
 
@@ -1231,7 +1248,7 @@
             // illustration-reg guaranteed premium.
             if(!SolvingForGuarPremium)
                 {
-                double fake_cum_pmt = 0.0; // TODO ?? Needs work.
+                double fake_cum_pmt = 0.0; // TODO ?? TAXATION !! Needs work.
                 Irc7702_->ProcessGptPmt(Year, eepmt, fake_cum_pmt);
                 }
             EeGrossPmts[Month] += eepmt;
@@ -1244,7 +1261,7 @@
             // illustration-reg guaranteed premium.
             if(!SolvingForGuarPremium)
                 {
-                double fake_cum_pmt = 0.0; // TODO ?? Needs work.
+                double fake_cum_pmt = 0.0; // TODO ?? TAXATION !! Needs work.
                 Irc7702_->ProcessGptPmt(Year, erpmt, fake_cum_pmt);
                 }
             ErGrossPmts[Month] += erpmt;
@@ -1277,7 +1294,7 @@
         // illustration-reg guaranteed premium.
         if(!SolvingForGuarPremium)
             {
-            double fake_cum_pmt = 0.0; // TODO ?? Needs work.
+            double fake_cum_pmt = 0.0; // TODO ?? TAXATION !! Needs work.
             Irc7702_->ProcessGptPmt(Year, Dumpin, fake_cum_pmt);
             }
         EeGrossPmts[Month] += Dumpin;
@@ -1287,6 +1304,8 @@
 }
 
 //============================================================================
+// TAXATION !! Should this be called for gpt? or, if it's called,
+// should it assert that it has no effect?
 void AccountValue::TxLimitPayment(double a_maxpmt)
 {
 // Subtract premium load from gross premium yielding net premium.
@@ -1294,7 +1313,7 @@
     // This is needed only for current-basis or solve-basis runs.
     // Otherwise we're doing too much work, and maybe doing things
     // we shouldn't.
-// TODO ?? Clean this up, and put GPT limit here, on prem net of WD.
+// TODO ?? TAXATION !! Clean this up, and put GPT limit here, on prem net of 
WD.
 
     HOPEFULLY(materially_equal(GrossPmts[Month], EeGrossPmts[Month] + 
ErGrossPmts[Month]));
 
@@ -1370,8 +1389,9 @@
         );
     LMI_ASSERT(0.0 <= Dcv);
 
-    // TODO ?? Not correct yet--need to test pmt less deductible WD; and
-    // shouldn't we deduct the *gross* WD?
+    // TODO ?? TAXATION !! Not correct yet--need to test pmt less deductible 
WD; and
+    // shouldn't we deduct the *gross* WD? [Yes, if any fee is part of the
+    // WD, which it normally is.]
     double amount_paid_7702A = a_pmt;
     Irc7702A_->UpdatePmt7702A
         (Dcv
@@ -1420,8 +1440,11 @@
     // TODO ?? This thing isn't really the tax basis as it should be
     // because we subtract all WDs without regard to taxability:
     // if WDs exceed basis, 7702A calculations are incorrect.
+    // TAXATION !! Fix this. Nontaxable WDs are handled much like
+    // GPT forceouts. Generally, WDs are nontaxable up to basis for
+    // non-MECs, except for 7702(f)(7)(B-E).
     TaxBasis += a_pmt;
-    // TODO ?? Save ee and er bases separately e.g. for split dollar;
+    // TODO ?? TAXATION !! Save ee and er bases separately e.g. for split 
dollar;
     // call them EeTaxBasis and ErTaxBasis.
 }
 
@@ -1575,12 +1598,16 @@
             }
         else
             {
+            // TAXATION !! We could at least change this in xrc help elements:
             // USER !! User documentation should explain that this
             // includes any 7702-integrated term rider.
             //
             // Some products have loads that depend on the initial
             // specified amount, which probably includes term; if it
             // doesn't, then a new input field would need to be added.
+            //
+            // TAXATION !! Is this really desirable? INPUT !! Should we
+            // instead capture specamt as of issue date for this purpose?
             z = yare_input_.SpecamtHistory.front();
             }
         SpecAmtLoadBase = std::max(z, NetPmts[Month] * YearsCorridorFactor);
@@ -1607,7 +1634,7 @@
 // Set death benefit reflecting corridor and death benefit option.
 void AccountValue::TxSetDeathBft(bool force_eoy_behavior)
 {
-    // TODO ?? Should 7702 or 7702A processing be done here?
+    // TODO ?? TAXATION !! Should 7702 or 7702A processing be done here?
     // If so, then this code may be useful:
 //    double prior_db_7702A = DB7702A;
 //    double prior_sa_7702A = ActualSpecAmt;
@@ -1689,6 +1716,7 @@
     DBReflectingCorr = round_death_benefit()(DBReflectingCorr);
     // This overrides the value assigned above. There's more than one
     // way to interpret 7702A "death benefit"; this is just one.
+    // TAXATION !! DATABASE !! Offer a choice of interpretations.
     DB7702A = DBReflectingCorr + TermDB;
 
     DcvDeathBft = std::max
@@ -1701,7 +1729,7 @@
                 )
             )
         );
-    // TODO ?? Should 7702 or 7702A processing be done here?
+    // TODO ?? TAXATION !! Should 7702 or 7702A processing be done here?
     // If so, then this code may be useful:
 /*
     // Try moving this here...
@@ -2625,15 +2653,15 @@
         }
 
     CumPmts     -= NetWD;
-    TaxBasis    -= NetWD;
+    TaxBasis    -= NetWD; // TODO ?? TAXATION !! This should be gross, not 
net; how about the line above and the line below?
     CumWD       += NetWD;
+    // TAXATION !! What about 7702A "amounts paid"?
 
     if(Solving || mce_run_gen_curr_sep_full == RunBasis_)
         {
         if(!SolvingForGuarPremium)
             {
             double fake_cum_pmt = 0.0; // TODO ?? Needs work.
-            // TODO ?? Should also use *gross* above in CumPmts etc.
             double premiums_paid_increment = -GrossWD;
             Irc7702_->ProcessGptPmt(Year, premiums_paid_increment, 
fake_cum_pmt);
             }

Modified: lmi/trunk/ihs_basicval.cpp
===================================================================
--- lmi/trunk/ihs_basicval.cpp  2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_basicval.cpp  2012-01-25 15:19:23 UTC (rev 5380)
@@ -95,7 +95,7 @@
 template std::string mc_str(mcenum_uw_basis);
 
 //============================================================================
-// TODO ?? Not for general use--use for GPT server only. This is bad design.
+// TODO ?? Not for general use--use for GPT server only. This is bad design. 
TAXATION !! Eliminate this.
 BasicValues::BasicValues
     (std::string  const& a_ProductName
     ,mcenum_gender       a_Gender
@@ -253,7 +253,8 @@
     // determined by a strategy. This data member is used only by
     // Init7702(), and is meaningful only when that function is called
     // by GPTServerInit(); the value assigned here is overridden by a
-    // downstream call to Irc7702::Initialize7702().
+    // downstream call to Irc7702::Initialize7702(). TAXATION !! So
+    // eliminate the member when it becomes unnecessary.
     InitialTargetPremium = 0.0;
 
     SetMaxSurvivalDur();
@@ -263,7 +264,7 @@
 }
 
 //============================================================================
-// TODO ??  Not for general use--use for GPT server only, for now--refactor 
later
+// TODO ??  Not for general use--use for GPT server only, for now. TAXATION !! 
refactor later
 void BasicValues::GPTServerInit()
 {
     ProductData_.reset(new product_data(yare_input_.ProductName));
@@ -438,6 +439,9 @@
     return z;
 }
 
+// TAXATION !! Reconsider unconditional initialization.
+// TAXATION !! For 7702A, offer a choice: tables or first principles.
+
 /// Initialize 7702 object.
 ///
 /// This function is called unconditionally, even for CVAT cases that
@@ -502,7 +506,7 @@
     // Monthly guar net int for 7702, with 4 or 6% min, is
     //   greater of {4%, 6%} and annual guar int rate
     //   less 7702 spread
-    // TODO ?? We need to subtract other things too, e.g. comp (sometimes)...
+    // TODO ?? TAXATION !! We need to subtract other things too, e.g. comp 
(sometimes)...
     //   transformed to monthly (simple subtraction?).
     // These interest rates belong here because they're used by
     // DCV calculations in the account value class as well as
@@ -510,6 +514,10 @@
 
     std::vector<double> guar_int;
     Database_->Query(guar_int, DB_GuarInt);
+// TAXATION !! Rework this. The intention is to make the 7702 interest
+// rate no less, at any duration, than the guaranteed loan rate--here,
+// the fixed rate charged on loans, minus the guaranteed loan spread
+// (if any).
 /*
     switch(yare_input_.LoanRateType)
         {
@@ -609,7 +617,7 @@
 
     // TODO ?? We should avoid reading the rate file again; but
     // the GPT server doesn't initialize a MortalityRates object
-    // that would hold those rates.
+    // that would hold those rates. TAXATION !! Rework this.
     std::vector<double> local_mly_charge_add(Length, 0.0);
     if(yare_input_.AccidentalDeathBenefit)
         {
@@ -656,16 +664,16 @@
 //============================================================================
 void BasicValues::Init7702A()
 {
-    int magic = 0; // TODO ?? A kludge.
+    int magic = 0; // TODO ?? TAXATION !! A kludge.
     Irc7702A_.reset
         (new Irc7702A
             (magic
             ,DefnLifeIns_
             ,DefnMaterialChange_
-            ,false // TODO ?? Joint life: hardcoded for now.
+            ,false // TODO ?? TAXATION !! Joint life: hardcoded for now.
             ,yare_input_.AvoidMecMethod
-            ,true  // TODO ?? Use table for 7pp: hardcoded for now.
-            ,true  // TODO ?? Use table for NSP: hardcoded for now.
+            ,true  // TODO ?? TAXATION !! Use table for 7pp: hardcoded for now.
+            ,true  // TODO ?? TAXATION !! Use table for NSP: hardcoded for now.
             ,MortalityRates_->SevenPayRates()
             ,MortalityRates_->CvatNspRates()
             ,round_max_premium()

Modified: lmi/trunk/ihs_irc7702.cpp
===================================================================
--- lmi/trunk/ihs_irc7702.cpp   2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_irc7702.cpp   2012-01-25 15:19:23 UTC (rev 5380)
@@ -40,6 +40,10 @@
 #include <limits>
 #include <numeric>
 
+// TAXATION !! Update this block comment, or simply delete it. The
+// client-server model is important, but not predominantly so. It is
+// no longer desirable to document basic C++ for C programmers here.
+//
 // The corridor factor may as well reside on the client system: it's
 // just a constant vector of 101 numbers. We make it available for
 // any client that wants us to supply it.
@@ -76,28 +80,33 @@
         return v;
         }
 
-    // Use 7702 int rate for DB discount in NAAR
+    // Use 7702 int rate for DB discount in NAAR. TAXATION !! Does it
+    // make sense to retain this?
     bool g_UseIcForIg = true;
 } // Unnamed namespace.
 
-// General concerns
+// TAXATION !! General concerns
 //
-// flat extras
+// TAXATION !! Explain why flat extras are generally ignored.
 //
-// off-anniversary processing
+// TAXATION !! Support off-anniversary adjustment events, though not
+// in illustrations.
 //
-// signal forceouts
-// signal if gp limit becomes negative
+// TAXATION !! Are forceouts signalled properly by the server? in 
illustrations?
 //
-// always allow min pmt to keep contract in force
+// TAXATION !! Signal if gp limit becomes negative; always allow min pmt to 
keep
+// contract in force.
 //
-// maturity duration
+// TAXATION !! What if maturity duration is beyond age 100?
 //
-// riders
+// TAXATION !! Are riders adequately supported?
 //
-// need these in ctor?
+// TAXATION !! need this in ctor?
 //  ,double     a_CumPmtYtd
+//
+// TAXATION !! 7702(f)(7)(B-E)
 
+// TAXATION !! Document these points in some more appropriate fashion:
 // Server questions and answers:
 // check each pmt? --no, admin system does that
 // maintain current and last GSP, GLP --no, admin system does that
@@ -176,13 +185,13 @@
 {
     LMI_ASSERT(a_PresentSpecAmt <= a_PresentBftAmt);
     LMI_ASSERT(0.0 <= a_TargetPremium);
-    // TODO ?? Instead put these in initializer-list and write assertions?
+    // TODO ?? TAXATION !! Instead put these in initializer-list and write 
assertions?
     if(0 == InforceYear && 0 == InforceMonth)
         {
         PriorBftAmt     = a_PresentBftAmt;
         PriorSpecAmt    = a_PresentSpecAmt;
-        // TODO ?? Assert that this is <= least-bft arg?
-        LeastBftAmtEver = a_PresentSpecAmt;
+        // TODO ?? TAXATION !! Assert that this is <= least-bft arg?
+        LeastBftAmtEver = a_PresentSpecAmt; // TAXATION !! Why not 
a_LeastBftAmtEver?
         PriorDBOpt      = PresentDBOpt;
         PresentGLP      = 0.0;
         PriorGLP        = 0.0;
@@ -194,13 +203,15 @@
         }
     else
         {
+        // TAXATION !! Why Prior from Prior here, but from Present above?
+        // and, below, from Present for dbopt?
         PriorBftAmt     = a_PresentBftAmt;
         PriorSpecAmt    = a_PresentSpecAmt;
         LeastBftAmtEver = a_LeastBftAmtEver;
         LMI_ASSERT(LeastBftAmtEver <= PriorBftAmt);
         LMI_ASSERT(LeastBftAmtEver <= PresentBftAmt);
-        PriorDBOpt      = PresentDBOpt; // TODO ?? handle this (and some 
others) in initializer-list instead
-        // TODO ?? Must these be members? The arguments could be used here 
instead.
+        PriorDBOpt      = PresentDBOpt; // TODO ?? TAXATION !! handle this 
(and some others) in initializer-list instead
+        // TODO ?? TAXATION !! Must these be members? The arguments could be 
used here instead.
         PresentGLP      = InforceGLP;
         PriorGLP        = InforceGLP;
         CumGLP          = InforceCumGLP;
@@ -208,6 +219,7 @@
         PriorGSP        = InforceGSP;
         GptLimit        = std::max(CumGLP, PresentGSP);
         CumPmts         = a_InforceCumPremsPaid;
+// TAXATION !! Are these comments still useful?
 // to handle inforce, we need to know:
 // the quantity A in A+B-C (i.e. both GSP and GLP)
 //  CumGLP
@@ -229,6 +241,7 @@
     )
 {
 // TODO ?? Duration and CumPmt args not yet used.
+// TAXATION !! Would Duration somehow be used for verification?
     if(mce_gpt != Test7702)
         {
         return;
@@ -239,6 +252,7 @@
 }
 
 //============================================================================
+// TAXATION !! Update this block comment.
 // Adjustable events processed here:
 //  actual changes in DB arising from:
 //      changes in SA
@@ -284,9 +298,11 @@
     LMI_ASSERT(materially_equal(PresentSpecAmt, a_PriorSpecAmt));
     LMI_ASSERT(PresentDBOpt == a_PriorDBOpt);
     LMI_ASSERT(0.0 <= a_TargetPremium);
+    // TAXATION !! Update this block comment:
     // Should be called only when something actually changed: either
     //   dbopt changed; or
     //   specamt changed, causing an actual change in bftamt.
+    //   TAXATION !! ...or bft amt, if 7702 DB is defined as that
     // For illustrations only, we assume:
     //   no changes in ratings
     //   no liberalizations in charges
@@ -312,6 +328,8 @@
 
     // Apply A + B - C method for both GLP and GSP.
 
+// TAXATION !! The name should certainly be changed; should the
+// old behavior be retained conditionally?
 // We changed our interpretation, but it'd be nice to preserve
 // the old functionality, conditional on a behavior flag. And
 // the name is poor: shouldn't it just be 'EndowmentBenefit'?
@@ -321,14 +339,14 @@
         (a_Duration
         ,PresentBftAmt
         ,PresentSpecAmt
-        ,PresentSpecAmt // LeastBftAmtEver
+        ,PresentSpecAmt // TAXATION !! LeastBftAmtEver
         ,PresentDBOpt
         );
     double c_level = CalculateGLP
         (a_Duration
         ,PriorBftAmt
         ,PriorSpecAmt
-        ,PriorSpecAmt // LeastBftAmtEver
+        ,PriorSpecAmt // TAXATION !! LeastBftAmtEver
         ,PriorDBOpt
         );
     PriorGLP = PresentGLP;
@@ -338,19 +356,20 @@
         (a_Duration
         ,PresentBftAmt
         ,PresentSpecAmt
-        ,PresentSpecAmt // LeastBftAmtEver
+        ,PresentSpecAmt // TAXATION !! LeastBftAmtEver
         );
     double c_single = CalculateGSP
         (a_Duration
         ,PriorBftAmt
         ,PriorSpecAmt
-        ,PriorSpecAmt // LeastBftAmtEver
+        ,PriorSpecAmt // TAXATION !! LeastBftAmtEver
         );
     PriorGSP = PresentGSP;
     PresentGSP = PriorGSP + b_single - c_single;
 // Test for negative guideline...then do what if negative?
 // --refer to actuarial department (see specs)
-    CumGLP = CumGLP + PresentGLP - PriorGLP;
+// TAXATION !! shouldn't that be handled here?
+    CumGLP = CumGLP + PresentGLP - PriorGLP; // TAXATION !! Eh? Because prior 
GLP was already added?
     GptLimit = std::max(CumGLP, PresentGSP);
 }
 
@@ -376,8 +395,10 @@
 {
     Length = Qc.size();
     // TODO ?? Assumes that endowment age is always 100--should pass as arg 
instead.
+    // TAXATION !! Is the comment above correct? Maturity age is passed as an 
argument.
     LMI_ASSERT(Length == EndtAge - IssueAge);
 
+    // TAXATION !! "For now": a decade has passed...
     // For now, always perform both GPT and CVAT calculations.
     // GLP might be wanted for some purpose in a CVAT product.
     // The extra overhead is not enormous.
@@ -389,7 +410,7 @@
     InitPvVectors(Opt1Int6Pct);
     // TODO ?? We can delete the commutation functions here, rather than in
     // the dtor, to save some space. We defer doing so until the
-    // program is complete.
+    // program is complete. TAXATION !! It would be better not to use 
pointers--see header.
 }
 
 //============================================================================
@@ -464,7 +485,7 @@
 {
     // CVAT corridor
     // TODO ?? Substandard: set last NSP to 1.0? ignore flats? set NSP[omega] 
to 1?
-    // --better to ignore susbstandard
+    // TAXATION !! --better to ignore susbstandard
     CvatCorridor.resize(Length);
     // ET !! CvatCorridor = CommFns[Opt1Int4Pct]->aD() / 
CommFns[Opt1Int4Pct]->kM();
     std::vector<double> denominator(CommFns[Opt1Int4Pct]->kM());
@@ -621,7 +642,7 @@
 
     // ET !! PvNpfSglTgt[a_EIOBasis] = (1.0 - LoadTgt) * comm_fns.aD();
     std::vector<double>& npf_sgl_tgt = PvNpfSglTgt[a_EIOBasis];
-//  LMI_ASSERT(u_length == npf_sgl_tgt.size());
+//  LMI_ASSERT(u_length == npf_sgl_tgt.size()); // TAXATION !! Expunge if 
truly unwanted.
     npf_sgl_tgt = LoadTgt;
     LMI_ASSERT(u_length == npf_sgl_tgt.size());
     std::transform(npf_sgl_tgt.begin(), npf_sgl_tgt.end(), npf_sgl_tgt.begin()
@@ -637,7 +658,7 @@
         ,std::multiplies<double>()
         );
     std::vector<double>& npf_lvl_tgt = PvNpfLvlTgt[a_EIOBasis];
-//  LMI_ASSERT(u_length == npf_lvl_tgt.size());
+//  LMI_ASSERT(u_length == npf_lvl_tgt.size()); // TAXATION !! Expunge if 
truly unwanted.
     npf_lvl_tgt = npf_sgl_tgt;
     LMI_ASSERT(u_length == npf_lvl_tgt.size());
     std::reverse(npf_lvl_tgt.begin(), npf_lvl_tgt.end());
@@ -648,13 +669,13 @@
 
     // ET !! PvNpfSglExc[a_EIOBasis] = (1.0 - LoadExc) * comm_fns.aD();
     std::vector<double>& npf_sgl_exc = PvNpfSglExc[a_EIOBasis];
-//  LMI_ASSERT(u_length == npf_sgl_exc.size());
+//  LMI_ASSERT(u_length == npf_sgl_exc.size()); // TAXATION !! Expunge if 
truly unwanted.
     npf_sgl_exc = LoadExc;
     LMI_ASSERT(u_length == npf_sgl_exc.size());
     std::transform(npf_sgl_exc.begin(), npf_sgl_exc.end(), npf_sgl_exc.begin()
         ,std::bind1st(std::minus<double>(), 1.0)
         );
-    LMI_ASSERT(u_length == npf_sgl_tgt.size());
+    LMI_ASSERT(u_length == npf_sgl_tgt.size()); // TAXATION !! Shouldn't this 
be npf_sgl_exc?
     LMI_ASSERT(u_length == comm_fns.aD().size());
     std::transform
         (npf_sgl_exc.begin()
@@ -664,7 +685,7 @@
         ,std::multiplies<double>()
         );
     std::vector<double>& npf_lvl_exc = PvNpfLvlExc[a_EIOBasis];
-//  LMI_ASSERT(u_length == npf_lvl_exc.size());
+//  LMI_ASSERT(u_length == npf_lvl_exc.size()); // TAXATION !! Expunge if 
truly unwanted.
     npf_lvl_exc = npf_sgl_exc;
     LMI_ASSERT(u_length == npf_lvl_exc.size());
     std::reverse(npf_lvl_exc.begin(), npf_lvl_exc.end());
@@ -675,7 +696,7 @@
 
     // ET !! PvLoadDiffSgl[a_EIOBasis] = npf_sgl_exc - npf_sgl_tgt;
     std::vector<double>& diff_sgl = PvLoadDiffSgl[a_EIOBasis];
-//  LMI_ASSERT(u_length == diff_sgl.size());
+//  LMI_ASSERT(u_length == diff_sgl.size()); // TAXATION !! Expunge if truly 
unwanted.
     diff_sgl.resize(Length);
     LMI_ASSERT(u_length == diff_sgl.size());
     LMI_ASSERT(u_length == npf_sgl_exc.size());
@@ -688,7 +709,7 @@
         ,std::minus<double>()
         );
     std::vector<double>& diff_lvl = PvLoadDiffLvl[a_EIOBasis];
-//  LMI_ASSERT(u_length == diff_lvl.size());
+//  LMI_ASSERT(u_length == diff_lvl.size()); // TAXATION !! Expunge if truly 
unwanted.
     diff_lvl.resize(Length);
     LMI_ASSERT(u_length == diff_lvl.size());
     std::reverse(diff_lvl.begin(), diff_lvl.end());
@@ -707,7 +728,7 @@
 void Irc7702::Initialize7702
     (double            a_BftAmt
     ,double            a_SpecAmt
-    ,mcenum_dbopt_7702 a_DBOpt // TODO ?? Is there any reason why dbopt would 
be changed here?
+    ,mcenum_dbopt_7702 a_DBOpt // TODO ?? TAXATION !! Is there any reason why 
dbopt would be changed here?
     ,double            a_TargetPremium
     )
 {
@@ -719,7 +740,7 @@
     PriorSpecAmt        = PresentSpecAmt;
     PresentBftAmt       = a_BftAmt;
     PriorBftAmt         = PresentBftAmt;
-// This:
+// TAXATION !! This:
 //  LeastBftAmtEver     = PresentBftAmt;
 // would appear correct: ...BftAmt assigned from ...BftAmt. However,
 // as pointed out above, 'EndowmentBenefit' would be a better name,
@@ -748,6 +769,7 @@
         }
     else
         {
+        // TAXATION !! Revisit this.
         // TODO ?? None of this should be necessary, but this function
         // is called for every basis, though it probably should be
         // called only once, for basis 'mce_run_gen_curr_sep_full'.
@@ -773,6 +795,9 @@
     // be OK because illustration systems confine most transactions
     // to anniversaries and we envision that an admin system client
     // will do this calculation itself.
+    // TAXATION !! Rewrite that comment. It is true that off-anniversary
+    // changes aren't handled at present, but the work done here would
+    // never be done at any other time.
     CumGLP += PresentGLP;
     GptLimit = std::max(CumGLP, PresentGSP);
 }
@@ -890,6 +915,7 @@
     LMI_ASSERT(0.0 != a_NetPmtFactorTgt);
     LMI_ASSERT(0.0 != a_NetPmtFactorExc);
 
+    // TAXATION !! Deal with this:
     // TODO ?? This implementation is correct only if target premium
     // is fixed forever at issue; otherwise, distinct target premiums
     // must be passed for each of the quantities A, B, and C. Should
@@ -926,19 +952,22 @@
         ;
 }
 
+// TAXATION !! Deal with this stuff.
 // Nothing past this point is intended for use by the GPT server
 
 // General concerns outside the scope of the standalone server
 //
-// combine txs on same date
+// combine txs on same date TAXATION !! isn't that up to the server?
 //
-// track cum pmts - wds and forceouts
+// track cum pmts less wds and forceouts TAXATION !! is it necessary
+// to add code here to accumulate those debits?
 //
-// current mort for substd
+// current mort for substd TAXATION !! is that outside the scope of this code?
 //
-// set SA at issue to reflect dumpins and 1035s
+// set SA at issue to reflect dumpins and 1035s TAXATION !! That could be
+// done for option two, but is probably a mistake.
 //
-// naming--SA vs SpecAmt, etc.
+// naming--SA vs SpecAmt, etc. TAXATION !! a grand renaming is desirable
 //
 
 /*
@@ -946,7 +975,7 @@
 void Irc7702::InitSevenPayPrem()
 {
         // 7PP = MO / (N0-N7) (limit 7 to maturity year)
-        // add flat extras to 7PP?
+        // TAXATION !! add flat extras to 7PP?
         double denom = CFFourPctMin->N()[j];
         if((7 + j) < q.size())
             {
@@ -1007,7 +1036,7 @@
     return CumPmts;
 }
 
-// TODO ?? This should be a separate, standalone unit test.
+// TAXATION !! TODO ?? This should be a separate, standalone unit test.
 #ifdef TESTING
 
 #include "ihs_timer.hpp"
@@ -1031,6 +1060,7 @@
 
 int main()
 {
+// TAXATION !! Update or remove these timings.
 // timing to construct Irc7702:
 // RW: about 37 msec
 // OS: about 93 msec; about 41 if we disable index checking

Modified: lmi/trunk/ihs_irc7702.hpp
===================================================================
--- lmi/trunk/ihs_irc7702.hpp   2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_irc7702.hpp   2012-01-25 15:19:23 UTC (rev 5380)
@@ -49,7 +49,7 @@
 // premium) and the bftamt (for death benefit), even though those two
 // arguments may be equal.
 
-// TODO ?? Is this still true?
+// TODO ?? TAXATION !! Is this still true?
 // No rounding is performed in this class. Round the values it calculates
 // as needed, being sure to round conservatively if at all. Unrounded
 // values are especially needed for the iterative specamt calculation.
@@ -94,7 +94,7 @@
         ,double                     a_InforceCumGLP
         ,double                     a_InforceGSP
         ,double                     a_InforceCumPremsPaid
-        // TODO ?? Perhaps other arguments are needed for inforce.
+        // TODO ?? TAXATION !! Perhaps other arguments are needed for inforce.
         );
     ~Irc7702();
 
@@ -110,7 +110,7 @@
         ,double&                    a_Pmt
         ,double&                    a_CumPmt
         );
-    // Returns forceout if any, else 0.0 .
+    // Returns forceout if any, else 0.0 . TAXATION !! But it's void.
     void ProcessAdjustableEvent
         (int                        a_Duration
         ,double                     a_NewBftAmt
@@ -174,6 +174,8 @@
         (mcenum_dbopt_7702          a_DBOpt
         );
 
+    // TAXATION !! Comments are unreliable (e.g., 7702 test may be
+    // neither CVAT nor GPT), and should be improved or removed.
     mcenum_defn_life_ins const Test7702;   // 7702 test: CVAT or GPT
     int const                  IssueAge;   // Issue age
     int const                  EndtAge;    // Endowment age
@@ -188,7 +190,7 @@
     double                     PriorBftAmt;
     double                     PresentSpecAmt;
     double                     PriorSpecAmt;
-    double                     LeastBftAmtEver;// Lowest bft amt since issue 
date // TODO ?? NOT!
+    double                     LeastBftAmtEver;// Lowest bft amt since issue 
date // TODO ?? TAXATION !! NOT!
     mcenum_dbopt_7702          PresentDBOpt;   // Present death benefit option
     mcenum_dbopt_7702          PriorDBOpt;     // Prior death benefit option
 
@@ -229,13 +231,18 @@
     // Commutation functions
 // TODO ?? Apparently the original reason for using smart pointers
 // was to minimize stack usage in a 16-bit environment; clearly that
-// doesn't matter anymore.
+// doesn't matter anymore. TAXATION !! Don't do that then.
 //
-// TODO ?? Consider using std::vector instead of array members.
+// TODO ?? TAXATION !! Consider using std::vector instead of array members.
     boost::scoped_ptr<ULCommFns> CommFns       [NumIOBases];
     // After the Init- functions have executed, we can delete the
     // rather sizeable ULCommFns objects, as long as we keep the
-    // endowment-year value of D for each basis.
+    // endowment-year value of D for each basis. TAXATION !! But
+    // not if they're created on the stack. And the meaning of
+    // "sizeable" has changed since that comment was written; the
+    // object contains nine vectors of double, each of potential
+    // length 100, and 9 * 8 * 100 = 7200 bytes is negligible in
+    // the twenty-first century.
     double                     DEndt           [NumIOBases];
 
     // GPT corridor factors for attained ages [IssueAge, 100]
@@ -249,16 +256,18 @@
     std::vector<double>        PvChgSpecAmt    [NumIOBases];
     std::vector<double>        PvChgADD        [NumIOBases];
     std::vector<double>        PvChgMort       [NumIOBases];
-    // TODO ?? Perhaps -Sgl/Lvl and -Tgt/Exc should be dimensions.
+    // TODO ?? TAXATION !! Perhaps -Sgl/Lvl and -Tgt/Exc should be dimensions.
     std::vector<double>        PvNpfSglTgt     [NumIOBases];
     std::vector<double>        PvNpfLvlTgt     [NumIOBases];
     std::vector<double>        PvNpfSglExc     [NumIOBases];
     std::vector<double>        PvNpfLvlExc     [NumIOBases];
-// TODO ?? Not necessary?
+// TODO ?? TAXATION !! Not necessary?
     std::vector<double>        PvLoadDiffSgl   [NumIOBases];
     std::vector<double>        PvLoadDiffLvl   [NumIOBases];
 };
 
+// TAXATION !! Update this, and move it to a better location.
+//
 // Implementation thoughts
 //
 // This class was designed to be instantiated by a C++ illustration

Modified: lmi/trunk/ihs_irc7702a.cpp
===================================================================
--- lmi/trunk/ihs_irc7702a.cpp  2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_irc7702a.cpp  2012-01-25 15:19:23 UTC (rev 5380)
@@ -21,11 +21,11 @@
 
 // $Id$
 
-// TODO ?? Make this a server app. Consider where to store DB, SA history.
+// TODO ?? TAXATION !! Make this a server app. Consider where to store DB, SA 
history.
 
-// TODO ?? Do we need a separate function to handle withdrawals?
+// TODO ?? TAXATION !! Do we need a separate function to handle withdrawals?
 
-// TODO ?? Treat ROP increases as material changes exactly where needed.
+// TODO ?? TAXATION !! Treat ROP increases as material changes exactly where 
needed.
 
 #ifdef __BORLANDC__
 #   include "pchfile.hpp"
@@ -51,7 +51,7 @@
 static int const         months_per_year              = 12          ;
 static long double const years_per_month              = 1.0L / 12.0L;
 static int const         statutory_max_endowment_age  = 100         ;
-// TODO ?? Test period not limited to seven years for survivorship.
+// TODO ?? TAXATION !! Test period not limited to seven years for survivorship.
 static int const         usual_test_period_length     = 7           ;
 }
 
@@ -116,8 +116,9 @@
     // Set flags for implementation choices. Assigning values here
     // looks superfluous because it duplicates the initializer-list;
     // they're grouped here to emphasize them for maintainers.
+    // TAXATION !! DATABASE !! Each should either be eliminated or moved to 
the database.
     InterpolateNspOnly      = false;
-    Exch1035IsMatChg        = true; // TODO ?? Silly--remove.
+    Exch1035IsMatChg        = true; // TODO ?? TAXATION !! Silly--remove.
     CorrHidesIncr           = false;
 
     switch(DefnMaterialChange)
@@ -140,7 +141,7 @@
             break;
         case mce_later_of_increase_or_unnecessary_premium:
             {
-            // TODO ?? Not implemented yet.
+            // TODO ?? TAXATION !! Not implemented yet.
             fatal_error()
                 << "mce_later_of_increase_or_unnecessary_premium not 
implemented."
                 << LMI_FLUSH
@@ -216,14 +217,14 @@
     double lowest_bft = *std::min_element(a_Bfts.begin(), a_Bfts.end());
     // Allow Bfts to be zero for solves.
     LMI_ASSERT(0.0 <= lowest_bft);
-    // TODO ?? Should we assert that this equals 'a_LowestBft'?
+    // TODO ?? TAXATION !! Should we assert that this equals 'a_LowestBft'?
     // If we can, then we don't need the latter as an argument.
 
     Ignore = false;
     if(a_Ignore || (mce_cvat != DefnLifeIns && mce_gpt != DefnLifeIns))
         {
         Ignore = true;
-        // TODO ?? An early return here as a speed optimization is not yet
+        // TODO ?? TAXATION !! An early return here as a speed optimization is 
not yet
         // safe. Routines to print optional monthly calculation detail rely
         // on sane values for some of the variables below. We could make
         // those routines depend on the early return condition here, or
@@ -234,12 +235,12 @@
 
     UnnecPremPaid = false;
     IsMec = false;
-    // TODO ?? I dislike this variable name because a contract can become a MEC
+    // TODO ?? TAXATION !! I dislike this variable name because a contract can 
become a MEC
     // at issue even when the variable's value is false.
     if(a_MecAtIssue)
         {
         IsMec = true;
-        // TODO ?? An early return here as a speed optimization is not yet
+        // TODO ?? TAXATION !! An early return here as a speed optimization is 
not yet
         // safe. Routines to print optional monthly calculation detail rely
         // on sane values for some of the variables below. We could make
         // those routines depend on the early return condition here, or
@@ -256,7 +257,7 @@
     PolicyYear          = a_PolicyYear;
     PolicyMonth         = a_PolicyMonth;
 
-    // TODO ?? Not for survivorship.
+    // TODO ?? TAXATION !! Not for survivorship.
     TestPeriodLen   = months_per_year * usual_test_period_length;
     TestPeriodDur   = a_ContractMonth + months_per_year * a_ContractYear;
 
@@ -266,7 +267,7 @@
             std::min(a_EndtAge, statutory_max_endowment_age)
         -   a_IssueAge
         ;
-    // TODO ?? Do we really need '1 +'?
+    // TODO ?? TAXATION !! Do we really need '1 +'?
     unsigned int max_dur = 1 + months_per_year * max_years;
     Pmts.assign(max_dur, 0.0);
     Bfts.assign(max_dur, 0.0);
@@ -274,11 +275,11 @@
     LMI_ASSERT(a_Pmts.size() <= max_years);
     for(unsigned int j = 0; j < a_Pmts.size(); ++j)
         {
-        // TODO ?? OK to treat premium history as annual?
+        // TODO ?? TAXATION !! OK to treat premium history as annual?
         Pmts[j * months_per_year] = a_Pmts[j];
         }
     LMI_ASSERT(a_Bfts.size() <= max_years);
-// UpdateBft7702A() updates this, thus:
+// TAXATION !! UpdateBft7702A() updates this, thus:
 //    Bfts[TestPeriodDur] = current_bft;
 // so should we make sure Bfts[TestPeriodDur] is zero here?
     for(unsigned int j = 0; j < a_Bfts.size(); ++j)
@@ -291,10 +292,10 @@
 
     CumPmts         = std::accumulate(a_Pmts.begin(), a_Pmts.end(), 0.0);
 
-    AssumedBft      = a_LowestBft; // TODO ?? Is this needed? Is it not always 
Bfts[0]?
+    AssumedBft      = a_LowestBft; // TAXATION !! TODO ?? Is this needed? Is 
it not always Bfts[0]?
     LowestBft       = a_LowestBft;
 
-    // For now, make do with the data available. Ultimately, pass
+    // TAXATION !! For now, make do with the data available. Ultimately, pass
     // duration of last material change as an argument.
     double const z = std::floor
         ( (    PolicyYear +     PolicyMonth / 12.0)
@@ -306,7 +307,7 @@
     state_.B2_deduced_px7_rate = SevenPPRateVec[duration_of_last_mc];
     SavedNecPrem    = 0.0;
     UnnecPrem       = 0.0;
-    SavedNSP        = NSPVec[PolicyYear]; // TODO ?? Ignores interpolation.
+    SavedNSP        = NSPVec[PolicyYear]; // TODO ?? TAXATION !! Ignores 
interpolation.
     state_.B3_deduced_nsp_rate = NSPVec[PolicyYear];
 
     Determine7PP
@@ -381,6 +382,7 @@
         // applying it irregularly is beyond the pale. We emulate this
         // ill-advised behavior only as an exercise in matching
         // another system. Do not use this for production.
+        // TAXATION !! Remove support for this misbegotten concept.
         double NSPBeg       = NSPVec[PolicyYear];
         double NSPEnd       = NSPVec[1 + PolicyYear];
         double lo_decrement = NSPBeg    * years_per_month;
@@ -419,7 +421,7 @@
         }
 
     // state_.Q4_cum_px7 and state_.Q5_cum_amt_pd are not updated here
-    // even though this function modifies CumSevenPP. Perhaps that
+    // even though this function modifies CumSevenPP. TAXATION !! Perhaps that
     // modification is a mistake: this function is called at the
     // beginning of each policy year, but the premium limit applies
     // to contract years.
@@ -634,7 +636,7 @@
         }
     else
         {
-        // TODO ?? For GPT, this is presumed valid but not yet tested.
+        // TODO ?? TAXATION !! For GPT, this is presumed valid but not yet 
tested.
         //
         // Initially assume the result is less than target. If it
         // turns out to be greater, then use a different formula.
@@ -717,6 +719,7 @@
     (double a_DeemedCashValue
     ,double a_Payment
     ,bool   a_ThisPaymentIsUnnecessary
+// TAXATION !! Eliminate these unused arguments?
     ,double // a_TargetPrem
     ,double // a_LoadTarget
     ,double // a_LoadExcess
@@ -728,7 +731,7 @@
         return a_Payment;
         }
 
-// TODO ?? Not necessarily true if we net out WD?
+// TODO ?? TAXATION !! Not necessarily true if we net out WD?
 //  LMI_ASSERT(0.0 <= a_Payment);
 
     // As long as we're MEC testing, this function should be called whenever a
@@ -736,20 +739,20 @@
     // called, the payment for the current duration should have its default
     // value of zero.
     //
-    // TODO ?? But then how will we handle a WD? Separate function?
+    // TODO ?? TAXATION !! But then how will we handle a WD? Separate function?
     //
     // Changed anyway: called twice a month when there's a material change.
 //    LMI_ASSERT(0.0 == Pmts[TestPeriodDur]);
 
     // During the test period (only), we accumulate premiums and compare
-    // to the seven-pay limit. We store premium history for this period(or 
longer?)
+    // to the seven-pay limit. We store premium history for this period (or 
longer?)
     // so that we can perform this comparison afresh in retrospect when
     // Bfts decreases.
     if(TestPeriodDur < TestPeriodLen)
         {
         // Reduce pmt to seven-pay limit if desired before recording it.
         // This won't avoid a retrospective MEC if Bfts later decreases.
-        // TODO ?? This is unnecessary now--premium limited in caller.
+        // TODO ?? TAXATION !! This is unnecessary now--premium limited in 
caller.
         /*
         if(mce_reduce_prem == AvoidMec)
             {
@@ -768,7 +771,7 @@
         if(CumSevenPP < CumPmts)
             {
             IsMec = true;
-/* TODO ?? Reenable after testing.
+/* TODO ?? TAXATION !! Reenable after testing.
             if(mce_reduce_prem == AvoidMec)
                 {
                 warning()
@@ -786,7 +789,7 @@
 
     // Test for unnecessary premium, which we deem to be a material change
 
-// TODO ?? Under GPT always MatChg if (iff?) GLP increased or if pmt increases 
ROP Bfts.
+// TODO ?? TAXATION !! Under GPT always MatChg if (iff?) GLP increased or if 
pmt increases ROP Bfts.
 
     if(mce_gpt == DefnLifeIns)
         {
@@ -805,10 +808,10 @@
 
     // Reduce pmt to necessary premium if desired before accepting it.
     // This won't avoid a retrospective MEC if Bfts later decreases.
-    // TODO ?? Anyway, why limit premium to necessary?
+    // TODO ?? TAXATION !! Anyway, why limit premium to necessary?
     if(mce_reduce_prem == AvoidMec)
         {
-    // TODO ?? Not needed unless we try handling MEC avoidance here.
+    // TODO ?? TAXATION !! Not needed unless we try handling MEC avoidance 
here.
 /*
     double max_necessary_prem = MaxNecessaryPremium
         (a_DeemedCashValue
@@ -837,7 +840,7 @@
         // never occur.
         //
         // However, a material change must be processed before any
-        // unnecessary premium is accepted. This code defectively
+        // unnecessary premium is accepted. This code defectively [TAXATION !! 
<-- Fix the defect then.]
         // accepts it while raising a flag calling for the material
         // change to be processed later. That's okay as long as a
         // material change has just been processed--but in that case
@@ -887,15 +890,15 @@
 
 //============================================================================
 // record and test monthly Bfts
-// This function always returns zero, so it shouldn't return anything.
+// TAXATION !! This function always returns zero, so it shouldn't return 
anything.
 double Irc7702A::UpdateBft7702A
-    (double // a_DeemedCashValue // TODO ?? Not used.
+    (double // a_DeemedCashValue // TODO ?? TAXATION !! Not used.
     ,double  a_NewDB
     ,double  a_OldDB
     ,bool    a_IsInCorridor
     ,double  a_NewSA
     ,double  a_OldSA
-    ,double  // a_CashValue // TODO ?? Not used.
+    ,double  // a_CashValue // TODO ?? TAXATION !! Not used.
     )
 {
     if(Ignore || IsMec)
@@ -911,7 +914,7 @@
 
     // I believe that the death benefit, unlike the premium, can be set more
     // than once per month in the present code. I do not know whether or not
-    // this can be avoided. TODO ?? Figure this out.
+    // this can be avoided. TODO ?? TAXATION !! Figure this out.
     LMI_ASSERT(TestPeriodDur < static_cast<int>(Bfts.size()));
 
     double current_bft = 0.0;
@@ -986,7 +989,7 @@
     // One school of thought treats any Bft increase following any unnec prem
     // as a MatChg.
 #ifdef THIS_IS_NOT_DEFINED
-    // TODO ?? Recognizing a MatChg wipes the slate clean: it is as though no
+    // TODO ?? TAXATION !! Recognizing a MatChg wipes the slate clean: it is 
as though no
     // unnecessary premium had ever been paid. So 'UnnecPremEver' is
     // a nonsensical notion.
     if(UnnecPremPaid && AssumedBft < current_bft)
@@ -997,14 +1000,14 @@
 
     if(is_material_change)
         {
-// Suppressed--see note above:
+// TAXATION !! Suppressed--see note above:
 //        LMI_ASSERT(AssumedBft < current_bft); // No decrease is a MC.
         IsMatChg = true;
         state_.D3_incr_is_mc = true;
 /*
         RedressMatChg
             (a_DeemedCashValue
-            ,0.0            // TODO ?? a_UnnecPrem
+            ,0.0            // TODO ?? TAXATION !! a_UnnecPrem
             ,0.0            // a_NecPrem
             ,a_CashValue
             );
@@ -1019,15 +1022,15 @@
 // recalculate 7pp and apply retroactively to beginning of 7 yr period
 void Irc7702A::TestBftDecrease(double a_NewBft)
 {
-    // TODO ?? Is AssumedBft always equal to LowestBft?
+    // TODO ?? TAXATION !! Is AssumedBft always equal to LowestBft?
 
     // Bfts reductions during any seven-year test period need to be tested.
     // In addition, only for second-to-die (but not first-to-die) contracts,
     // Bfts reductions have to be tested whenever they occur, even if it's
     // outside any seven-year test period; but such testing covers only
     // seven years in any event.
-    // VERIFY Bfts decrease at end of period, and just beyond; also dur zero
-    // VERIFY same with survivorship; also in last contract month
+    // TAXATION !! VERIFY Bfts decrease at end of period, and just beyond; 
also dur zero
+    // TAXATION !! VERIFY same with survivorship; also in last contract month
     if(!(IsSurvivorship || TestPeriodDur < TestPeriodLen))
         {
         return;
@@ -1041,7 +1044,7 @@
 
     // Recalculate 7pp to reflect lower death benefit.
     //
-    // TODO ?? If the benefit decreases subsequent to a MatChg, then the 7pp
+    // TODO ?? TAXATION !! If the benefit decreases subsequent to a MatChg, 
then the 7pp
     // recalculation should use AV, NecPrem, and NSP as of the last MatChg.
     Determine7PP
         (a_NewBft
@@ -1054,7 +1057,7 @@
 
     // Retest all premiums from beginning of test period.
     //
-    // TODO ?? We also need to test for unnecessary premium in retrospect.
+    // TODO ?? TAXATION !! We also need to test for unnecessary premium in 
retrospect. [obsolete interpretation?]
     //
     // Recalculate CumSevenPP because SevenPP changed.
     CumSevenPP = 0.0;
@@ -1133,7 +1136,7 @@
     ,double  a_CashValue
     )
 {
-// TODO ?? I think all public functions in this class need this test:
+// TODO ?? TAXATION !! I think all public functions in this class need this 
test:
     if(Ignore || IsMec || !IsMaterialChangeInQueue())
         {
         return;
@@ -1148,11 +1151,11 @@
     // 'SavedDCV' is used only for monthly trace.
     SavedDCV = a_DeemedCashValue;
 
-    // TODO ?? What if account value is less than zero here?
+    // TODO ?? TAXATION !! What if account value is less than zero here?
 
     // Recalculate 7pp to reflect material change
     Determine7PP
-// TODO ?? If MatChg due to unnec prem, should Bfts reflect any corridor 
increase?
+// TODO ?? TAXATION !! If MatChg due to unnec prem, should Bfts reflect any 
corridor increase?
 // Yes.
         (Bfts[TestPeriodDur]    // a_Bft
         ,false                  // a_TriggeredByBftDecrease
@@ -1171,7 +1174,7 @@
         (Pmts.begin()
         ,Pmts.begin() + TestPeriodDur
         );
-// TODO ?? Is the latest payment still there?
+// TODO ?? TAXATION !! Is the latest payment still there?
 
     // Start new 7 pay period
     TestPeriodDur = 0;
@@ -1204,7 +1207,7 @@
 
 //============================================================================
 // update 7pp
-// Restructure this--too many TriggeredBy's
+// TAXATION !! Restructure this--too many TriggeredBy's
 void Irc7702A::Determine7PP
     (double a_Bft
     ,bool   // a_TriggeredByBftDecrease
@@ -1216,7 +1219,7 @@
 {
     // We always treat payment of unnecessary premium as a material change
     // So this test is unnecessary; so is the parm in the conditional.
-    // TODO ?? NO LONGER TRUE.
+    // TODO ?? TAXATION !! NO LONGER TRUE.
     if(a_TriggeredByUnnecPrem)
         {
         LMI_ASSERT(a_TriggeredByMatChg);
@@ -1227,7 +1230,7 @@
     // Store new values for
     //  Saved7PPRate, SavedAVBeforeMatChg, SavedNecPrem, and SavedNSP
     // iff 7pp recalculation due to material change. (But how could
-    // a material change mutate 'Saved7PPRate'?)
+    // a material change mutate 'Saved7PPRate'?) [TAXATION !! rethink that]
     // But leave those values undisturbed if triggered by Bfts decrease.
     if(a_TriggeredByMatChg)
         {
@@ -1238,7 +1241,7 @@
         // premium was paid. Otherwise, the premium, which was all necessary,
         // simply went into the AV. SavedNecPrem is used only to adjust
         // the AV saved prior to a material change.
-        // TODO ?? Is that rigorous?
+        // TODO ?? TAXATION !! Is that rigorous?
         if(a_TriggeredByUnnecPrem)
             {
             SavedNecPrem = a_NecPrem;
@@ -1252,7 +1255,7 @@
         {
         // No material change--either we're initializing, or processing
         // a Bfts decrease. NO...could be an inforce case.
-// TODO ?? expunge
+// TODO ?? TAXATION !! expunge
 //        LMI_ASSERT
 //            (   a_TriggeredByBftDecrease
 //            ||  (0 == PolicyYear && 0 == PolicyMonth)
@@ -1271,7 +1274,7 @@
 // pass DCV as an argument; maybe we should drop the assertion. Note
 // that 'SavedDCV', because of its limited purpose, isn't reliably
 // initialized; I'm not sure we should promote that variable to a
-// first-class citizen by initializing it carefully.
+// first-class citizen by initializing it carefully. [TAXATION !! Address 
this.]
             LMI_ASSERT
                 (   0.0                 == SavedAVBeforeMatChg
                 ||  materially_equal(SavedDCV, SavedAVBeforeMatChg)
@@ -1280,7 +1283,7 @@
             LMI_ASSERT(materially_equal(SevenPPRateVec[0], Saved7PPRate));
             LMI_ASSERT(materially_equal(NSPVec[0], SavedNSP));
             }
-/* TODO ?? Expunge this perhaps. Not sure what we should do if someone
+/* TODO ?? TAXATION !! Expunge this perhaps. Not sure what we should do if 
someone
 tries running an inforce case as of month 0, year 0.
         // In either of these two cases--initialization or Bfts reduction--the
         // a_AVBeforeMatChg and a_NecPrem arguments are not used, so give a
@@ -1313,7 +1316,7 @@
     // worry about whether the denominator is zero. For instance, Bfts
     // is allowed to be zero for solves.
     double bft_adjustment = SavedAVBeforeMatChg / SavedNSP;
-// TODO ?? expunge
+// TODO ?? TAXATION !! expunge
 //    double bft_adjustment =
 //            (SavedAVBeforeMatChg + SavedNecPrem)
 //        /   SavedNSP
@@ -1327,7 +1330,7 @@
         {
         SevenPP = 0.0;
         }
-// TODO ?? AssumedBft should reflect any Bfts increase--AFTER the MatChg?
+// TODO ?? TAXATION !! AssumedBft should reflect any Bfts increase--AFTER the 
MatChg?
 }
 
 //============================================================================
@@ -1340,7 +1343,7 @@
         ,Bfts.begin() + std::min(TestPeriodLen, TestPeriodDur)
         );
     LMI_ASSERT(Bfts.begin() <= last_bft_in_test_period);
-// This is harmful for inforce if inforce history is unreliable:
+// TAXATION !! This is harmful for inforce if inforce history is unreliable:
     LowestBft = *std::min_element(Bfts.begin(), last_bft_in_test_period);
     return LowestBft;
 }
@@ -1349,13 +1352,13 @@
 // determine lowest non-MEC spec amt
 double Irc7702A::SAIncreaseToAvoidMec(bool a_TriggeredByUnnecPrem)
 {
-// TODO ?? Specs say DB, but isn't this SA?
+// TODO ?? TAXATION !! Specs say DB, but isn't this SA?
     double av = SavedAVBeforeMatChg;
     if(a_TriggeredByUnnecPrem)  // TODO ?? iff MatChg triggered by unnec prem?
         {
         av += SavedNecPrem;
         }
-    // Why aren't we using something like "SavedUnnecPrem" instead?
+    // TAXATION !! Why aren't we using something like "SavedUnnecPrem" instead?
     double new_bft =
             UnnecPrem / Saved7PPRate
         +   av
@@ -1365,7 +1368,7 @@
 // Specs say this formula is for Bfts increase to avoid MEC when unnec prem
 // paid. Also need to handle case where prem exceeds 7pp. Also need to handle
 // dumpins. Also need to handle Bfts decrease (complicated). Also need to
-// reflect new 7pp upon MatChg. TODO ?? Where should we do all this?
+// reflect new 7pp upon MatChg. TODO ?? TAXATION !! Where should we do all 
this?
 //
 // Events that are MatChgs:
 //   1035 exchange--but we treat that as a special case
@@ -1378,6 +1381,7 @@
     return new_bft;
 }
 
+// TAXATION !! Rewrite or remove this block comment:
 /*
  * // Entry points
  *

Modified: lmi/trunk/ihs_irc7702a.hpp
===================================================================
--- lmi/trunk/ihs_irc7702a.hpp  2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_irc7702a.hpp  2012-01-25 15:19:23 UTC (rev 5380)
@@ -36,7 +36,7 @@
 
 void LMI_SO TestIrc7702A();
 
-// TODO ?? Known defects:
+// TAXATION !! TODO ?? Known defects:
 //   need to handle withdrawals correctly;
 //   7-pay premium strategy changes premium when spec amt changes;
 //   should optionally calculate factors e.g. 7pp, NSP from first principles.
@@ -57,9 +57,10 @@
         ,mcenum_mec_avoid_method     a_AvoidMec
         ,bool                        a_Use7PPTable
         ,bool                        a_UseNSPTable
-        ,std::vector<double> const&  a_SevenPPRateVec// TODO ?? Assume table 
passed, for now.
-        ,std::vector<double> const&  a_NSPVec        // TODO ?? Assume table 
passed, for now.
+        ,std::vector<double> const&  a_SevenPPRateVec// TODO ?? TAXATION !! 
Assume table passed, for now.
+        ,std::vector<double> const&  a_NSPVec        // TODO ?? TAXATION !! 
Assume table passed, for now.
         ,round_to<double>    const&  a_RoundNonMecPrem
+// TAXATION !! Either use these arguments or eliminate them.
 //      ,unsigned int                a_IssueAge
 //      ,double                      a_Face
 //      ,mcenum_dbopt_7702           a_DBOpt
@@ -68,13 +69,14 @@
 //      ,std::vector<double> const&  a_PremLoad
 //      ,std::vector<double> const&  a_PerKCharge
 //      ,std::vector<double> const&  a_PolFee
-// probably other arguments are needed for reproposals
+// TAXATION !! probably other arguments are needed for reproposals
         );
     ~Irc7702A();
 
+// TAXATION !! Move documentation of functions to '.cpp' file.
     // This is notionally called once per *current*-basis run
     // and actually called once per run, with calculations suppressed
-    // for all other bases by setting Ignore (q.v.).
+    // for all other bases by setting Ignore (q.v.). TAXATION !! Is that good?
     void Initialize7702A                    // set initial values at issue
         (bool   a_Ignore
         ,bool   a_MecAtIssue
@@ -90,7 +92,7 @@
         ,std::vector<double> const& a_Bfts
         );
     // Always call at beginning of policy year
-    // interpolate NSP; update cum 7pp
+    // interpolate NSP; update cum 7pp // TAXATION !! That interpolation is a 
poor idea.
     void UpdateBOY7702A
         (int a_PolicyYear
         );
@@ -124,7 +126,7 @@
     // record and test monthly Bfts
     // return min non-mec Bft if called for
     double UpdateBft7702A
-        (double  // a_DeemedCashValue
+        (double  // a_DeemedCashValue // TAXATION !! Is this argument useful?
         ,double  a_NewDB
         ,double  a_OldDB
         ,bool    a_IsInCorridor
@@ -134,7 +136,7 @@
         );
     // Queue a material change for later handling.
     void InduceMaterialChange();
-    // TODO ?? Handle material change--always call right before monthly 
deduction?
+    // TODO ?? TAXATION !! Handle material change--always call right before 
monthly deduction?
     void RedressMatChg
         (double& a_DeemedCashValue
         ,double  a_UnnecPrem
@@ -157,7 +159,7 @@
         ,double a_LoadExcess
         ,double a_CashValue
         ) const;
-    // SOMEDAY !! Consider using accessors like Irc7702::RoundedGLP()
+    // TAXATION !! Consider using accessors like Irc7702::RoundedGLP()
     // to encapsulate rounding within this class.
     double GetPresent7pp() const        {return SevenPP;}
     bool IsMecAlready() const           {return IsMec;}
@@ -172,7 +174,7 @@
     // for other purposes. They may be changed or eliminated in future
     // versions. I don't regard them as part of the public interface,
     // although they physically happen to be so.
-    // TODO ?? IOW, 'friend' would be better?
+    // TODO ?? TAXATION !! IOW, 'friend' would be better?
     int     DebugGetTestDur         () const
         {return TestPeriodDur - 1;  /* we already incremented it */}
     double  DebugGet7ppRate         () const
@@ -217,7 +219,7 @@
         ,double a_AVBeforeMatChg
         ,double a_NecPrem
         );
-    // TODO ?? Wouldn't this need to be public?
+    // TODO ?? TAXATION !! Wouldn't this need to be public?
     double  SAIncreaseToAvoidMec    // determine lowest non-MEC spec amt
         (bool a_TriggeredByUnnecPrem
         );
@@ -226,9 +228,9 @@
     mutable mec_state state_;
 
 // NOTE: table lookup really means supplied via arguments ?
-// TODO ?? Need to calculate if not table lookup.
+// TODO ?? TAXATION !! Need to calculate if not table lookup.
 
-    int magic; // TODO ?? Temporary kludge.
+    int magic; // TODO ?? TAXATION !! Temporary kludge.
 
     mcenum_defn_life_ins DefnLifeIns;
     mcenum_defn_material_change DefnMaterialChange;
@@ -240,7 +242,7 @@
     bool InterpolateNspOnly;
 
     bool const      IsSurvivorship; // is policy multilife and not first to 
die?
-    mcenum_mec_avoid_method AvoidMec; // TODO ?? Document what this does.
+    mcenum_mec_avoid_method AvoidMec; // TODO ?? TAXATION !! Document what 
this does.
     bool const      Use7PPTable;    // get SevenPP from table, not calculation
     bool const      UseNSPTable;    // get NSP from table, not calculation
 
@@ -250,11 +252,12 @@
     round_to<double> RoundNonMecPrem;
 
     // Note that death benefit and pmts may not have their usual meanings.
-    // Pmts is premium net of deductible withdrawals.
+    // TAXATION !! [Explain why.]
+    // Pmts is premium net of deductible withdrawals. [TAXATION !! globally 
prefer "nontaxable" to "deductible"]
     // Bfts is SA, plus tax basis for ROP. The corridor is conservatively
     //   ignored to prevent the policy from becoming a MEC retroactively
     //   due to poor investment performance.
-    // TODO ?? Maybe not--Bfts might be DB.
+    // TODO ?? TAXATION !! Maybe not--Bfts might be DB.
     std::vector<double> Bfts;           // "death benefit" for 7702A
     std::vector<double> Pmts;           // premium net of deductible 
withdrawals
     std::vector<double> MlyInterpNSP;   // monthly interpolated NSP per $
@@ -279,7 +282,7 @@
     int             TestPeriodLen;  // length (months) of test period
     int             TestPeriodDur;  // duration (months) since beginning of
                                     //   current test period
-    // We need policy year for table lookups, and month for NSP interpolation
+    // We need policy year for table lookups, and month for NSP interpolation 
TAXATION !! eliminate interpolation
     int             PolicyYear;     // duration since issue (full years)
     int             PolicyMonth;    // duration since issue (months)
     double          AssumedBft;     // death bft assumed in setting last 
SevenPP
@@ -292,9 +295,11 @@
     double          SavedNSP;       // interpolated NSP
     double          SavedDCV;       // deemed cash value
 
+    // TAXATION !! Need these be 'mutable'?
     mutable double  NetNecessaryPrem;   // maximum necessary premium, no loads
     mutable double  GrossNecessaryPrem; // max nec prem grossed up for prem 
load
 
+// TAXATION !! Is this stuff useful? q and i might be, but the others?
 //  std::vector<double> const&  q;
 //  std::vector<double> const&  i;
 //  std::vector<double> const&  PremLoad;




reply via email to

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