Autofill phone number enhancements and integration of Phone Number Util Library: part 3
BUG=71443
TEST=unit-tested
Review URL: http://codereview.chromium.org/6877130

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86305 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc
index 5829c5c7..96a4ba1 100644
--- a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc
+++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc
@@ -19,6 +19,8 @@
 #include "chrome/browser/autofill/field_types.h"
 #include "chrome/browser/autofill/form_group.h"
 #include "chrome/browser/autofill/personal_data_manager.h"
+#include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
 #include "chrome/browser/sync/util/data_encryption.h"
 
 using base::win::RegKey;
@@ -131,6 +133,10 @@
 
   bool has_non_empty_fields = false;
 
+  // Phones need to be rebuilt.
+  PhoneNumber::PhoneCombineHelper home(AutofillType::PHONE_HOME);
+  PhoneNumber::PhoneCombineHelper fax(AutofillType::PHONE_FAX);
+
   for (uint32 value_index = 0; value_index < key->ValueCount(); ++value_index) {
     std::wstring value_name;
     if (key->ReadName(value_index, &value_name) != ERROR_SUCCESS)
@@ -144,9 +150,21 @@
       if (it->second == CREDIT_CARD_NUMBER) {
         field_value = DecryptCCNumber(field_value);
       }
-      profile->SetInfo(it->second, field_value);
+      // We need to store phone data in the variables, before building the whole
+      // number at the end. The rest of the fields are set "as is".
+      if (!home.SetInfo(it->second, field_value) &&
+          !fax.SetInfo(it->second, field_value)) {
+        profile->SetInfo(it->second, field_value);
+      }
     }
   }
+  // Now re-construct the phones if needed.
+  string16 constructed_number;
+  if (!home.empty() && home.ParseNumber(std::string("US"), &constructed_number))
+    profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number);
+  if (!fax.empty() && fax.ParseNumber(std::string("US"), &constructed_number))
+    profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, constructed_number);
+
   return has_non_empty_fields;
 }
 
@@ -219,15 +237,6 @@
     AutofillProfile profile;
     if (ImportSingleProfile(&profile, &key, reg_to_field)) {
       // Combine phones into whole phone #.
-      string16 phone;
-      phone = profile.GetInfo(PHONE_HOME_COUNTRY_CODE);
-      phone.append(profile.GetInfo(PHONE_HOME_CITY_CODE));
-      phone.append(profile.GetInfo(PHONE_HOME_NUMBER));
-      profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, phone);
-      phone = profile.GetInfo(PHONE_FAX_COUNTRY_CODE);
-      phone.append(profile.GetInfo(PHONE_FAX_CITY_CODE));
-      phone.append(profile.GetInfo(PHONE_FAX_NUMBER));
-      profile.SetInfo(PHONE_FAX_WHOLE_NUMBER, phone);
       profiles->push_back(profile);
     }
   }
diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc
index b1150383..240055f 100644
--- a/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc
+++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc
@@ -44,7 +44,7 @@
   { L"email", L"[email protected]" },
   { L"company_name", L"Testcompany" },
   { L"phone_home_number", L"555-5555" },
-  { L"phone_home_city_code", L"444" },
+  { L"phone_home_city_code", L"650" },
   { L"phone_home_country_code", L"1" },
 };
 
@@ -54,8 +54,8 @@
   { L"email", L"[email protected]" },
   { L"company_name", L"Testcompany" },
   { L"phone_fax_number", L"555-6666" },
-  { L"phone_fax_city_code", L"777" },
-  { L"phone_fax_country_code", L"2" },
+  { L"phone_fax_city_code", L"812" },
+  { L"phone_fax_country_code", L"7" },
 };
 
 ValueDescription credit_card[] = {
@@ -171,7 +171,7 @@
   EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_COUNTRY_CODE), profile1[7].value);
   EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_CITY_CODE), profile1[6].value);
   EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_NUMBER), L"5555555");
-  EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_WHOLE_NUMBER), L"14445555555");
+  EXPECT_EQ(profiles[1].GetInfo(PHONE_HOME_WHOLE_NUMBER), L"+16505555555");
 
   EXPECT_EQ(profiles[0].GetInfo(NAME_FIRST), profile2[0].value);
   EXPECT_EQ(profiles[0].GetInfo(NAME_LAST), profile2[1].value);
@@ -180,7 +180,7 @@
   EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_COUNTRY_CODE), profile2[6].value);
   EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_CITY_CODE), profile2[5].value);
   EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_NUMBER), L"5556666");
-  EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_WHOLE_NUMBER), L"27775556666");
+  EXPECT_EQ(profiles[0].GetInfo(PHONE_FAX_WHOLE_NUMBER), L"+78125556666");
 
   ASSERT_EQ(credit_cards.size(), 1);
   EXPECT_EQ(credit_cards[0].GetInfo(CREDIT_CARD_NAME), credit_card[0].value);
diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc
index 35ae16e..f576f646 100644
--- a/chrome/browser/autofill/autofill_manager_unittest.cc
+++ b/chrome/browser/autofill/autofill_manager_unittest.cc
@@ -1879,16 +1879,15 @@
   AutofillProfile *work_profile = autofill_manager_->GetProfileWithGUID(
       "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != NULL);
-  string16 saved_phone = work_profile->GetInfo(PHONE_HOME_NUMBER);
 
   GUIDPair guid(work_profile->guid(), 0);
   GUIDPair empty(std::string(), 0);
 
-  char test_data[] = "1234567890123456";
+  char test_data[] = "16505554567890123456";
   for (int i = arraysize(test_data) - 1; i >= 0; --i) {
     test_data[i] = 0;
     SCOPED_TRACE(StringPrintf("Testing phone: %s", test_data));
-    work_profile->SetInfo(PHONE_HOME_NUMBER, ASCIIToUTF16(test_data));
+    work_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16(test_data));
     // The page ID sent to the AutofillManager from the RenderView, used to send
     // an IPC message back to the renderer.
     int page_id = 100 - i;
@@ -1899,17 +1898,15 @@
     FormData results;
     EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
 
-    if (i != 7) {
-      EXPECT_EQ(ASCIIToUTF16(test_data), results.fields[2].value);
-      EXPECT_EQ(ASCIIToUTF16(test_data), results.fields[3].value);
+    if (i != 11) {
+      // The only parsable phone is 16505554567.
+      EXPECT_EQ(string16(), results.fields[2].value);
+      EXPECT_EQ(string16(), results.fields[3].value);
     } else {
-      // The only size that is parsed and split, right now is 7:
-      EXPECT_EQ(ASCIIToUTF16("123"), results.fields[2].value);
+      EXPECT_EQ(ASCIIToUTF16("555"), results.fields[2].value);
       EXPECT_EQ(ASCIIToUTF16("4567"), results.fields[3].value);
     }
   }
-
-  work_profile->SetInfo(PHONE_HOME_NUMBER, saved_phone);
 }
 
 // Test that we can still fill a form when a field has been removed from it.
diff --git a/chrome/browser/autofill/autofill_profile.cc b/chrome/browser/autofill/autofill_profile.cc
index f359799f..4df95bda 100644
--- a/chrome/browser/autofill/autofill_profile.cc
+++ b/chrome/browser/autofill/autofill_profile.cc
@@ -15,8 +15,8 @@
 #include "chrome/browser/autofill/address.h"
 #include "chrome/browser/autofill/autofill_type.h"
 #include "chrome/browser/autofill/contact_info.h"
-#include "chrome/browser/autofill/fax_number.h"
-#include "chrome/browser/autofill/home_phone_number.h"
+#include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
 #include "chrome/common/guid.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -117,13 +117,14 @@
 template <class T>
 void CopyValuesToItems(AutofillFieldType type,
                        const std::vector<string16>& values,
-                       std::vector<T>* form_group_items) {
+                       std::vector<T>* form_group_items,
+                       const T& prototype) {
   form_group_items->resize(values.size());
   for (size_t i = 0; i < form_group_items->size(); ++i)
     (*form_group_items)[i].SetInfo(type, CollapseWhitespace(values[i], false));
   // Must have at least one (possibly empty) element.
   if (form_group_items->empty())
-    form_group_items->resize(1);
+    form_group_items->resize(1, prototype);
 }
 
 template <class T>
@@ -174,18 +175,42 @@
   std::swap(*type_set, collapsed_set);
 }
 
+class FindByPhone {
+ public:
+  FindByPhone(const string16& phone, const std::string& country_code)
+      : phone_(phone),
+        country_code_(country_code) {
+  }
+
+  bool operator()(const string16& phone) {
+    return autofill_i18n::PhoneNumbersMatch(phone, phone_, country_code_);
+  }
+
+  bool operator()(const string16* phone) {
+    return autofill_i18n::PhoneNumbersMatch(*phone, phone_, country_code_);
+  }
+
+ private:
+  string16 phone_;
+  std::string country_code_;
+};
+
 }  // namespace
 
 AutofillProfile::AutofillProfile(const std::string& guid)
