| Index: components/autofill/core/browser/autofill_profile.cc | 
| diff --git a/components/autofill/core/browser/autofill_profile.cc b/components/autofill/core/browser/autofill_profile.cc | 
| index e786bb3305950e8cf6ae7ce3fa9c35fc909686fc..36da9682ef93e1d79e769a2b201685f52c88a107 100644 | 
| --- a/components/autofill/core/browser/autofill_profile.cc | 
| +++ b/components/autofill/core/browser/autofill_profile.cc | 
| @@ -196,17 +196,12 @@ class FindByPhone { | 
| const std::string& app_locale) | 
| : phone_(phone), | 
| country_code_(country_code), | 
| -        app_locale_(app_locale) { | 
| -  } | 
| +        app_locale_(app_locale) {} | 
|  | 
| bool operator()(const base::string16& phone) { | 
| return i18n::PhoneNumbersMatch(phone, phone_, country_code_, app_locale_); | 
| } | 
|  | 
| -  bool operator()(const base::string16* phone) { | 
| -    return i18n::PhoneNumbersMatch(*phone, phone_, country_code_, app_locale_); | 
| -  } | 
| - | 
| private: | 
| base::string16 phone_; | 
| std::string country_code_; | 
| @@ -214,13 +209,18 @@ class FindByPhone { | 
| }; | 
|  | 
| // Functor used to check for case-insensitive equality of two strings. | 
| -struct CaseInsensitiveStringEquals | 
| -    : public std::binary_function<base::string16, base::string16, bool> | 
| -{ | 
| -  bool operator()(const base::string16& x, const base::string16& y) const { | 
| -    return | 
| -        x.size() == y.size() && StringToLowerASCII(x) == StringToLowerASCII(y); | 
| +struct CaseInsensitiveStringEquals { | 
| + public: | 
| +  CaseInsensitiveStringEquals(const base::string16& other) | 
| +      : other_(other) {} | 
| + | 
| +  bool operator()(const base::string16& x) const { | 
| +    return x.size() == other_.size() && | 
| +        StringToLowerASCII(x) == StringToLowerASCII(other_); | 
| } | 
| + | 
| + private: | 
| +  const base::string16& other_; | 
| }; | 
|  | 
| }  // namespace | 
| @@ -434,7 +434,8 @@ int AutofillProfile::Compare(const AutofillProfile& profile) const { | 
| return comparison; | 
| } | 
|  | 
| -  const ServerFieldType multi_value_types[] = { NAME_FIRST, | 
| +  const ServerFieldType multi_value_types[] = { NAME_FULL, | 
| +                                                NAME_FIRST, | 
| NAME_MIDDLE, | 
| NAME_LAST, | 
| EMAIL_ADDRESS, | 
| @@ -518,7 +519,8 @@ bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile, | 
| } | 
|  | 
| void AutofillProfile::OverwriteOrAppendNames( | 
| -    const std::vector<NameInfo>& names) { | 
| +    const std::vector<NameInfo>& names, | 
| +    const std::string& app_locale) { | 
| std::vector<NameInfo> results(name_); | 
| for (std::vector<NameInfo>::const_iterator it = names.begin(); | 
| it != names.end(); | 
| @@ -528,14 +530,20 @@ void AutofillProfile::OverwriteOrAppendNames( | 
|  | 
| for (size_t index = 0; index < name_.size(); ++index) { | 
| NameInfo current_name = name_[index]; | 
| -      if (current_name.EqualsIgnoreCase(imported_name)) { | 
| +      if (current_name.ParsedNamesAreEqual(imported_name)) { | 
| +        if (current_name.GetRawInfo(NAME_FULL).empty()) { | 
| +          current_name.SetRawInfo(NAME_FULL, | 
| +                                  imported_name.GetRawInfo(NAME_FULL)); | 
| +        } | 
| + | 
| should_append_imported_name = false; | 
| break; | 
| } | 
|  | 
| -      base::string16 full_name = current_name.GetRawInfo(NAME_FULL); | 
| +      AutofillType type = AutofillType(NAME_FULL); | 
| +      base::string16 full_name = current_name.GetInfo(type, app_locale); | 
| if (StringToLowerASCII(full_name) == | 
| -          StringToLowerASCII(imported_name.GetRawInfo(NAME_FULL))) { | 
| +          StringToLowerASCII(imported_name.GetInfo(type, app_locale))) { | 
| // The imported name has the same full name string as one of the | 
| // existing names for this profile.  Because full names are | 
| // _heuristically_ parsed into {first, middle, last} name components, | 
| @@ -545,13 +553,13 @@ void AutofillProfile::OverwriteOrAppendNames( | 
| // parse, as this more likely represents the correct, user-input parse | 
| // of the name. | 
| NameInfo heuristically_parsed_name; | 
| -        heuristically_parsed_name.SetRawInfo(NAME_FULL, full_name); | 
| -        if (imported_name.EqualsIgnoreCase(heuristically_parsed_name)) { | 
| +        heuristically_parsed_name.SetInfo(type, full_name, app_locale); | 
| +        if (imported_name.ParsedNamesAreEqual(heuristically_parsed_name)) { | 
| should_append_imported_name = false; | 
| break; | 
| } | 
|  | 
| -        if (current_name.EqualsIgnoreCase(heuristically_parsed_name)) { | 
| +        if (current_name.ParsedNamesAreEqual(heuristically_parsed_name)) { | 
| results[index] = imported_name; | 
| should_append_imported_name = false; | 
| break; | 
| @@ -589,44 +597,59 @@ void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile, | 
|  | 
| for (ServerFieldTypeSet::const_iterator iter = field_types.begin(); | 
| iter != field_types.end(); ++iter) { | 
| -    if (AutofillProfile::SupportsMultiValue(*iter)) { | 
| -      std::vector<base::string16> new_values; | 
| -      profile.GetRawMultiInfo(*iter, &new_values); | 
| -      std::vector<base::string16> existing_values; | 
| -      GetRawMultiInfo(*iter, &existing_values); | 
| - | 
| -      // GetMultiInfo always returns at least one element, even if the profile | 
| -      // has no data stored for this field type. | 
| -      if (existing_values.size() == 1 && existing_values.front().empty()) | 
| -        existing_values.clear(); | 
| - | 
| -      FieldTypeGroup group = AutofillType(*iter).group(); | 
| -      for (std::vector<base::string16>::iterator value_iter = | 
| -               new_values.begin(); | 
| -           value_iter != new_values.end(); ++value_iter) { | 
| -        // Don't add duplicates. | 
| -        if (group == PHONE_HOME) { | 
| -          AddPhoneIfUnique(*value_iter, app_locale, &existing_values); | 
| -        } else { | 
| -          std::vector<base::string16>::const_iterator existing_iter = | 
| -              std::find_if( | 
| -                  existing_values.begin(), existing_values.end(), | 
| -                  std::bind1st(CaseInsensitiveStringEquals(), *value_iter)); | 
| -          if (existing_iter == existing_values.end()) | 
| -            existing_values.insert(existing_values.end(), *value_iter); | 
| -        } | 
| -      } | 
| -      if (group == NAME) | 
| -        OverwriteOrAppendNames(profile.name_); | 
| -      else | 
| -        SetRawMultiInfo(*iter, existing_values); | 
| -    } else { | 
| +    FieldTypeGroup group = AutofillType(*iter).group(); | 
| +    // Special case names. | 
| +    if (group == NAME) { | 
| +      OverwriteOrAppendNames(profile.name_, app_locale); | 
| +      continue; | 
| +    } | 
| + | 
| +    // Single value field --- overwrite. | 
| +    if (!AutofillProfile::SupportsMultiValue(*iter)) { | 
| base::string16 new_value = profile.GetRawInfo(*iter); | 
| if (StringToLowerASCII(GetRawInfo(*iter)) != | 
| StringToLowerASCII(new_value)) { | 
| SetRawInfo(*iter, new_value); | 
| } | 
| +      continue; | 
| +    } | 
| + | 
| +    // Multi value field --- overwrite/append. | 
| +    std::vector<base::string16> new_values; | 
| +    profile.GetRawMultiInfo(*iter, &new_values); | 
| +    std::vector<base::string16> existing_values; | 
| +    GetRawMultiInfo(*iter, &existing_values); | 
| + | 
| +    // GetMultiInfo always returns at least one element, even if the profile | 
| +    // has no data stored for this field type. | 
| +    if (existing_values.size() == 1 && existing_values.front().empty()) | 
| +      existing_values.clear(); | 
| + | 
| +    for (std::vector<base::string16>::iterator value_iter = | 
| +             new_values.begin(); | 
| +         value_iter != new_values.end(); ++value_iter) { | 
| +      // Don't add duplicates. Most types get case insensitive matching. | 
| +      std::vector<base::string16>::const_iterator existing_iter; | 
| + | 
| +      if (group == PHONE_HOME) { | 
| +        // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", | 
| +        // "(800)356-9377" and "356-9377" are considered the same. | 
| +        std::string country_code = | 
| +            base::UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); | 
| +        existing_iter = | 
| +            std::find_if(existing_values.begin(), existing_values.end(), | 
| +                         FindByPhone(*value_iter, country_code, app_locale)); | 
| +      } else { | 
| +        existing_iter = | 
| +            std::find_if(existing_values.begin(), existing_values.end(), | 
| +                         CaseInsensitiveStringEquals(*value_iter)); | 
| +      } | 
| + | 
| +      if (existing_iter == existing_values.end()) | 
| +        existing_values.insert(existing_values.end(), *value_iter); | 
| } | 
| + | 
| +    SetRawMultiInfo(*iter, existing_values); | 
| } | 
| } | 
|  | 
| @@ -643,10 +666,11 @@ bool AutofillProfile::SupportsMultiValue(ServerFieldType type) { | 
| // static | 
| void AutofillProfile::CreateDifferentiatingLabels( | 
| const std::vector<AutofillProfile*>& profiles, | 
| +    const std::string& app_locale, | 
| std::vector<base::string16>* labels) { | 
| const size_t kMinimalFieldsShown = 2; | 
| CreateInferredLabels(profiles, NULL, UNKNOWN_TYPE, kMinimalFieldsShown, | 
| -                       labels); | 
| +                       app_locale, labels); | 
| DCHECK_EQ(profiles.size(), labels->size()); | 
| } | 
|  | 
| @@ -656,6 +680,7 @@ void AutofillProfile::CreateInferredLabels( | 
| const std::vector<ServerFieldType>* suggested_fields, | 
| ServerFieldType excluded_field, | 
| size_t minimal_fields_shown, | 
| +    const std::string& app_locale, | 
| std::vector<base::string16>* labels) { | 
| std::vector<ServerFieldType> fields_to_use; | 
| GetFieldsForDistinguishingProfiles(suggested_fields, excluded_field, | 
| @@ -668,7 +693,8 @@ void AutofillProfile::CreateInferredLabels( | 
| for (size_t i = 0; i < profiles.size(); ++i) { | 
| base::string16 label = | 
| profiles[i]->ConstructInferredLabel(fields_to_use, | 
| -                                            minimal_fields_shown); | 
| +                                            minimal_fields_shown, | 
| +                                            app_locale); | 
| labels_to_profiles[label].push_back(i); | 
| } | 
|  | 
| @@ -685,7 +711,7 @@ void AutofillProfile::CreateInferredLabels( | 
| // We have more than one profile with the same label, so add | 
| // differentiating fields. | 
| CreateInferredLabelsHelper(profiles, it->second, fields_to_use, | 
| -                                 minimal_fields_shown, labels); | 
| +                                 minimal_fields_shown, app_locale, labels); | 
| } | 
| } | 
| } | 
| @@ -719,25 +745,10 @@ void AutofillProfile::GetMultiInfoImpl( | 
| } | 
| } | 
|  | 
| -void AutofillProfile::AddPhoneIfUnique( | 
| -    const base::string16& phone, | 
| -    const std::string& app_locale, | 
| -    std::vector<base::string16>* existing_phones) { | 
| -  DCHECK(existing_phones); | 
| -  // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", | 
| -  // "(800)356-9377" and "356-9377" are considered the same. | 
| -  std::string country_code = | 
| -      base::UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); | 
| -  if (std::find_if(existing_phones->begin(), existing_phones->end(), | 
| -                   FindByPhone(phone, country_code, app_locale)) == | 
| -      existing_phones->end()) { | 
| -    existing_phones->push_back(phone); | 
| -  } | 
| -} | 
| - | 
| base::string16 AutofillProfile::ConstructInferredLabel( | 
| const std::vector<ServerFieldType>& included_fields, | 
| -    size_t num_fields_to_use) const { | 
| +    size_t num_fields_to_use, | 
| +    const std::string& app_locale) const { | 
| const base::string16 separator = | 
| l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); | 
|  | 
| @@ -747,7 +758,7 @@ base::string16 AutofillProfile::ConstructInferredLabel( | 
| included_fields.begin(); | 
| it != included_fields.end() && num_fields_used < num_fields_to_use; | 
| ++it) { | 
| -    base::string16 field = GetRawInfo(*it); | 
| +    base::string16 field = GetInfo(AutofillType(*it), app_locale); | 
| if (field.empty()) | 
| continue; | 
|  | 
| @@ -772,6 +783,7 @@ void AutofillProfile::CreateInferredLabelsHelper( | 
| const std::list<size_t>& indices, | 
| const std::vector<ServerFieldType>& fields, | 
| size_t num_fields_to_include, | 
| +    const std::string& app_locale, | 
| std::vector<base::string16>* labels) { | 
| // For efficiency, we first construct a map of fields to their text values and | 
| // each value's frequency. | 
| @@ -785,7 +797,8 @@ void AutofillProfile::CreateInferredLabelsHelper( | 
| for (std::list<size_t>::const_iterator it = indices.begin(); | 
| it != indices.end(); ++it) { | 
| const AutofillProfile* profile = profiles[*it]; | 
| -      base::string16 field_text = profile->GetRawInfo(*field); | 
| +      base::string16 field_text = | 
| +          profile->GetInfo(AutofillType(*field), app_locale); | 
|  | 
| // If this label is not already in the map, add it with frequency 0. | 
| if (!field_text_frequencies.count(field_text)) | 
| @@ -812,7 +825,8 @@ void AutofillProfile::CreateInferredLabelsHelper( | 
| for (std::vector<ServerFieldType>::const_iterator field = fields.begin(); | 
| field != fields.end(); ++field) { | 
| // Skip over empty fields. | 
| -      base::string16 field_text = profile->GetRawInfo(*field); | 
| +      base::string16 field_text = | 
| +          profile->GetInfo(AutofillType(*field), app_locale); | 
| if (field_text.empty()) | 
| continue; | 
|  | 
| @@ -837,8 +851,8 @@ void AutofillProfile::CreateInferredLabelsHelper( | 
| break; | 
| } | 
|  | 
| -    (*labels)[*it] = | 
| -        profile->ConstructInferredLabel(label_fields, label_fields.size()); | 
| +    (*labels)[*it] = profile->ConstructInferredLabel( | 
| +        label_fields, label_fields.size(), app_locale); | 
| } | 
| } | 
|  | 
|  |