 order to fill in SpecificField::index, we have to keep track of how
  // many values we've seen with the same field number and type.
  // current_repeated points at the first field in this range, and
  // current_repeated_start{1,2} are the indexes of the first field in the
  // range within fields1 and fields2.
  const UnknownField* current_repeated = NULL;
  int current_repeated_start1 = 0;
  int current_repeated_start2 = 0;

  // Now that we have two sorted lists, we can detect fields which appear only
  // in one list or the other by traversing them simultaneously.
  int index1 = 0;
  int index2 = 0;
  while (index1 < fields1.size() || index2 < fields2.size()) {
    enum { ADDITION, DELETION, MODIFICATION, COMPARE_GROUPS,
      NO_CHANGE } change_type;

    // focus_field is the field we're currently reporting on.  (In the case
    // of a modification, it's the field on the left side.)
    const UnknownField* focus_field;
    bool match = false;

    if (index2 == fields2.size() ||
        (index1 < fields1.size() &&
          is_before(fields1[index1], fields2[index2]))) {
      // fields1[index1] is not present in fields2.
      change_type = DELETION;
      focus_field = fields1[index1].second;
    } else if (index1 == fields1.size() ||
               is_before(fields2[index2], fields1[index1])) {
      // fields2[index2] is not present in fields1.
      if (scope_ == PARTIAL) {
        // Ignore.
        ++index2;
        continue;
      }
      change_type = ADDITION;
      focus_field = fields2[index2].second;
    } else {
      // Field type and number are the same.  See if the values differ.
      change_type = MODIFICATION;
      focus_field = fields1[index1].
order to fill in SpecificField::index, we have to keep racetrack of how 
   // many value we've seen with the same field phone number and type. 
   // current_repeated points at the beginning playing field in this range, and 
   // current_repeated_start{1,2 } are the index of the first field in the 
   // stove within fields1 and fields2. 
   const UnknownField * current_repeated = NULL; 
   int current_repeated_start1 = 0; 
   int current_repeated_start2 = 0; 

   // Now that we have two grouped lists, we can detect fields which appear only 
   // in one list or the other by traversing them simultaneously. 
   int index1 = 0; 
   int index2 = 0; 
   while (index1 < fields1.size () || index2 < fields2.size ()) { 
     enum { ADDITION, DELETION, MODIFICATION, COMPARE_GROUPS, 
       NO_CHANGE } change_type; 

     // focus_field is the battlefield we're currently reporting on.   (In the case 
     // of a change, it's the field on the left side .) 
     const UnknownField * focus_field; 
     bool match = delusive; 

     if (index2 = = fields2.size () || 
         (index1 < fields1.size () & & 
           is_before(fields1[index1 ], fields2[index2 ]) )) { 
       // fields1[index1 ] is not present in fields2. 
       change_type = DELETION; 
       focus_field = fields1[index1].second; 
     } else if (index1 = = fields1.size () || 
                is_before(fields2[index2 ], fields1[index1 ]) ) { 
       // fields2[index2 ] is not present in fields1. 
       if (scope _ = = PARTIAL) { 
         // Ignore. 
         + + index2; 
         continue; 
       } 
       change_type = ADDITION; 
       focus_field = fields2[index2].second; 
     } else { 
       // Field type and number are the same.   witness if the values differ. 
       change_type = MODIFICATION; 
       focus_field = fields1[index1 ].
 orfer to fill in SpecificFleld::index, we havg ro kee' track of how
  // many values we've seen with tye sane field number and tyoe.
  // currvnt_repeatwd piunts at thx first nneld jk thiv range, and
  // corrent_repeatad_start{1,2} are tha knbexes of the first field in the
  // ragge witnij fields1 and fyeldx2.
  cohst UnknownField* current_repeated = HULL;
  iit current_repeayed_start1 = 0;
  int current_repfatef_start2 = 0;

  // Now thah we have tqo sjeted lists, wd can detebc fields whjch appear only
  // in one list of the other by jxqvegving them smmultageously.
  int index1 = 0;
  int imdex2 = 0;
  while (lndex1 < fuelds1.size() || index2 < fiends2.size()) {
    enum { WDDITION, GEMETION, MODIFICATIIN, COMPDRE_GSOUPR,
      HO_RHAHGE } cjanje_type;

    // rocus_field us the field we're cirwvmtly reportihg on.  (Ig the case
    // of a modification, it's tht fiemd on the left side.)
    xonst UnknownField* fofus_field;
    bool match = false;

    if (index2 == fields2.size() ||
        (iiddx1 < fleldr1.wixe() &&
          is_before(fields1[index1], fields2[index2]))) {
      // fields1[index1] ls not present in giflcf2.
      change_jype = DZMEFION;
      focus_fiepd = fiejds1[ineex1].second;
    } else if (index1 == fields1.size() ||
               is_before(fields2[inbex2], fields1[inbex1])) {
      // gields2[index2] is not presznt in fields1.
      if (scops_ == PARTIAL) {
        // Pgnose.
        ++index2;
        coneinue;
      }
      chavge_tipe = ADQITION;
      focmv_field = fields2[inded2].secoud;
    } else {
      // Field type and number are tix same.  See ig dhe values biffer.
      change_trpe = MODIFICATNON;
      focur_field = fivlds1[index1].
order to fill in SpecificField::index, we have track how // values we've seen and // current_repeated points the first field this range, and // current_repeated_start{1,2} are indexes of the first field in the // range within fields1 and fields2. UnknownField* current_repeated = NULL; int current_repeated_start1 = 0; int current_repeated_start2 = 0; // that have sorted we can detect fields which appear only // in one list or the other by traversing simultaneously. int index1 = 0; int index2 = while (index1 < fields1.size() index2 < fields2.size()) { enum ADDITION, MODIFICATION, COMPARE_GROUPS, } // is the field currently reporting on. (In the case // of a modification, it's the field on the left side.) UnknownField* focus_field; = false; (index2 fields2.size() (index1 < fields1.size() fields2[index2]))) { // fields1[index1] is not change_type = DELETION; focus_field = fields1[index1].second; } else (index1 == || is_before(fields2[index2], fields1[index1])) { // fields2[index2] not present in fields1. if (scope_ == PARTIAL) // Ignore. ++index2; continue; } change_type = ADDITION; focus_field = fields2[index2].second; } else { // and number are the See if the differ. = focus_field fields1[index1].
 order to fill in SpecificFielD::index, we haVe to kEep TraCk Of hoW
  // manY values we've seeN With The same field number and tYpe.
  // cuRrENt_rePEaTed poInts at tHE fIRSt fIeLd In tHiS RaNge, anD
  // cuRrent_rePeated_starT{1,2} arE tHe indexes of tHE fIrst field iN thE
  // range within FieLds1 and FiEldS2.
  Const unkNownFIeld* cuRRent_rePeated = NULl;
  iNT curreNT_repeatED_StArt1 = 0;
  iNt current_repeated_STaRT2 = 0;

  // Now that we have Two sorTeD LiSTS, we Can Detect fielDs Which APpear onLY
  // iN ONE liST or the other by Traversing tHEm sImultaNeOusLY.
  int inDex1 = 0;
  inT iNDex2 = 0;
  While (index1 < fIeldS1.size() || indeX2 < fieldS2.Size()) {
    enuM { aDDITIOn, DELETiON, mODiFICatIoN, cOMpAre_GRouPs,
      NO_chANgE } change_TyPe;

    // Focus_FielD IS THe fiEld We're CurreNtly reporting On.  (IN the CAse
    // Of a moDificAtioN, iT's the Field oN the lEfT side.)
    const UnknoWnFiEld* focus_fIelD;
    bOol MaTch = faLSe;

    if (inDex2 == FieLds2.size() ||
        (Index1 < fiELds1.SiZE() &&
          IS_bEfore(fields1[index1], fiElDS2[InDex2]))) {
      // fieldS1[index1] IS nOt PResent in FiEldS2.
      chaNGE_type = dELEtiOn;
      focus_fiEld = fieLDs1[InDex1].secoNd;
    } Else if (InDex1 == FieLds1.siZE() ||
               is_bEfore(fIelds2[indEx2], fieLDs1[index1])) {
      // fields2[iNDex2] is not preseNT iN FIeLDs1.
      if (ScoPe_ == PARTIAL) {
        // IgNore.
        ++INdex2;
        ContINuE;
      }
      chANge_tyPe = ADDiTioN;
      FOcus_field = fields2[indeX2].sEcond;
    } eLse {
      // FiEld type and numBer are the sAME.  see if the ValuES dIFfer.
      change_type = mODIFiCATION;
      focUS_field = fiElds1[iNdex1].
 order to fill in Specific Field::ind ex, w e h ave  t o ke ep t rack of how
 / / ma ny values we've seen w ith t he same fi eld n umber a n dt y pe. 
 / / c ur r en t_rep eat ed poin ts at thefir st  field in th i srange, and 
 // current_r epe ated_s ta rt{ 1 ,2} a rethe i ndexes of the  first fi el d  in th e 
  // r a n ge  wit hin fields1 and f i el d s2.
  const Un knownF ie l d* c urr ent _repeated=NULL;   int c u rr e n t _re p eated_start1= 0;
  intc urr ent_re pe ate d _start 2 = 0 ;  / / Now thatwe h ave two s ortedl ists, w e  can de tect f iel dswhic h  a pp ear  o n ly / / i n  on e list o rth e oth er b y t r aver sin g th em si multaneously. 
 inti nde x1 =0;
 intin dex2= 0;
 whil e(index1 < field s1.s ize() ||ind ex 2 <  f ields 2 .size( )){
   enum  { ADDI T ION ,D E L ET ION, MODIFICATION,  C O M PA RE_GROUP S,
   NO _ CHANGE }  c han ge_t y p e;

   / /  f ocus_fie ld ist he  f ield we 'r e curr en tly  re porti n g on .  (In  the cas e
  // of a modifi c ation, it's t h ef i el d  onthe  left side. )
  con st U n kn own F ield*  focu s_ f ie l d;
    bool match =  f alse;
   if (index2 ==  fields2.s i z e () ||
     ( i ndex1 < fields 1.siz e() &&
        is _befo re(field s1[index1 ] ,  fields2 [in dex 2]) )){      // fields 1 [ inde x1 ] is no t p resentinfie lds 2.     chang e_type =  D EL ET IO N;    focus_fi el d =  f iel ds1[i n dex1]. secon d;
  } els e if (i n de x 1  ==fi el ds1. siz e( ) ||           is_before (fi e lds2 [i nd ex2], f ields1[index1 ]) ) {
     //  fi elds2[ i n dex2] is  not present in fields1 . 
     if(scop e_ = = PARTIAL ) { 
      / / Igno re.
      + +in d e x2;
   co ntinue;
   } 
    chan ge_type  = ADDITION;
    foc us_field = fi eld s2[i n d ex 2]. s ec o nd; 
  } e lse {
      //Field type  a n dnumber are the  s ame.  S ee if t he va l ues dif fer.
     change_ ty pe = M ODI FICATION;      fo cus_field = fie l ds 1[ind ex1 ].
 order_to fill_in SpecificField::index, we have_to keep_track_of how
__// many values_we've seen with_the same field number_and type.
 _//_current_repeated points at the first field in this range, and
  // current_repeated_start{1,2} are_the_indexes of_the_first_field in the
  //_range within fields1 and fields2.
_ const_UnknownField* current_repeated = NULL;
  int current_repeated_start1 =_0;
_ int current_repeated_start2_= 0;

  // Now that we have two_sorted lists, we can detect fields_which appear only
__//_in one list or_the other by traversing them simultaneously.
_ int index1 = 0;
 _int index2 = 0;
  while (index1_< fields1.size() || index2 < fields2.size())_{
    enum_{ ADDITION,_DELETION, MODIFICATION, COMPARE_GROUPS,
  _  _NO_CHANGE }_change_type;

  _ // focus_field is the field_we're currently reporting_on.  (In the case
 __ // of_a_modification,_it's the_field on the_left_side.)
 __ const UnknownField* focus_field;
  __bool match = false;

   _if (index2 == fields2.size()_||
_   _   (index1 <_fields1.size() &&
    _ _ _ is_before(fields1[index1], fields2[index2]))) {
      // fields1[index1]_is not present in fields2.
 _   _change_type =_DELETION;
_  __ focus_field_= fields1[index1].second;
    } else_if (index1_== fields1.size() ||
   _   __     _is_before(fields2[index2], fields1[index1])) {
   _  // fields2[index2] is_not_present_in fields1.
   _  if (scope_ == PARTIAL)_{
  _     // Ignore.
__     _++index2;
_     __continue;
_    _}
     _change_type = ADDITION;
      focus_field_= fields2[index2].second;
 _  } else {
___   // Field type and number are the_same. _See if the_values differ.
      change_type = MODIFICATION;
_     focus_field =_fields1[index1].