-    : guid_(guid), name_(1), email_(1), home_number_(1), fax_number_(1) {
+    : guid_(guid),
+      name_(1),
+      email_(1),
+      home_number_(1, PhoneNumber(AutofillType::PHONE_HOME)),
+      fax_number_(1, PhoneNumber(AutofillType::PHONE_FAX)) {
 }
 
 AutofillProfile::AutofillProfile()
     : guid_(guid::GenerateGUID()),
       name_(1),
       email_(1),
-      home_number_(1),
-      fax_number_(1) {
+      home_number_(1, PhoneNumber(AutofillType::PHONE_HOME)),
+      fax_number_(1, PhoneNumber(AutofillType::PHONE_FAX)) {
 }
 
 AutofillProfile::AutofillProfile(const AutofillProfile& profile)
@@ -246,16 +271,22 @@
                                    const std::vector<string16>& values) {
   switch (AutofillType(type).group()) {
     case AutofillType::NAME:
-      CopyValuesToItems(type, values, &name_);
+      CopyValuesToItems(type, values, &name_, NameInfo());
       break;
     case AutofillType::EMAIL:
-      CopyValuesToItems(type, values, &email_);
+      CopyValuesToItems(type, values, &email_, EmailInfo());
       break;
     case AutofillType::PHONE_HOME:
-      CopyValuesToItems(type, values, &home_number_);
+      CopyValuesToItems(type,
+                        values,
+                        &home_number_,
+                        PhoneNumber(AutofillType::PHONE_HOME));
       break;
     case AutofillType::PHONE_FAX:
-      CopyValuesToItems(type, values, &fax_number_);
+      CopyValuesToItems(type,
+                        values,
+                        &fax_number_,
+                        PhoneNumber(AutofillType::PHONE_FAX));
       break;
     default:
       if (values.size() == 1) {
@@ -463,6 +494,22 @@
          GetInfo(ADDRESS_HOME_CITY);
 }
 
+bool AutofillProfile::NormalizePhones() {
+  // Successful either if nothing to parse, or everything is parsed correctly.
+  bool success = true;
+  for (size_t i = 0; i < home_number_.size(); ++i) {
+    home_number_[i].set_locale(CountryCode());
+    if (!home_number_[i].NormalizePhone())
+      success = false;
+  }
+  for (size_t i = 0; i < fax_number_.size(); ++i) {
+    fax_number_[i].set_locale(CountryCode());
+    if (!fax_number_[i].NormalizePhone())
+      success = false;
+  }
+  return success;
+}
+
 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) {
   FieldTypeSet field_types;
   profile.GetNonEmptyTypes(&field_types);
@@ -478,12 +525,18 @@
       profile.GetMultiInfo(*iter, &new_values);
       std::vector<string16> existing_values;
       GetMultiInfo(*iter, &existing_values);
+      FieldTypeGroup group = AutofillType(*iter).group();
       for (std::vector<string16>::iterator value_iter = new_values.begin();
            value_iter != new_values.end(); ++value_iter) {
         // Don't add duplicates.
-        if (std::find(existing_values.begin(), existing_values.end(),
-                      *value_iter) == existing_values.end()) {
-          existing_values.insert(existing_values.end(), *value_iter);
+        if (group == AutofillType::PHONE_HOME ||
+            group == AutofillType::PHONE_FAX) {
+          AddPhoneIfUnique(*value_iter, &existing_values);
+        } else {
+          if (std::find(existing_values.begin(), existing_values.end(),
+                        *value_iter) == existing_values.end()) {
+            existing_values.insert(existing_values.end(), *value_iter);
+          }
         }
       }
       SetMultiInfo(*iter, existing_values);
@@ -493,6 +546,19 @@
   }
 }
 
+void AutofillProfile::AddPhoneIfUnique(const string16& phone,
+                                       std::vector<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::vector<string16>::const_iterator phone_iter;
+  if (std::find_if(existing_phones->begin(), existing_phones->end(),
+                   FindByPhone(phone, CountryCode())) ==
+      existing_phones->end()) {
+    existing_phones->push_back(phone);
+  }
+}
+
 string16 AutofillProfile::ConstructInferredLabel(
     const std::vector<AutofillFieldType>& included_fields,
     size_t num_fields_to_use) const {
diff --git a/chrome/browser/autofill/autofill_profile.h b/chrome/browser/autofill/autofill_profile.h
index 80a54e8..1ff9d8d 100644
--- a/chrome/browser/autofill/autofill_profile.h
+++ b/chrome/browser/autofill/autofill_profile.h
@@ -119,6 +119,13 @@
   // aid with correct aggregation of new data.
   const string16 PrimaryValue() const;
 
+  // Normalizes the home phone and fax numbers.
+  // Should be called after all of the form data is imported into profile.
+  // Drops unparsable numbers, so the numbers that are incomplete or wrong
+  // are not saved. Returns true if all numbers were successfully parsed,
+  // false otherwise.
+  bool NormalizePhones();
+
   // Overwrites the single-valued field data in |profile| with this
   // Profile.  Or, for multi-valued fields append the new values.
   void OverwriteWithOrAddTo(const AutofillProfile& profile);
@@ -126,6 +133,13 @@
  private:
   typedef std::vector<const FormGroup*> FormGroupList;
 
+  // Checks if the |phone| is in the |existing_phones| using fuzzy matching:
+  // for example, "1-800-FLOWERS", "18003569377", "(800)356-9377" and "356-9377"
+  // are considered the same.
+  // Adds the |phone| to the |existing_phones| if not already there.
+  void AddPhoneIfUnique(const string16& phone,
+                        std::vector<string16>* existing_phones);
+
   // Builds inferred label from the first |num_fields_to_include| non-empty
   // fields in |label_fields|. Uses as many fields as possible if there are not
   // enough non-empty fields.
@@ -161,8 +175,8 @@
   std::vector<NameInfo> name_;
   std::vector<EmailInfo> email_;
   CompanyInfo company_;
-  std::vector<HomePhoneNumber> home_number_;
-  std::vector<FaxNumber> fax_number_;
+  std::vector<PhoneNumber> home_number_;
+  std::vector<PhoneNumber> fax_number_;
   Address address_;
 };
 
diff --git a/chrome/browser/autofill/autofill_profile_unittest.cc b/chrome/browser/autofill/autofill_profile_unittest.cc
index 28b5f84..8bfb3bab 100644
--- a/chrome/browser/autofill/autofill_profile_unittest.cc
+++ b/chrome/browser/autofill/autofill_profile_unittest.cc
@@ -39,7 +39,7 @@
   AutofillProfile profile00;
   autofill_test::SetProfileInfo(&profile00, "", "Mitchell", "",
       "[email protected]", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US",
-      "12345678910", "01987654321");
+      "16505678910", "78127654321");
   EXPECT_TRUE(UpdateProfileLabel(&profile00));
   string16 summary00 = profile00.Label();
   EXPECT_EQ(ASCIIToUTF16("Hollywood, CA"), summary00);
@@ -48,7 +48,7 @@
   AutofillProfile profile1;
   autofill_test::SetProfileInfo(&profile1, "", "Mitchell", "",
       "[email protected]", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
-      "91601", "US", "12345678910", "01987654321");
+      "91601", "US", "16505678910", "78127654321");
   EXPECT_TRUE(UpdateProfileLabel(&profile1));
   string16 summary1 = profile1.Label();
   EXPECT_EQ(ASCIIToUTF16("123 Zoo St., Hollywood"), summary1);
@@ -57,7 +57,7 @@
   AutofillProfile profile2;
   autofill_test::SetProfileInfo(&profile2, "", "Mitchell",
       "Morrison", "[email protected]", "Fox", "", "unit 5", "Hollywood", "CA",
-      "91601", "US", "12345678910", "01987654321");
+      "91601", "US", "16505678910", "78127654321");
   EXPECT_TRUE(UpdateProfileLabel(&profile2));
   string16 summary2 = profile2.Label();
   // Summary does include full name which is empty if the first name is empty.
@@ -67,7 +67,7 @@
   AutofillProfile profile3;
   autofill_test::SetProfileInfo(&profile3, "", "Mitchell",
       "Morrison", "[email protected]", "Fox", "123 Zoo St.", "unit 5",
-      "Hollywood", "CA", "91601", "US", "12345678910", "01987654321");
+      "Hollywood", "CA", "91601", "US", "16505678910", "78127654321");
   EXPECT_TRUE(UpdateProfileLabel(&profile3));
   string16 summary3 = profile3.Label();
   EXPECT_EQ(ASCIIToUTF16("123 Zoo St., Hollywood"), summary3);
@@ -76,7 +76,7 @@
   AutofillProfile profile4;
   autofill_test::SetProfileInfo(&profile4, "Marion", "Mitchell", "",
       "[email protected]", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US",
-      "12345678910", "01987654321");
+      "16505678910", "01987654321");
   EXPECT_TRUE(UpdateProfileLabel(&profile4));
   string16 summary4 = profile4.Label();
   EXPECT_EQ(ASCIIToUTF16("Marion Mitchell, Hollywood"), summary4);
@@ -85,7 +85,7 @@
   AutofillProfile profile5;
   autofill_test::SetProfileInfo(&profile5, "Marion", "Mitchell", "",
       "[email protected]", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
-      "91601", "US", "12345678910", "01987654321");
+      "91601", "US", "16505678910", "78127654321");
   EXPECT_TRUE(UpdateProfileLabel(&profile5));
   string16 summary5 = profile5.Label();
   EXPECT_EQ(ASCIIToUTF16("Marion Mitchell, 123 Zoo St."), summary5);
