nsCAutoString fractionString;  nsCAutoString fractionStringWithoutDenominator;
nsAutoString fractionString;  nsAutoString fractionStringWithoutDenominator;
wallet_ResolvePositionalSchema(nsIDOMNode* elementNode, nsACString& schema) {  static PRInt32 numerator = 0;  static PRInt32 denominator = 0;  static nsCString lastPositionalSchema;  /* return if no PositionalSchema list exists */  if (!wallet_PositionalSchema_list) {    schema.SetLength(0);    return;  }  if (!schema.IsEmpty()) {    numerator = 0;    denominator = 0;    lastPositionalSchema.Assign(schema);  } else if (numerator < denominator) {    schema.Assign(lastPositionalSchema);  } else {    schema.SetLength(0);    return;  }  /* search PositionalSchema list for our positional schema */  wallet_MapElement * mapElementPtr;  PRInt32 count = LIST_COUNT(wallet_PositionalSchema_list);  for (PRInt32 i=0; i<count; i++) {    mapElementPtr = NS_STATIC_CAST(wallet_MapElement*, wallet_PositionalSchema_list->ElementAt(i));    if (schema.Equals(mapElementPtr->item1, nsCaseInsensitiveCStringComparator())) {      /* found our positional schema in the list */      /* A "position set" is a set of continuous <input> or <select> fields       * with no displayable text between them.  For example: zipcode [     ]-[    ].       * We need to determine how many elements are in the current set (denominator)       * and which of those elements we are currently up to (numerator).  From that       * we can identify our position with the fraction x/y meaning the xth element       * out of a set of y.  We use that fraction when consulting the positionalSchema list       * to determine which schema should be used.       *       * So for example, the positionalSchema list for %zip might be:       *       *    1/1  Home.PostalCode       *    1/2  Home.PostalCode.Prefix       *    2/2  Home.PostalCode.Suffix       *       * The positionalSchema list also contains fractions with no denominators, for example x/.       * That means the xth element out of a set of any length.  These entries come last in       * the positionalSchema list so they can match only if no match for a specific length is       * found.  As an example, the positionalSchema list for %phone might be:       *       *    1/1 Home.Phone       *    1/2 Home.Phone.LocCode       *    2/2 Home.Phone.Number       *    1/  Home.Phone.LocCode       *    2/  Home.Phone.Number.Prefix       *    3/  Home.Phone.Number.Suffix       */      if (numerator < denominator) {        /* this is a continuation of previous position set */        numerator++;      } else {        /* start a new position set */        numerator = 1; /* start with first element */        /* determine how many elements in current position set (denominator) */        denominator = 1; /* assume that's the only element */        PRBool atInputOrSelect = PR_FALSE;        PRBool charFound = PR_FALSE;        while (!charFound) {          nsAutoString text;          PRBool atEnd;          wallet_StepForwardOrBack            (elementNode, text, atInputOrSelect, atEnd, PR_TRUE); /* step forward */          if (atEnd) {            break;          }          PRUnichar c;          for (PRUint32 j=0; j<text.Length(); j++) {            c = text.CharAt(j);            /* break out if an alphanumeric character is found *///          nsresult res = nsServiceManager::GetService(kUnicharUtilCID, kICaseConversionIID,//                                      (nsISupports**)&gCaseConv);////          nsIUGenCategory* intl =  nsnull;//          nsresult rv = nsServiceManager::GetService(kUnicharUtilCID, kIUGenCategoryIID,//                                      (nsISupports**)&intl);//          Whaaaaaa, intl is never released here!//          if (NS_SUCCEEDED(rv) && intl) {//            PRBool accept;//            rv = intl->Is(c, intl->kUGenCategory_Number, &accept);//            if (NS_FAILED(rv) || !accept) {//              rv = intl->Is(c, intl->kUGenCategory_Letter, &accept);//            }//            if (NS_OK(rv) && accept) {//              charFound = PR_TRUE;//              break;//            }//          } else {//            /* failed to get the i18n interfaces, so just treat latin characters */              if (nsCRT::IsAsciiAlpha(c) || nsCRT::IsAsciiDigit(c)) {                charFound = PR_TRUE;                break;//            }            }          }          if (!charFound && atInputOrSelect) {            /* add one more element to position set */            denominator++;          }        }      }      nsCAutoString fractionString; /* of form 2/5 meaning 2nd in a 5-element set */      nsCAutoString fractionStringWithoutDenominator; /* of form 2/ meaning 2nd in any-length set */      fractionString.SetLength(0);      fractionString.AppendInt(numerator);      fractionString.Append("/");      fractionStringWithoutDenominator.Assign(fractionString);      fractionString.AppendInt(denominator);      /* use positionalSchema list to obtain schema */      wallet_Sublist * sublistPtr;      PRInt32 count2 = LIST_COUNT(mapElementPtr->itemList);      for (PRInt32 j=0; j<count2; j=j+2) {        sublistPtr = NS_STATIC_CAST(wallet_Sublist*, mapElementPtr->itemList->ElementAt(j));        if (!PL_strcmp(sublistPtr->item, fractionString.get()) ||            !PL_strcmp(sublistPtr->item, fractionStringWithoutDenominator.get())) {          sublistPtr = NS_STATIC_CAST(wallet_Sublist*, mapElementPtr->itemList->ElementAt(j+1));          schema.Assign(sublistPtr->item);          return;        }      }    }  }}