Index: src/engine/gnc-lot.c
===================================================================
--- src/engine/gnc-lot.c	(revision 13880)
+++ src/engine/gnc-lot.c	(working copy)
@@ -42,6 +42,7 @@
 #include "Account.h"
 #include "gnc-lot.h"
 #include "gnc-lot-p.h"
+#include "cap-gains.h"
 #include "Transaction.h"
 #include "TransactionP.h"
 
@@ -236,13 +237,23 @@
    
    if (lot && lot->splits)
    {
+      Transaction *ta, *tb;
+      Split *target;
+      /* If this is a gains split, find the source of the gains and use
+         its transaction for the comparison.  Gains splits are in separate
+         transactions that may sort after non-gains transactions.  */
+      target = xaccSplitGetGainsSourceSplit (split);
+      if (target == NULL)
+         target = split;
+      tb = xaccSplitGetParent (target);
       for (node = lot->splits; node; node = node->next)
       {
          Split *s = node->data;
-         Transaction *ta, *tb;
-         ta = xaccSplitGetParent (s);
-         tb = xaccSplitGetParent (split);
-         if ((ta == tb && s != split) ||
+         Split *source = xaccSplitGetGainsSourceSplit (s);
+         if (source == NULL)
+            source = s;
+         ta = xaccSplitGetParent (source);
+         if ((ta == tb && source != target) ||
              xaccTransOrder (ta, tb) < 0)
          {
             gnc_numeric tmpval = xaccSplitGetAmount (s);
Index: src/engine/cap-gains.c
===================================================================
--- src/engine/cap-gains.c	(revision 13880)
+++ src/engine/cap-gains.c	(working copy)
@@ -141,6 +141,8 @@
    if (0 == (els->numeric_pred) (bal)) return NULL;
    
    s = gnc_lot_get_earliest_split (lot);
+   if (s == NULL) return NULL;
+   
    trans = s->parent;
    if (els->currency && 
        (FALSE == gnc_commodity_equiv (els->currency,
@@ -653,6 +655,29 @@
 
 /* ============================================================== */
 
+Split *
+xaccSplitGetGainsSourceSplit (const Split *split)
+{
+   KvpValue *val;
+   GUID *source_guid;
+   Split *source_split;
+   
+   if (!split) return NULL;
+
+   val = kvp_frame_get_slot (split->inst.kvp_data, "gains-source");
+   if (!val) return NULL;
+   source_guid = kvp_value_get_guid (val);
+   if (!source_guid) return NULL;
+
+   /* Both splits will be in the same collection, so seearch there. */
+   source_split = (Split*) qof_collection_lookup_entity (split->inst.entity.collection, 
+                                                         source_guid);
+   PINFO ("split=%p has source-split=%p", split, source_split);
+   return source_split;
+}
+
+/* ============================================================== */
+
 void
 xaccSplitComputeCapGains(Split *split, Account *gain_acc)
 {
@@ -783,6 +808,9 @@
     * 'dirty' and the gains really do need to be recomputed. 
     * So start working things. */
 
+   /* Get the amount and value in this lot at the time of this transaction. */
+   gnc_lot_get_balance_before (lot, split, &lot_amount, &lot_value);
+
    pcy->PolicyGetLotOpening (pcy, lot, &opening_amount, &opening_value,
        &opening_currency);
 
@@ -803,7 +831,7 @@
     * XXX This should really be a part of a scrub routine that
     * cleans up the lot, before we get at it!
     */
-   if (0 > gnc_numeric_compare (gnc_numeric_abs(opening_amount),
+   if (0 > gnc_numeric_compare (gnc_numeric_abs(lot_amount),
                                 gnc_numeric_abs(split->amount)))
    {
       GList *n;
@@ -815,14 +843,14 @@
       PERR ("Malformed Lot \"%s\"! (too thin!) " 
             "opening amt=%s split amt=%s baln=%s",
              gnc_lot_get_title (lot),
-             gnc_num_dbg_to_string (opening_amount),
+             gnc_num_dbg_to_string (lot_amount),
              gnc_num_dbg_to_string (split->amount),
              gnc_num_dbg_to_string (gnc_lot_get_balance(lot)));
       return;
    }
-   if ( (gnc_numeric_negative_p(opening_amount) ||
+   if ( (gnc_numeric_negative_p(lot_amount) ||
          gnc_numeric_positive_p(split->amount)) &&
-        (gnc_numeric_positive_p(opening_amount) ||
+        (gnc_numeric_positive_p(lot_amount) ||
          gnc_numeric_negative_p(split->amount)))
    {
       GList *n;
@@ -834,7 +862,7 @@
       PERR ("Malformed Lot \"%s\"! (too fat!) "
             "opening amt=%s split amt=%s baln=%s",
              gnc_lot_get_title (lot),
-             gnc_num_dbg_to_string (opening_amount),
+             gnc_num_dbg_to_string (lot_amount),
              gnc_num_dbg_to_string (split->amount),
              gnc_num_dbg_to_string (gnc_lot_get_balance(lot)));
       return;
@@ -847,7 +875,6 @@
     * cost_basis = purchase_price * current_split_amount
     * cap_gain = current_split_value - cost_basis 
     */
-   gnc_lot_get_balance_before (lot, split, &lot_amount, &lot_value);
    /* Fraction of the lot that this split represents: */
    frac = gnc_numeric_div (split->amount, lot_amount, 
                             GNC_DENOM_AUTO, 
@@ -860,8 +887,8 @@
    value = gnc_numeric_sub (value, split->value,
                             GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
    PINFO ("Open amt=%s val=%s;  split amt=%s val=%s; gains=%s\n",
-          gnc_num_dbg_to_string (opening_amount),
-          gnc_num_dbg_to_string (opening_value),
+          gnc_num_dbg_to_string (lot_amount),
+          gnc_num_dbg_to_string (lot_value),
           gnc_num_dbg_to_string (split->amount),
           gnc_num_dbg_to_string (split->value),
           gnc_num_dbg_to_string (value));
@@ -872,8 +899,8 @@
             "\tOpen amt=%s val=%s\n\tsplit amt=%s val=%s\n\tgains=%s\n",
              xaccAccountGetName(split->acc),
              xaccTransGetDescription(split->parent),
-             gnc_num_dbg_to_string (opening_amount),
-             gnc_num_dbg_to_string (opening_value),
+             gnc_num_dbg_to_string (lot_amount),
+             gnc_num_dbg_to_string (lot_value),
              gnc_num_dbg_to_string (split->amount),
              gnc_num_dbg_to_string (split->value),
              gnc_num_dbg_to_string (value));
@@ -967,7 +994,6 @@
 
       xaccSplitSetAmount (lot_split, zero);
       xaccSplitSetValue (lot_split, value);
-      gnc_lot_add_split (lot, lot_split);
 
       value = gnc_numeric_neg (value);
       xaccSplitSetAmount (gain_split, value);
@@ -980,6 +1006,10 @@
       lot_split->gains_split = split;
       gain_split->gains = GAINS_STATUS_GAINS;
       gain_split->gains_split = split;
+      
+      /* Do this last since it may generate an event that will call us
+         recursively. */
+      gnc_lot_add_split (lot, lot_split);
 
       xaccTransCommitEdit (trans);
    }
Index: src/engine/cap-gains.h
===================================================================
--- src/engine/cap-gains.h	(revision 13880)
+++ src/engine/cap-gains.h	(working copy)
@@ -150,6 +150,13 @@
  */                                       
 Split * xaccSplitGetCapGainsSplit (const Split *);
 
+/** The xaccSplitGetGainsSourceSplit() routine returns the split
+ *  that is the source of the cap gains in this split.  It returns
+ *  NULL if not found.  This routine does nothing more than search 
+ *  for the split recorded in the KVP key "/gains-source"
+ */                                       
+Split * xaccSplitGetGainsSourceSplit (const Split *);
+
 /** The`xaccSplitAssign() routine will take the indicated
  *  split and, if it doesn't already belong to a lot, it will attempt 
  *  to assign it to an appropriate lot.