@@ -94,7 +94,7 @@
   AutofillProfile profile6;
   autofill_test::SetProfileInfo(&profile6, "Marion", "Mitchell",
       "Morrison", "[email protected]", "Fox", "", "unit 5", "Hollywood", "CA",
-      "91601", "US", "12345678910", "01987654321");
+      "91601", "US", "16505678910", "78127654321");
   EXPECT_TRUE(UpdateProfileLabel(&profile6));
   string16 summary6 = profile6.Label();
   EXPECT_EQ(ASCIIToUTF16("Marion Mitchell Morrison, Hollywood"),
@@ -104,7 +104,7 @@
   AutofillProfile profile7;
   autofill_test::SetProfileInfo(&profile7, "Marion", "Mitchell",
       "Morrison", "[email protected]", "Fox", "123 Zoo St.", "unit 5",
-      "Hollywood", "CA", "91601", "US", "12345678910", "01987654321");
+      "Hollywood", "CA", "91601", "US", "16505678910", "78127654321");
   EXPECT_TRUE(UpdateProfileLabel(&profile7));
   string16 summary7 = profile7.Label();
   EXPECT_EQ(ASCIIToUTF16("Marion Mitchell Morrison, 123 Zoo St."),
@@ -115,7 +115,7 @@
   AutofillProfile profile7a;
   autofill_test::SetProfileInfo(&profile7a, "Marion", "Mitchell",
     "Morrison", "[email protected]", "Fox", "123 Zoo St.", "unit 5",
-    "Hollywood", "CA", "91601", "US", "12345678910", "01987654321");
+    "Hollywood", "CA", "91601", "US", "16505678910", "78127654321");
   std::vector<AutofillProfile*> profiles;
   profiles.push_back(&profile7);
   profiles.push_back(&profile7a);
@@ -143,8 +143,8 @@
       "Elysium", "CA",
       "91111",
       "US",
-      "11111111111",
-      "22222222222");
+      "16502111111",
+      "16502222222");
   profiles.push_back(new AutofillProfile);
   autofill_test::SetProfileInfo(
       profiles[1],
@@ -182,8 +182,8 @@
       "Elysium", "CA",
       "91111",
       "US",
-      "11111111111",
-      "22222222222");
+      "16502111111",
+      "16502222222");
   EXPECT_TRUE(AutofillProfile::AdjustInferredLabels(&profiles));
 
   // Profile 0 and 2 inferred label now includes an e-mail.
@@ -210,17 +210,17 @@
       "Elysium", "CA",
       "91111",
       "US",
-      "11111111111",
-      "33333333333");  // Fax is different
+      "16502111111",
+      "16503333333");  // Fax is different
 
   EXPECT_TRUE(AutofillProfile::AdjustInferredLabels(&profiles));
 
   // Profile 0 and 2 inferred label now includes a fax number.
-  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., fax:#22222222222"),
+  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., fax:#16502222222"),
             profiles[0]->Label());
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."),
             profiles[1]->Label());
-  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., fax:#33333333333"),
+  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., fax:#16503333333"),
             profiles[2]->Label());
 
   profiles.push_back(new AutofillProfile);
@@ -236,22 +236,22 @@
       "Elysium", "CA",
       "91111",
       "US",
-      "44444444444",  // Phone is different for some.
-      "33333333333");  // Fax is different for some.
+      "16504444444",  // Phone is different for some.
+      "16503333333");  // Fax is different for some.
 
   EXPECT_TRUE(AutofillProfile::AdjustInferredLabels(&profiles));
 
-  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 11111111111,"
-                         " fax:#22222222222"),
+  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 16502111111,"
+                         " fax:#16502222222"),
             profiles[0]->Label());
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."),
             profiles[1]->Label());
-  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 11111111111,"
-                         " fax:#33333333333"),
+  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 16502111111,"
+                         " fax:#16503333333"),
             profiles[2]->Label());
   // This one differs from other ones by unique phone, so no need for extra
   // information.
-  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 44444444444"),
+  EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., 16504444444"),
             profiles[3]->Label());
 
   profiles.push_back(new AutofillProfile);
@@ -267,21 +267,21 @@
       "Elysium", "CA",
       "91111",
       "US",
-      "44444444444",  // Phone is different for some.
-      "33333333333");  // Fax is different for some.
+      "16504444444",  // Phone is different for some.
+      "16503333333");  // Fax is different for some.
 
   EXPECT_TRUE(AutofillProfile::AdjustInferredLabels(&profiles));
 
   EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., [email protected],"
-                         " 11111111111, fax:#22222222222"),
+                         " 16502111111, fax:#16502222222"),
             profiles[0]->Label());
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."),
             profiles[1]->Label());
   EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., [email protected],"
-                         " 11111111111, fax:#33333333333"),
+                         " 16502111111, fax:#16503333333"),
             profiles[2]->Label());
   EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., [email protected],"
-                         " 44444444444, fax:#33333333333"),
+                         " 16504444444, fax:#16503333333"),
             profiles[3]->Label());
   // This one differs from other ones by unique e-mail, so no need for extra
   // information.
@@ -308,8 +308,8 @@
                                 "Elysium", "CA",
                                 "91111",
                                 "US",
-                                "11111111111",
-                                "22222222222");
+                                "16502111111",
+                                "16502222222");
   profiles.push_back(new AutofillProfile);
   autofill_test::SetProfileInfo(profiles[1],
                                 "Jane",
@@ -754,7 +754,7 @@
   AutofillProfile p2 = p;
   EXPECT_EQ(0, p.Compare(p2));
   EXPECT_EQ(0, p.CompareMulti(p2));
-  const string16 kNoOne(ASCIIToUTF16("4151110000"));
+  const string16 kNoOne(ASCIIToUTF16("4152110000"));
   set_values[1] = kNoOne;
   p.SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, set_values);
   p.GetMultiInfo(PHONE_HOME_WHOLE_NUMBER, &get_values);
@@ -777,8 +777,8 @@
 
 TEST(AutofillProfileTest, MultiValueFax) {
   AutofillProfile p;
-  const string16 kJohnDoe(ASCIIToUTF16("4151112222"));
-  const string16 kJohnPDoe(ASCIIToUTF16("4151113333"));
+  const string16 kJohnDoe(ASCIIToUTF16("4152112222"));
+  const string16 kJohnPDoe(ASCIIToUTF16("4153113333"));
   std::vector<string16> set_values;
   set_values.push_back(kJohnDoe);
   set_values.push_back(kJohnPDoe);
diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc
index 3135044..03eb64e 100644
--- a/chrome/browser/autofill/personal_data_manager.cc
+++ b/chrome/browser/autofill/personal_data_manager.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/autofill/autofill_metrics.h"
 #include "chrome/browser/autofill/form_structure.h"
 #include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
 #include "chrome/browser/autofill/select_control_handler.h"
 #include "chrome/browser/prefs/pref_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -225,6 +226,11 @@
   // Detect and discard forms with multiple fields of the same type.
   std::set<AutofillFieldType> types_seen;
 
+  // We only set complete phone, so aggregate phone parts in these vars and set
+  // complete at the end.
+  PhoneNumber::PhoneCombineHelper home(AutofillType::PHONE_HOME);
+  PhoneNumber::PhoneCombineHelper fax(AutofillType::PHONE_FAX);
+
   for (size_t i = 0; i < form.field_count(); ++i) {
     const AutofillField* field = form.field(i);
     string16 value = CollapseWhitespace(field->value, false);
@@ -262,51 +268,12 @@
       }
       ++importable_credit_card_fields;
     } else {
-      // In the case of a phone number, if the whole phone number was entered
-      // into a single field, then parse it and set the sub components.
-      if (AutofillType(field_type).subgroup() ==
-              AutofillType::PHONE_WHOLE_NUMBER) {
-        string16 number;
-        string16 city_code;
-        string16 country_code;
-        PhoneNumber::ParsePhoneNumber(value,
-                                      &number,
-                                      &city_code,
-                                      &country_code);
-        if (number.empty())
-          continue;
-
-        if (group == AutofillType::PHONE_HOME) {
-          imported_profile->SetInfo(PHONE_HOME_COUNTRY_CODE, country_code);
-          imported_profile->SetInfo(PHONE_HOME_CITY_CODE, city_code);
-          imported_profile->SetInfo(PHONE_HOME_NUMBER, number);
-        } else if (group == AutofillType::PHONE_FAX) {
-          imported_profile->SetInfo(PHONE_FAX_COUNTRY_CODE, country_code);
-          imported_profile->SetInfo(PHONE_FAX_CITY_CODE, city_code);
-          imported_profile->SetInfo(PHONE_FAX_NUMBER, number);
-        }
-
-        continue;
-      }
-
-      // Phone and fax numbers can be split across multiple fields, so we
-      // might have already stored the prefix, and now be at the suffix.
-      // If so, combine them to form the full number.
-      if (group == AutofillType::PHONE_HOME ||
-          group == AutofillType::PHONE_FAX) {
-        AutofillFieldType number_type = PHONE_HOME_NUMBER;
-        if (group == AutofillType::PHONE_FAX)
-          number_type = PHONE_FAX_NUMBER;
-
-        string16 stored_number = imported_profile->GetInfo(number_type);
-        if (stored_number.size() ==
-                static_cast<size_t>(PhoneNumber::kPrefixLength) &&
-            value.size() == static_cast<size_t>(PhoneNumber::kSuffixLength)) {
-          value = stored_number + value;
-        }
-      }
-
-      imported_profile->SetInfo(field_type, value);
+      // We need to store phone data in the variables, before building the whole
+      // number at the end. The rest of the fields are set "as is".
+      // If the fields are not the phone fields in question both home.SetInfo()
+      // and fax.SetInfo() are going to return false.
+      if (!home.SetInfo(field_type, value) && !fax.SetInfo(field_type, value))
+        imported_profile->SetInfo(field_type, value);
 
       // Reject profiles with invalid country information.
       if (field_type == ADDRESS_HOME_COUNTRY &&
@@ -317,6 +284,33 @@
     }
   }
 
+  // Build phone numbers if they are from parts.
+  if (imported_profile.get()) {
+    string16 constructed_number;
+    if (!home.empty()) {
+      if (!home.ParseNumber(imported_profile->CountryCode(),
+                            &constructed_number)) {
+        imported_profile.reset();
+      } else {
+        imported_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number);
+      }
+    }
+    if (!fax.empty()) {
+      if (!fax.ParseNumber(imported_profile->CountryCode(),
+                           &constructed_number)) {
+        imported_profile.reset();
+      } else {
+        imported_profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, constructed_number);
+      }
+    }
+  }
+  // Normalize phone numbers.
+  if (imported_profile.get()) {
+    // Reject profile if even one of the phones is invalid.
+    if (!imported_profile->NormalizePhones())
+      imported_profile.reset();
+  }
+
   // Reject the profile if minimum address and validation requirements are not
   // met.
   if (imported_profile.get() && !IsValidLearnableProfile(*imported_profile))
diff --git a/chrome/browser/autofill/personal_data_manager_mac.mm b/chrome/browser/autofill/personal_data_manager_mac.mm
index c1f9ebe2..5d02166 100644
--- a/chrome/browser/autofill/personal_data_manager_mac.mm
+++ b/chrome/browser/autofill/personal_data_manager_mac.mm
@@ -189,10 +189,6 @@
     ABPerson* me,
     NSString* addressLabelRaw,
     AutofillProfile* profile) {
-  string16 number;
-  string16 city_code;
-  string16 country_code;
-
   ABMultiValue* phoneNumbers = [me valueForProperty:kABPhoneProperty];
   for (NSUInteger k = 0, phoneCount = [phoneNumbers count];
        k < phoneCount; k++) {
@@ -202,40 +198,25 @@
         [phoneLabelRaw isEqualToString:kABPhoneHomeLabel]) {
       string16 homePhone = base::SysNSStringToUTF16(
           [phoneNumbers valueAtIndex:reverseK]);
-      PhoneNumber::ParsePhoneNumber(
-          homePhone, &number, &city_code, &country_code);
-      profile->SetInfo(PHONE_HOME_NUMBER, number);
-      profile->SetInfo(PHONE_HOME_CITY_CODE, city_code);
-      profile->SetInfo(PHONE_HOME_COUNTRY_CODE, country_code);
+      profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, homePhone);
     } else if ([addressLabelRaw isEqualToString:kABAddressHomeLabel] &&
                [phoneLabelRaw isEqualToString:kABPhoneHomeFAXLabel]) {
       string16 homeFax = base::SysNSStringToUTF16(
           [phoneNumbers valueAtIndex:reverseK]);
-      PhoneNumber::ParsePhoneNumber(homeFax,
-          &number, &city_code, &country_code);
-      profile->SetInfo(PHONE_FAX_NUMBER, number);
-      profile->SetInfo(PHONE_FAX_CITY_CODE, city_code);
-      profile->SetInfo(PHONE_FAX_COUNTRY_CODE, country_code);
+      profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, homeFax);
     } else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] &&
                [phoneLabelRaw isEqualToString:kABPhoneWorkLabel]) {
       string16 workPhone = base::SysNSStringToUTF16(
           [phoneNumbers valueAtIndex:reverseK]);
-      PhoneNumber::ParsePhoneNumber(workPhone,
-          &number, &city_code, &country_code);
-      profile->SetInfo(PHONE_HOME_NUMBER, number);
-      profile->SetInfo(PHONE_HOME_CITY_CODE, city_code);
-      profile->SetInfo(PHONE_HOME_COUNTRY_CODE, country_code);
+      profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, workPhone);
     } else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] &&
                [phoneLabelRaw isEqualToString:kABPhoneWorkFAXLabel]) {
       string16 workFax = base::SysNSStringToUTF16(
           [phoneNumbers valueAtIndex:reverseK]);
-      PhoneNumber::ParsePhoneNumber(workFax,
-          &number, &city_code, &country_code);
-      profile->SetInfo(PHONE_FAX_NUMBER, number);
-      profile->SetInfo(PHONE_FAX_CITY_CODE, city_code);
-      profile->SetInfo(PHONE_FAX_COUNTRY_CODE, country_code);
+      profile->SetInfo(PHONE_FAX_WHOLE_NUMBER, workFax);
     }
   }
+  profile->NormalizePhones();
 }
 
 }  // namespace
diff --git a/chrome/browser/autofill/personal_data_manager_unittest.cc b/chrome/browser/autofill/personal_data_manager_unittest.cc
index 2ddb0c7..5d1b57f 100644
--- a/chrome/browser/autofill/personal_data_manager_unittest.cc
+++ b/chrome/browser/autofill/personal_data_manager_unittest.cc
@@ -889,7 +889,7 @@
   form1.fields.push_back(field);
   // Phone gets updated.
   autofill_test::CreateTestFormField(
-      "Phone:", "phone", "4445556666", "text", &field);
+      "Phone:", "phone", "6505556666", "text", &field);
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
@@ -907,7 +907,7 @@
   AutofillProfile expected;
   autofill_test::SetProfileInfo(&expected, "George", NULL,
       "Washington", "[email protected]", NULL, "1600 Pennsylvania Avenue",
-      "Suite A", "San Francisco", "California", "94102", NULL, "4445556666",
+      "Suite A", "San Francisco", "California", "94102", NULL, "4085556666",
       NULL);
   const std::vector<AutofillProfile*>& results1 = personal_data_->profiles();
   ASSERT_EQ(1U, results1.size());
@@ -945,7 +945,7 @@
   form2.fields.push_back(field);
   // Phone gets updated.
   autofill_test::CreateTestFormField(
-      "Phone:", "phone", "1231231234", "text", &field);
+      "Phone:", "phone", "6502231234", "text", &field);
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
@@ -964,7 +964,7 @@
   // Add multi-valued phone number to expectation.  Also, country gets added.
   std::vector<string16> values;
   expected.GetMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
-  values.push_back(ASCIIToUTF16("1231231234"));
+  values.push_back(ASCIIToUTF16("6502231234"));
   expected.SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, values);
   expected.SetInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("United States"));
   ASSERT_EQ(1U, results2.size());
@@ -1632,7 +1632,7 @@
   autofill_test::SetProfileInfo(&profile0,
       "Marion", NULL, "Morrison",
       "[email protected]", NULL, "123 Zoo St.", NULL, "Hollywood", "CA",
-      "91601", "US", "2345678910", NULL);
+      "91601", "US", "14155678910", NULL);
 
   personal_data_->AddProfile(profile0);
 
@@ -1642,7 +1642,7 @@
   MessageLoop::current()->Run();
 
   personal_data_->GetNonEmptyTypes(&non_empty_types);
-  EXPECT_EQ(13U, non_empty_types.size());
+  EXPECT_EQ(14U, non_empty_types.size());
   EXPECT_TRUE(non_empty_types.count(NAME_FIRST));
   EXPECT_TRUE(non_empty_types.count(NAME_LAST));
   EXPECT_TRUE(non_empty_types.count(NAME_FULL));
@@ -1653,6 +1653,7 @@
   EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_ZIP));
   EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_COUNTRY));
   EXPECT_TRUE(non_empty_types.count(PHONE_HOME_NUMBER));
+  EXPECT_TRUE(non_empty_types.count(PHONE_HOME_COUNTRY_CODE));
   EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_CODE));
   EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_AND_NUMBER));
   EXPECT_TRUE(non_empty_types.count(PHONE_HOME_WHOLE_NUMBER));
@@ -1662,13 +1663,13 @@
   autofill_test::SetProfileInfo(&profile1,
       "Josephine", "Alicia", "Saenz",
       "[email protected]", "Fox", "903 Apple Ct.", NULL, "Orlando", "FL", "32801",
-      "US", "19482937549", "13502849239");
+      "US", "16502937549", "14082849239");
 
   AutofillProfile profile2;
   autofill_test::SetProfileInfo(&profile2,
       "Josephine", "Alicia", "Saenz",
       "[email protected]", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
-      "32801", "US", "19482937549", "13502849239");
+      "32801", "US", "16502937549", "14152849239");
 
   personal_data_->AddProfile(profile1);
   personal_data_->AddProfile(profile2);
diff --git a/chrome/browser/autofill/phone_field.cc b/chrome/browser/autofill/phone_field.cc
index c5045aa..d1ba987 100644
--- a/chrome/browser/autofill/phone_field.cc
+++ b/chrome/browser/autofill/phone_field.cc
@@ -330,9 +330,9 @@
   // Field types are different as well, so we create a temporary phone number,
   // to get relevant field types.
   if (phone_type == HOME_PHONE)
-    number_.reset(new HomePhoneNumber);
+    number_.reset(new PhoneNumber(AutofillType::PHONE_HOME));
   else
-    number_.reset(new FaxNumber);
+    number_.reset(new PhoneNumber(AutofillType::PHONE_FAX));
   phone_type_ = phone_type;
 }
 
diff --git a/chrome/browser/autofill/phone_number.cc b/chrome/browser/autofill/phone_number.cc
index d1ca32a..1eca43a 100644
--- a/chrome/browser/autofill/phone_number.cc
+++ b/chrome/browser/autofill/phone_number.cc
@@ -5,10 +5,13 @@
 #include "chrome/browser/autofill/phone_number.h"
 
 #include "base/basictypes.h"
+#include "base/string_number_conversions.h"
 #include "base/string_util.h"
+#include "base/utf_string_conversions.h"
 #include "chrome/browser/autofill/autofill_profile.h"
 #include "chrome/browser/autofill/autofill_type.h"
 #include "chrome/browser/autofill/field_types.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
 
 namespace {
 
@@ -32,7 +35,13 @@
 
 }  // namespace
 
-PhoneNumber::PhoneNumber() {}
+PhoneNumber::PhoneNumber()
+    : phone_group_(AutofillType::NO_GROUP) {
+}
+
+PhoneNumber::PhoneNumber(AutofillType::FieldTypeGroup phone_group)
+    : phone_group_(phone_group) {
+}
 
 PhoneNumber::PhoneNumber(const PhoneNumber& number) : FormGroup() {
   *this = number;
@@ -43,10 +52,8 @@
 PhoneNumber& PhoneNumber::operator=(const PhoneNumber& number) {
   if (this == &number)
     return *this;
-  country_code_ = number.country_code_;
-  city_code_ = number.city_code_;
   number_ = number.number_;
-  extension_ = number.extension_;
+  phone_group_ = number.phone_group_;
   return *this;
 }
 
@@ -54,194 +61,247 @@
                                    FieldTypeSet* matching_types) const {
   string16 stripped_text(text);
   StripPunctuation(&stripped_text);
-  if (!Validate(stripped_text))
+
+  string16 number;
+  string16 city_code;
+  string16 country_code;
+  // Full number - parse it, split it and re-combine into canonical form.
+  if (!autofill_i18n::ParsePhoneNumber(
+          number_, locale_, &country_code, &city_code, &number))
     return;
 
-  if (IsNumber(stripped_text))
+  if (IsNumber(stripped_text, number))
     matching_types->insert(GetNumberType());
 
-  if (IsCityCode(stripped_text))
+  if (stripped_text == city_code)
     matching_types->insert(GetCityCodeType());
 
-  if (IsCountryCode(stripped_text))
+  if (stripped_text == country_code)
     matching_types->insert(GetCountryCodeType());
 
-  if (IsCityAndNumber(stripped_text))
+  city_code.append(number);
+  if (stripped_text == city_code)
     matching_types->insert(GetCityAndNumberType());
 
-  if (IsWholeNumber(stripped_text))
+  // Whole number is compared to unfiltered text - it would be parsed for phone
+  // comparision (e.g. 1-800-FLOWERS and 18003569377 are the same)
+  if (IsWholeNumber(text))
     matching_types->insert(GetWholeNumberType());
 }
 
-void PhoneNumber::GetNonEmptyTypes(FieldTypeSet* non_empty_typess) const {
-  DCHECK(non_empty_typess);
+void PhoneNumber::GetNonEmptyTypes(FieldTypeSet* non_empty_types) const {
+  DCHECK(non_empty_types);
 
-  if (!number().empty())
-    non_empty_typess->insert(GetNumberType());
+  if (number_.empty())
+    return;
 
-  if (!city_code().empty())
-    non_empty_typess->insert(GetCityCodeType());
+  non_empty_types->insert(GetWholeNumberType());
 
-  if (!country_code().empty())
-    non_empty_typess->insert(GetCountryCodeType());
+  string16 number;
+  string16 city_code;
+  string16 country_code;
+  // Full number - parse it, split it and re-combine into canonical form.
+  if (!autofill_i18n::ParsePhoneNumber(
+          number_, locale_, &country_code, &city_code, &number))
+    return;
 
-  if (!CityAndNumber().empty())
-    non_empty_typess->insert(GetCityAndNumberType());
+  non_empty_types->insert(GetNumberType());
 
-  if (!WholeNumber().empty())
-    non_empty_typess->insert(GetWholeNumberType());
+  if (!city_code.empty()) {
+    non_empty_types->insert(GetCityCodeType());
+    non_empty_types->insert(GetCityAndNumberType());
+  }
+
+  if (!country_code.empty())
+    non_empty_types->insert(GetCountryCodeType());
 }
 
 string16 PhoneNumber::GetInfo(AutofillFieldType type) const {
+  if (type == GetWholeNumberType())
+    return number_;
+
+  string16 number;
+  string16 city_code;
+  string16 country_code;
+  // Full number - parse it, split it and re-combine into canonical form.
+  if (!autofill_i18n::ParsePhoneNumber(
+          number_, locale_, &country_code, &city_code, &number))
+    return string16();
+
   if (type == GetNumberType())
-    return number();
+    return number;
 
   if (type == GetCityCodeType())
-    return city_code();
+    return city_code;
 
   if (type == GetCountryCodeType())
-    return country_code();
+    return country_code;
 
+  city_code.append(number);
   if (type == GetCityAndNumberType())
-    return CityAndNumber();
-
-  if (type == GetWholeNumberType())
-    return WholeNumber();
+    return city_code;
 
   return string16();
 }
 
 void PhoneNumber::SetInfo(AutofillFieldType type, const string16& value) {
-  string16 number(value);
-  StripPunctuation(&number);
-  if (!Validate(number))
-    return;
-
   FieldTypeSubGroup subgroup = AutofillType(type).subgroup();
-  if (subgroup == AutofillType::PHONE_NUMBER)
-    set_number(number);
-  else if (subgroup == AutofillType::PHONE_CITY_CODE)
-    set_city_code(number);
-  else if (subgroup == AutofillType::PHONE_COUNTRY_CODE)
-    set_country_code(number);
-  else if (subgroup == AutofillType::PHONE_CITY_AND_NUMBER ||
-           subgroup == AutofillType::PHONE_WHOLE_NUMBER)
-    set_whole_number(number);
+  FieldTypeGroup group = AutofillType(type).group();
+  if (phone_group_ == AutofillType::NO_GROUP)
+    phone_group_ = group;  // First call on empty phone - set the group.
+  if (subgroup == AutofillType::PHONE_NUMBER) {
+    // Should not be set directly.
+    NOTREACHED();
+  } else if (subgroup == AutofillType::PHONE_CITY_CODE) {
+    // Should not be set directly.
+    NOTREACHED();
+  } else if (subgroup == AutofillType::PHONE_COUNTRY_CODE) {
+    // Should not be set directly.
+    NOTREACHED();
+  } else if (subgroup == AutofillType::PHONE_CITY_AND_NUMBER ||
+             subgroup == AutofillType::PHONE_WHOLE_NUMBER) {
+    number_ = value;
+    StripPunctuation(&number_);
+  } else {
+    NOTREACHED();
+  }
+}
+
+bool PhoneNumber::NormalizePhone() {
+  bool success = true;
+  // Empty number does not need normalization.
+  if (number_.empty())
+    return true;
+
+  string16 number;
+  string16 city_code;
+  string16 country_code;
+  // Full number - parse it, split it and re-combine into canonical form.
+  if (!autofill_i18n::ParsePhoneNumber(
+          number_, locale_, &country_code, &city_code, &number) ||
+      !autofill_i18n::ConstructPhoneNumber(
+          country_code, city_code, number,
+          locale_,
+          (country_code.empty() ?
+              autofill_i18n::NATIONAL : autofill_i18n::INTERNATIONAL),
+          &number_)) {
+    // Parsing failed -  do not store phone.
+    number_.clear();
+    success = false;
+  }
+  number_ = autofill_i18n::NormalizePhoneNumber(number_);
+  return success;
+}
+
+void PhoneNumber::set_locale(const std::string& locale) {
+  locale_ = locale;
+}
+
+AutofillFieldType PhoneNumber::GetNumberType() const {
+  if (phone_group_ == AutofillType::PHONE_HOME)
+    return PHONE_HOME_NUMBER;
+  else if (phone_group_ == AutofillType::PHONE_FAX)
+    return PHONE_FAX_NUMBER;
   else
     NOTREACHED();
+  return UNKNOWN_TYPE;
 }
 
-// Static.
-bool PhoneNumber::ParsePhoneNumber(const string16& value,
-                                   string16* number,
-                                   string16* city_code,
-                                   string16* country_code) {
-  DCHECK(number);
-  DCHECK(city_code);
-  DCHECK(country_code);
+AutofillFieldType PhoneNumber::GetCityCodeType() const {
+  if (phone_group_ == AutofillType::PHONE_HOME)
+    return PHONE_HOME_CITY_CODE;
+  else if (phone_group_ == AutofillType::PHONE_FAX)
+    return PHONE_FAX_CITY_CODE;
+  else
+    NOTREACHED();
+  return UNKNOWN_TYPE;
+}
 
-  // Make a working copy of value.
-  string16 working = value;
+AutofillFieldType PhoneNumber::GetCountryCodeType() const {
+  if (phone_group_ == AutofillType::PHONE_HOME)
+    return PHONE_HOME_COUNTRY_CODE;
+  else if (phone_group_ == AutofillType::PHONE_FAX)
+    return PHONE_FAX_COUNTRY_CODE;
+  else
+    NOTREACHED();
+  return UNKNOWN_TYPE;
+}
 
-  *number = string16();
-  *city_code = string16();
-  *country_code = string16();
+AutofillFieldType PhoneNumber::GetCityAndNumberType() const {
+  if (phone_group_ == AutofillType::PHONE_HOME)
+    return PHONE_HOME_CITY_AND_NUMBER;
+  else if (phone_group_ == AutofillType::PHONE_FAX)
+    return PHONE_FAX_CITY_AND_NUMBER;
+  else
+    NOTREACHED();
+  return UNKNOWN_TYPE;
+}
 
-  // First remove any punctuation.
-  StripPunctuation(&working);
+AutofillFieldType PhoneNumber::GetWholeNumberType() const {
+  if (phone_group_ == AutofillType::PHONE_HOME)
+    return PHONE_HOME_WHOLE_NUMBER;
+  else if (phone_group_ == AutofillType::PHONE_FAX)
+    return PHONE_FAX_WHOLE_NUMBER;
+  else
+    NOTREACHED();
+  return UNKNOWN_TYPE;
+}
 
-  if (working.size() < kPhoneNumberLength)
+bool PhoneNumber::PhoneCombineHelper::SetInfo(AutofillFieldType field_type,
+                                              const string16& value) {
+  PhoneNumber temp(phone_group_);
+
+  if (field_type == temp.GetCountryCodeType()) {
+    country_ = value;
+    return true;
+  } else if (field_type == temp.GetCityCodeType()) {
+    city_ = value;
+    return true;
+  } else if (field_type == temp.GetCityAndNumberType()) {
+    phone_ = value;
+    return true;
+  } else if (field_type == temp.GetNumberType()) {
+    phone_.append(value);
+    return true;
+  } else {
     return false;
-
-  // Treat the last 7 digits as the number.
-  *number = working.substr(working.size() - kPhoneNumberLength,
-                           kPhoneNumberLength);
-  working.resize(working.size() - kPhoneNumberLength);
-  if (working.size() < kPhoneCityCodeLength)
-    return true;
-
-  // Treat the next three digits as the city code.
-  *city_code = working.substr(working.size() - kPhoneCityCodeLength,
-                              kPhoneCityCodeLength);
-  working.resize(working.size() - kPhoneCityCodeLength);
-  if (working.empty())
-    return true;
-
-  // Treat any remaining digits as the country code.
-  *country_code = working;
-  return true;
+  }
 }
 
-string16 PhoneNumber::WholeNumber() const {
-  string16 whole_number;
-  if (!country_code_.empty())
-    whole_number.append(country_code_);
-
-  if (!city_code_.empty())
-    whole_number.append(city_code_);
-
-  if (!number_.empty())
-    whole_number.append(number_);
-
-  return whole_number;
+bool PhoneNumber::PhoneCombineHelper::ParseNumber(const std::string& locale,
+                                                  string16* value) {
+  DCHECK(value);
+  return autofill_i18n::ConstructPhoneNumber(
+      country_, city_, phone_,
+      locale,
+      (country_.empty() ?
+          autofill_i18n::NATIONAL : autofill_i18n::INTERNATIONAL),
+      value);
 }
 
-void PhoneNumber::set_number(const string16& number) {
-  string16 digits(number);
-  StripPunctuation(&digits);
-  number_ = digits;
-}
-
-void PhoneNumber::set_whole_number(const string16& whole_number) {
-  string16 number, city_code, country_code;
-  ParsePhoneNumber(whole_number, &number, &city_code, &country_code);
-  set_number(number);
-  set_city_code(city_code);
-  set_country_code(country_code);
-}
-
-bool PhoneNumber::IsNumber(const string16& text) const {
-  // TODO(isherman): This will need to be updated once we add support for
+bool PhoneNumber::IsNumber(const string16& text, const string16& number) const {
+  // TODO(georgey): This will need to be updated once we add support for
   // international phone numbers.
   const size_t kPrefixLength = 3;
   const size_t kSuffixLength = 4;
 
-  if (text == number_)
+  if (text == number)
     return true;
-  if (text.length() == kPrefixLength && StartsWith(number_, text, true))
+  if (text.length() == kPrefixLength && StartsWith(number, text, true))
     return true;
-  if (text.length() == kSuffixLength && EndsWith(number_, text, true))
+  if (text.length() == kSuffixLength && EndsWith(number, text, true))
     return true;
 
   return false;
 }
 
-bool PhoneNumber::IsCityCode(const string16& text) const {
-  return text == city_code_;
-}
-
-bool PhoneNumber::IsCountryCode(const string16& text) const {
-  return text == country_code_;
-}
-
-bool PhoneNumber::IsCityAndNumber(const string16& text) const {
-  return text == CityAndNumber();
-}
-
 bool PhoneNumber::IsWholeNumber(const string16& text) const {
-  return text == WholeNumber();
-}
-
-bool PhoneNumber::Validate(const string16& number) const {
-  for (size_t i = 0; i < number.length(); ++i) {
-    if (!IsAsciiDigit(number[i]))
-      return false;
-  }
-
-  return true;
+  return autofill_i18n::ComparePhones(text, number_, locale_) ==
+         autofill_i18n::PHONES_EQUAL;
 }
 
 // Static.
 void PhoneNumber::StripPunctuation(string16* number) {
   RemoveChars(*number, kPhoneNumberSeparators, number);
 }
+
diff --git a/chrome/browser/autofill/phone_number.h b/chrome/browser/autofill/phone_number.h
index 9cbb6b2..2790f9c2 100644
--- a/chrome/browser/autofill/phone_number.h
+++ b/chrome/browser/autofill/phone_number.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_AUTOFILL_PHONE_NUMBER_H_
 #pragma once
 
+#include <string>
 #include <vector>
 
 #include "base/gtest_prod_util.h"
@@ -17,7 +18,8 @@
 class PhoneNumber : public FormGroup {
  public:
   PhoneNumber();
-  explicit PhoneNumber(const PhoneNumber& number);
+  explicit PhoneNumber(AutofillType::FieldTypeGroup phone_group);
+  PhoneNumber(const PhoneNumber& number);
   virtual ~PhoneNumber();
 
   PhoneNumber& operator=(const PhoneNumber& number);
@@ -29,15 +31,9 @@
   virtual string16 GetInfo(AutofillFieldType type) const;
   virtual void SetInfo(AutofillFieldType type, const string16& value);
 
-  // Parses |value| to extract the components of a phone number.  |number|
-  // returns the trailing 7 digits, |city_code| returns the next 3 digits, and
-  // |country_code| returns any remaining digits.
-  // Separator characters are stripped before parsing the digits.
-  // Returns true if parsing was successful, false otherwise.
-  static bool ParsePhoneNumber(const string16& value,
-                               string16* number,
-                               string16* city_code,
-                               string16* country_code);
+  // Validates |number_| and translates it into digits-only format.
+  // Locale must be set.
+  bool NormalizePhone();
 
   // Size and offset of the prefix and suffix portions of phone numbers.
   static const int kPrefixOffset = 0;
@@ -45,53 +41,55 @@
   static const int kSuffixOffset = 3;
   static const int kSuffixLength = 4;
 
+  // Sets locale for normalizing phone numbers. Must be called if you get
+  // normalized number or use NormalizePhone() function;
+  // Setting it to "", actually sets it to default locale - "US".
+  void set_locale(const std::string& locale);
+
   // The following functions should return the field type for each part of the
   // phone number.  Currently, these are either fax or home phone number types.
-  virtual AutofillFieldType GetNumberType() const = 0;
-  virtual AutofillFieldType GetCityCodeType() const = 0;
-  virtual AutofillFieldType GetCountryCodeType() const = 0;
-  virtual AutofillFieldType GetCityAndNumberType() const = 0;
-  virtual AutofillFieldType GetWholeNumberType() const = 0;
+  AutofillFieldType GetNumberType() const;
+  AutofillFieldType GetCityCodeType() const;
+  AutofillFieldType GetCountryCodeType() const;
+  AutofillFieldType GetCityAndNumberType() const;
+  AutofillFieldType GetWholeNumberType() const;
+
+  // The class used to combine home phone or fax parts into a whole number.
+  class PhoneCombineHelper {
+   public:
+    explicit PhoneCombineHelper(AutofillType::FieldTypeGroup phone_group)
+        : phone_group_(phone_group) { }
+    // Sets PHONE_HOME/FAX_CITY_CODE, PHONE_HOME/FAX_COUNTRY_CODE,
+    // PHONE_HOME/FAX_CITY_AND_NUMBER, PHONE_HOME/FAX_NUMBER and returns true.
+    // For all other field types returs false.
+    bool SetInfo(AutofillFieldType type, const string16& value);
+    // Returns true if parsing was successful, false otherwise.
+    bool ParseNumber(const std::string& locale, string16* value);
+
+    bool empty() const { return phone_.empty(); }
+   private:
+    string16 country_;
+    string16 city_;
+    string16 phone_;
+    AutofillType::FieldTypeGroup phone_group_;
+  };
 
  private:
   FRIEND_TEST_ALL_PREFIXES(PhoneNumberTest, Matcher);
 
-  const string16& country_code() const { return country_code_; }
-  const string16& city_code() const { return city_code_; }
-  const string16& number() const { return number_; }
-  const string16& extension() const { return extension_; }
-  string16 CityAndNumber() const { return city_code_ + number_; }
-
-  // Returns the entire phone number as a string, without punctuation.
-  virtual string16 WholeNumber() const;
-
-  void set_country_code(const string16& country_code) {
-    country_code_ = country_code;
-  }
-  void set_city_code(const string16& city_code) { city_code_ = city_code; }
-  void set_number(const string16& number);
-  void set_extension(const string16& extension) { extension_ = extension; }
-  void set_whole_number(const string16& whole_number);
-
   // The numbers will be digits only (no punctuation), so any call to the IsX()
   // functions should first call StripPunctuation on the text.
-  bool IsNumber(const string16& text) const;
-  bool IsCityCode(const string16& text) const;
-  bool IsCountryCode(const string16& text) const;
-  bool IsCityAndNumber(const string16& text) const;
+  bool IsNumber(const string16& text, const string16& number) const;
   bool IsWholeNumber(const string16& text) const;
 
-  // Verifies that |number| is a valid phone number.
-  bool Validate(const string16& number) const;
-
-  // Removes any punctuation characters from |number|.
   static void StripPunctuation(string16* number);
 
+  // Phone group -  currently it is PHONE_HOME and PHONE_FAX.
+  AutofillType::FieldTypeGroup phone_group_;
+  // Locale for phone normalizing.
+  std::string locale_;
   // The pieces of the phone number.
-  string16 country_code_;
-  string16 city_code_;  // city or area code.
   string16 number_;
-  string16 extension_;
 };
 
 #endif  // CHROME_BROWSER_AUTOFILL_PHONE_NUMBER_H_
diff --git a/chrome/browser/autofill/phone_number_i18n.cc b/chrome/browser/autofill/phone_number_i18n.cc
index 2217fb9..73ee97c 100644
--- a/chrome/browser/autofill/phone_number_i18n.cc
+++ b/chrome/browser/autofill/phone_number_i18n.cc
@@ -9,6 +9,7 @@
 #include "base/stringprintf.h"
 #include "base/string_number_conversions.h"
 #include "base/utf_string_conversions.h"
+#include "chrome/browser/autofill/autofill_country.h"
 #include "third_party/libphonenumber/cpp/src/phonenumberutil.h"
 
 namespace {
@@ -16,8 +17,8 @@
 std::string SanitizeLocaleCode(const std::string& locale_code) {
   if (locale_code.length() == 2)
     return locale_code;
-  // Use USA for incomplete locales.
-  return std::string("US");
+  return AutofillCountry::CountryCodeForLocale(
+      AutofillCountry::ApplicationLocale());
 }
 
 i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat UtilsTypeToPhoneLibType(
@@ -162,6 +163,12 @@
   if (validation != i18n::phonenumbers::PhoneNumberUtil::IS_POSSIBLE)
     return false;
 
+  // This verifies that number has a valid area code (that in some cases could
+  // be empty) for parsed country code. Also verifies that this is a valid
+  // number (in US 1234567 is not valid, because numbers do not start with 1).
+  if (!phone_util->IsValidNumber(i18n_number))
+    return false;
+
   std::string formatted_number;
 
   phone_util->Format(i18n_number, UtilsTypeToPhoneLibType(phone_format),
diff --git a/chrome/browser/autofill/phone_number_i18n_unittest.cc b/chrome/browser/autofill/phone_number_i18n_unittest.cc
index 4134a824..22a349e 100644
--- a/chrome/browser/autofill/phone_number_i18n_unittest.cc
+++ b/chrome/browser/autofill/phone_number_i18n_unittest.cc
@@ -283,20 +283,29 @@
                                     &number));
   EXPECT_EQ(number, string16());
   // Italian number
-  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("39"),
-                                   ASCIIToUTF16(""),
-                                   ASCIIToUTF16("236618300"),
-                                   "US",
+  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16(""),
+                                   ASCIIToUTF16("347"),
+                                   ASCIIToUTF16("2345678"),
+                                   "IT",
                                    autofill_i18n::INTERNATIONAL,
                                    &number));
-  EXPECT_EQ(number, ASCIIToUTF16("+39 236618300"));
-  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("39"),
-                                   ASCIIToUTF16(""),
-                                   ASCIIToUTF16("236618300"),
-                                   "US",
+  EXPECT_EQ(number, ASCIIToUTF16("+39 347 234 5678"));
+  // German number.
+  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("49"),
+                                   ASCIIToUTF16("024"),
+                                   ASCIIToUTF16("2345678901"),
+                                   "DE",
                                    autofill_i18n::NATIONAL,
                                    &number));
-  EXPECT_EQ(number, ASCIIToUTF16("236618300"));
+  EXPECT_EQ(number, ASCIIToUTF16("02423/45678901"));
+
+  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("49"),
+                                   ASCIIToUTF16("024"),
+                                   ASCIIToUTF16("2345678901"),
+                                   "DE",
+                                   autofill_i18n::INTERNATIONAL,
+                                   &number));
+  EXPECT_EQ(number, ASCIIToUTF16("+49 2423/45678901"));
 }
 
 TEST(PhoneNumberI18NTest, FormatPhone) {
diff --git a/chrome/browser/autofill/phone_number_unittest.cc b/chrome/browser/autofill/phone_number_unittest.cc
index 8766398..65b5952 100644
--- a/chrome/browser/autofill/phone_number_unittest.cc
+++ b/chrome/browser/autofill/phone_number_unittest.cc
@@ -3,126 +3,160 @@
 // found in the LICENSE file.
 
 #include "base/utf_string_conversions.h"
-#include "chrome/browser/autofill/home_phone_number.h"
+#include "chrome/browser/autofill/field_types.h"
 #include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/phone_number_i18n.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-// Tests the phone number parser.
-TEST(PhoneNumberTest, Parser) {
-  string16 number;
-  string16 city_code;
-  string16 country_code;
+TEST(PhoneNumberTest, Matcher) {
+  // Set phone number so country_code == 1, city_code = 650, number = 2345678.
+  string16 phone(ASCIIToUTF16("1 [650] 234-5678"));
+  PhoneNumber phone_number(AutofillType::PHONE_HOME);
+  phone_number.SetInfo(PHONE_HOME_WHOLE_NUMBER, phone);
+  phone_number.set_locale(std::string("US"));
+  phone_number.NormalizePhone();
 
-  // Test for empty string.  Should give back empty strings.
-  string16 phone0;
-  PhoneNumber::ParsePhoneNumber(phone0, &number, &city_code, &country_code);
-  EXPECT_EQ(string16(), number);
-  EXPECT_EQ(string16(), city_code);
-  EXPECT_EQ(string16(), country_code);
+  FieldTypeSet matching_types;
+  phone_number.GetMatchingTypes(ASCIIToUTF16(""), &matching_types);
+  EXPECT_EQ(0U, matching_types.size());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("1"), &matching_types);
+  EXPECT_EQ(1U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_COUNTRY_CODE) !=
+              matching_types.end());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("16"), &matching_types);
+  EXPECT_EQ(0U, matching_types.size());
+  phone_number.GetMatchingTypes(ASCIIToUTF16("165"), &matching_types);
+  EXPECT_EQ(0U, matching_types.size());
+  phone_number.GetMatchingTypes(ASCIIToUTF16("1650"), &matching_types);
+  EXPECT_EQ(0U, matching_types.size());
+  phone_number.GetMatchingTypes(ASCIIToUTF16("16502"), &matching_types);
+  EXPECT_EQ(0U, matching_types.size());
+  phone_number.GetMatchingTypes(ASCIIToUTF16("165023"), &matching_types);
+  EXPECT_EQ(0U, matching_types.size());
+  phone_number.GetMatchingTypes(ASCIIToUTF16("1650234"), &matching_types);
+  EXPECT_EQ(0U, matching_types.size());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("16502345678"), &matching_types);
+  EXPECT_EQ(1U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_WHOLE_NUMBER) !=
+              matching_types.end());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("650"), &matching_types);
+  EXPECT_EQ(1U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_CITY_CODE) !=
+              matching_types.end());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("2345678"), &matching_types);
+  EXPECT_EQ(1U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_NUMBER) != matching_types.end());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("234"), &matching_types);
+  EXPECT_EQ(1U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_NUMBER) != matching_types.end());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("5678"), &matching_types);
+  EXPECT_EQ(1U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_NUMBER) != matching_types.end());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("2345"), &matching_types);
+  EXPECT_EQ(0U, matching_types.size());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("6502345678"), &matching_types);
+  EXPECT_EQ(2U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_CITY_AND_NUMBER) !=
+              matching_types.end());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_WHOLE_NUMBER) !=
+              matching_types.end());
+  matching_types.clear();
+  phone_number.GetMatchingTypes(ASCIIToUTF16("(650)2345678"), &matching_types);
+  EXPECT_EQ(2U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_CITY_AND_NUMBER) !=
+              matching_types.end());
+  EXPECT_TRUE(matching_types.find(PHONE_HOME_WHOLE_NUMBER) !=
+              matching_types.end());
 
-  // Test for string with less than 7 digits.  Should give back empty strings.
-  string16 phone1(ASCIIToUTF16("1234"));
-  PhoneNumber::ParsePhoneNumber(phone1, &number, &city_code, &country_code);
-  EXPECT_EQ(string16(), number);
-  EXPECT_EQ(string16(), city_code);
-  EXPECT_EQ(string16(), country_code);
+  string16 fax(ASCIIToUTF16("+1(650)650-5678"));
+  PhoneNumber fax_number;
+  fax_number.set_locale(std::string("US"));
+  fax_number.SetInfo(PHONE_FAX_WHOLE_NUMBER, fax);
 
-  // Test for string with exactly 7 digits.  Should give back only phone number.
-  string16 phone2(ASCIIToUTF16("1234567"));
-  PhoneNumber::ParsePhoneNumber(phone2, &number, &city_code, &country_code);
-  EXPECT_EQ(ASCIIToUTF16("1234567"), number);
-  EXPECT_EQ(string16(), city_code);
-  EXPECT_EQ(string16(), country_code);
+  matching_types.clear();
+  fax_number.GetMatchingTypes(ASCIIToUTF16("16506505678"), &matching_types);
+  EXPECT_EQ(1U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_FAX_WHOLE_NUMBER) !=
+              matching_types.end());
 
-  // Test for string with exactly 7 digits and separators.  Should give back
-  // only phone number.
-  string16 phone_separator2(ASCIIToUTF16("123-4567"));
-  PhoneNumber::ParsePhoneNumber(phone_separator2,
-      &number, &city_code, &country_code);
-  EXPECT_EQ(ASCIIToUTF16("1234567"), number);
-  EXPECT_EQ(string16(), city_code);
-  EXPECT_EQ(string16(), country_code);
-
-  // Test for string with greater than 7 digits but less than 10 digits.
-  // Should give back only phone number.
-  string16 phone3(ASCIIToUTF16("123456789"));
-  PhoneNumber::ParsePhoneNumber(phone3, &number, &city_code, &country_code);
-  EXPECT_EQ(ASCIIToUTF16("3456789"), number);
-  EXPECT_EQ(string16(), city_code);
-  EXPECT_EQ(string16(), country_code);
-
-  // Test for string with greater than 7 digits but less than 10 digits and
-  // separators.
-  // Should give back only phone number.
-  string16 phone_separator3(ASCIIToUTF16("12.345-6789"));
-  PhoneNumber::ParsePhoneNumber(phone3, &number, &city_code, &country_code);
-  EXPECT_EQ(ASCIIToUTF16("3456789"), number);
-  EXPECT_EQ(string16(), city_code);
-  EXPECT_EQ(string16(), country_code);
-
-  // Test for string with exactly 10 digits.
-  // Should give back phone number and city code.
-  string16 phone4(ASCIIToUTF16("1234567890"));
-  PhoneNumber::ParsePhoneNumber(phone4, &number, &city_code, &country_code);
-  EXPECT_EQ(ASCIIToUTF16("4567890"), number);
-  EXPECT_EQ(ASCIIToUTF16("123"), city_code);
-  EXPECT_EQ(string16(), country_code);
-
-  // Test for string with exactly 10 digits and separators.
-  // Should give back phone number and city code.
-  string16 phone_separator4(ASCIIToUTF16("(123) 456-7890"));
-  PhoneNumber::ParsePhoneNumber(phone_separator4,
-      &number, &city_code, &country_code);
-  EXPECT_EQ(ASCIIToUTF16("4567890"), number);
-  EXPECT_EQ(ASCIIToUTF16("123"), city_code);
-  EXPECT_EQ(string16(), country_code);
-
-  // Test for string with over 10 digits.
-  // Should give back phone number, city code, and country code.
-  string16 phone5(ASCIIToUTF16("011234567890"));
-  PhoneNumber::ParsePhoneNumber(phone5, &number, &city_code, &country_code);
-  EXPECT_EQ(ASCIIToUTF16("4567890"), number);
-  EXPECT_EQ(ASCIIToUTF16("123"), city_code);
-  EXPECT_EQ(ASCIIToUTF16("01"), country_code);
-
-  // Test for string with over 10 digits with separator characters.
-  // Should give back phone number, city code, and country code.
-  string16 phone6(ASCIIToUTF16("(01) 123-456.7890"));
-  PhoneNumber::ParsePhoneNumber(phone6, &number, &city_code, &country_code);
-  EXPECT_EQ(ASCIIToUTF16("4567890"), number);
-  EXPECT_EQ(ASCIIToUTF16("123"), city_code);
-  EXPECT_EQ(ASCIIToUTF16("01"), country_code);
+  matching_types.clear();
+  fax_number.GetMatchingTypes(ASCIIToUTF16("650"), &matching_types);
+  EXPECT_EQ(2U, matching_types.size());
+  EXPECT_TRUE(matching_types.find(PHONE_FAX_CITY_CODE) !=
+              matching_types.end());
+  EXPECT_TRUE(matching_types.find(PHONE_FAX_NUMBER) !=
+              matching_types.end());
 }
 
-TEST(PhoneNumberTest, Matcher) {
-  // Set phone number so country_code == 12, city_code = 123, number = 1234567.
-  string16 phone(ASCIIToUTF16("121231234567"));
-  HomePhoneNumber phone_number;
-  phone_number.set_whole_number(phone);
+TEST(PhoneNumberTest, PhoneCombineHelper) {
+  PhoneNumber::PhoneCombineHelper number1(AutofillType::PHONE_HOME);
+  EXPECT_FALSE(number1.SetInfo(ADDRESS_BILLING_CITY,
+                               ASCIIToUTF16("1")));
+  EXPECT_FALSE(number1.SetInfo(PHONE_FAX_COUNTRY_CODE,
+                               ASCIIToUTF16("1")));
+  EXPECT_TRUE(number1.SetInfo(PHONE_HOME_COUNTRY_CODE,
+                              ASCIIToUTF16("1")));
+  EXPECT_TRUE(number1.SetInfo(PHONE_HOME_CITY_CODE,
+                              ASCIIToUTF16("650")));
+  EXPECT_TRUE(number1.SetInfo(PHONE_HOME_NUMBER,
+                              ASCIIToUTF16("2345678")));
+  string16 parsed_phone;
+  EXPECT_TRUE(number1.ParseNumber("US", &parsed_phone));
+  // International format as it has a country code.
+  EXPECT_EQ(ASCIIToUTF16("+1 650-234-5678"), parsed_phone);
 
-  EXPECT_FALSE(phone_number.IsCountryCode(ASCIIToUTF16("")));
-  EXPECT_FALSE(phone_number.IsCountryCode(ASCIIToUTF16("1")));
-  EXPECT_TRUE(phone_number.IsCountryCode(ASCIIToUTF16("12")));
-  EXPECT_FALSE(phone_number.IsCountryCode(ASCIIToUTF16("123")));
+  PhoneNumber::PhoneCombineHelper number2(AutofillType::PHONE_FAX);
+  EXPECT_FALSE(number2.SetInfo(PHONE_HOME_COUNTRY_CODE,
+                               ASCIIToUTF16("1")));
+  EXPECT_TRUE(number2.SetInfo(PHONE_FAX_COUNTRY_CODE,
+                              ASCIIToUTF16("1")));
+  EXPECT_TRUE(number2.SetInfo(PHONE_FAX_CITY_CODE,
+                              ASCIIToUTF16("650")));
+  EXPECT_TRUE(number2.SetInfo(PHONE_FAX_NUMBER,
+                              ASCIIToUTF16("2345679")));
+  EXPECT_TRUE(number2.ParseNumber("US", &parsed_phone));
+  // International format as it has a country code.
+  EXPECT_EQ(ASCIIToUTF16("+1 650-234-5679"), parsed_phone);
 
-  EXPECT_FALSE(phone_number.IsCityCode(ASCIIToUTF16("")));
-  EXPECT_FALSE(phone_number.IsCityCode(ASCIIToUTF16("1")));
-  EXPECT_FALSE(phone_number.IsCityCode(ASCIIToUTF16("12")));
-  EXPECT_TRUE(phone_number.IsCityCode(ASCIIToUTF16("123")));
-  EXPECT_FALSE(phone_number.IsCityCode(ASCIIToUTF16("1234")));
+  PhoneNumber::PhoneCombineHelper number3(AutofillType::PHONE_HOME);
+  EXPECT_TRUE(number3.SetInfo(PHONE_HOME_CITY_CODE,
+                              ASCIIToUTF16("650")));
+  EXPECT_TRUE(number3.SetInfo(PHONE_HOME_NUMBER,
+                              ASCIIToUTF16("2345680")));
+  EXPECT_TRUE(number3.ParseNumber("US", &parsed_phone));
+  // National format as it does not have a country code.
+  EXPECT_EQ(ASCIIToUTF16("(650) 234-5680"), parsed_phone);
 
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("1")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("12")));
-  EXPECT_TRUE(phone_number.IsNumber(ASCIIToUTF16("123")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("1234")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("12345")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("123456")));
-  EXPECT_TRUE(phone_number.IsNumber(ASCIIToUTF16("1234567")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("234567")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("34567")));
-  EXPECT_TRUE(phone_number.IsNumber(ASCIIToUTF16("4567")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("567")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("67")));
-  EXPECT_FALSE(phone_number.IsNumber(ASCIIToUTF16("7")));
+  PhoneNumber::PhoneCombineHelper number4(AutofillType::PHONE_HOME);
+  EXPECT_TRUE(number4.SetInfo(PHONE_HOME_CITY_CODE,
+                              ASCIIToUTF16("123")));  // Incorrect city code.
+  EXPECT_TRUE(number4.SetInfo(PHONE_HOME_NUMBER,
+                              ASCIIToUTF16("2345680")));
+  EXPECT_FALSE(number4.ParseNumber("US", &parsed_phone));
+  EXPECT_EQ(string16(), parsed_phone);
+
+  PhoneNumber::PhoneCombineHelper number5(AutofillType::PHONE_HOME);
+  EXPECT_TRUE(number5.SetInfo(PHONE_HOME_CITY_AND_NUMBER,
+                              ASCIIToUTF16("6502345681")));
+  EXPECT_TRUE(number5.ParseNumber("US", &parsed_phone));
+  EXPECT_EQ(ASCIIToUTF16("(650) 234-5681"), parsed_phone);
+
+  PhoneNumber::PhoneCombineHelper number6(AutofillType::PHONE_HOME);
+  EXPECT_TRUE(number6.SetInfo(PHONE_HOME_CITY_CODE,
+                              ASCIIToUTF16("650")));
+  EXPECT_TRUE(number6.SetInfo(PHONE_HOME_NUMBER,
+                              ASCIIToUTF16("234")));
+  EXPECT_TRUE(number6.SetInfo(PHONE_HOME_NUMBER,
+                              ASCIIToUTF16("5682")));
+  EXPECT_TRUE(number6.ParseNumber("US", &parsed_phone));
+  EXPECT_EQ(ASCIIToUTF16("(650) 234-5682"), parsed_phone);
 }