Update external/libphonenumber from r9 to r15 with the latest functionality, bug-fixes and phone number plan updates.
Details of each revisions see: http://code.google.com/p/libphonenumber/updates/list

Change-Id: Id57d6e15c0a01f304b519ebacca3a415b329c3eb
diff --git a/README.android b/README.android
index 8939d6d..545c0d1 100644
--- a/README.android
+++ b/README.android
@@ -1,4 +1,4 @@
 URL: http://code.google.com/p/libphonenumber/
-Version: r9
+Version: r15
 License: Apache 2
 Description: Google Phone Number Library.
diff --git a/java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml b/java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml
index 0e72c87..d714e48 100644
--- a/java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml
+++ b/java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml
@@ -479,12 +479,16 @@
     <!-- http://en.wikipedia.org/wiki/Telephone_numbers_in_Australia -->
     <territory id="AU" countryCode="61" preferredInternationalPrefix="0011"
                internationalPrefix="(?:14(?:1[14]|34|4[17]|[56]6|7[47]|88))?001[14-689]"
-               nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
+               nationalPrefix="0">
       <availableFormats>
         <numberFormat leadingDigits="[2378]"
+                      nationalPrefixFormattingRule="($NP$FG)"
                       pattern="([2378])(\d{4})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="4" pattern="(4\d{2})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
+        <numberFormat leadingDigits="4"
+                      nationalPrefixFormattingRule="$NP$FG"
+                      pattern="(4\d{2})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
         <numberFormat leadingDigits="5"
+                      nationalPrefixFormattingRule="$NP$FG"
                       pattern="(5[05]0)(\d{3})(\d{3})">$1 $2 $3</numberFormat>
         <numberFormat leadingDigits="1(?:[38]00|9)" nationalPrefixFormattingRule="$FG"
                       pattern="(1[389]\d{2})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
@@ -542,10 +546,10 @@
     <!-- http://www.itu.int/oth/T020200000B/en -->
     <territory id="AW" countryCode="297" internationalPrefix="00">
       <availableFormats>
-        <numberFormat pattern="([57-9]\d{2})(\d{4})">$1 $2</numberFormat>
+        <numberFormat pattern="([5-9]\d{2})(\d{4})">$1 $2</numberFormat>
       </availableFormats>
       <generalDesc>
-        <nationalNumberPattern>[57-9]\d{6}</nationalNumberPattern>
+        <nationalNumberPattern>[5-9]\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{7}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
@@ -553,7 +557,10 @@
         <exampleNumber>5212345</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:5[69]\d|9(?:6\d|9[02-9])|7[34]\d)\d{4}</nationalNumberPattern>
+        <!-- Adding 660 since we can successfully deliver SMS messages to
+        numbers with this prefix, and numbers can be found in the yellow pages.
+        -->
+        <nationalNumberPattern>(?:5[69]\d|660|9(?:6\d|9[02-9])|7[34]\d)\d{4}</nationalNumberPattern>
         <exampleNumber>5601234</exampleNumber>
       </mobile>
       <tollFree>
@@ -702,7 +709,9 @@
         <exampleNumber>20491234</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>7(?:[0168]\d|2[0-4]|4[01]|5[01346-9])\d{5}</nationalNumberPattern>
+        <!-- Adding 75 for Zain, Burkina Faso. This is actually used in the
+        help-line number for them. -->
+        <nationalNumberPattern>7(?:[01568]\d|2[0-4]|4[01]|5[01346-9])\d{5}</nationalNumberPattern>
         <exampleNumber>70123456</exampleNumber>
       </mobile>
     </territory>
@@ -769,10 +778,10 @@
       <mobile>
         <!-- Extra online mobile number prefixes found: 79 10, 78 \d{2} and
         76 [29]\d. -->
-        <!-- The 2955 prefix is listed as a mobile prefix, but many people list
+        <!-- The 29 prefix is listed as a mobile prefix, but many people list
         it as their fixed home number. We will keep it as mobile for now, but it
         may actually be a prefix for fixed satellite phones. -->
-        <nationalNumberPattern>(?:2955|7(?:9(?:5[6-9]|[19]\d)|(?:6[269]|77|8\d)\d))\d{4}</nationalNumberPattern>
+        <nationalNumberPattern>(?:29\d|7(?:1[1-3]|[4-9]\d))\d{5}</nationalNumberPattern>
         <exampleNumber>79561234</exampleNumber>
       </mobile>
     </territory>
@@ -785,7 +794,7 @@
         <!-- Numbers beginning with 7 should be formatted as a block. -->
       </availableFormats>
       <generalDesc>
-        <nationalNumberPattern>[289]\d{7}|7\d{3}</nationalNumberPattern>
+        <nationalNumberPattern>[2689]\d{7}|7\d{3}</nationalNumberPattern>
         <possibleNumberPattern>\d{4,8}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
@@ -798,8 +807,11 @@
       </fixedLine>
       <mobile>
         <!-- 93 0, 93 4, 93 5 and 93 8 have been added as many online examples
-        of these prefixes can be found.  -->
-        <nationalNumberPattern>9(?:0[069]|[35][0-2457-9]|7[014-9])\d{5}</nationalNumberPattern>
+        of these prefixes can be found. 9[68] and 97[23] prefixes have also been
+        added because of online numbers following these patterns and numbers
+        where SMSs were successfully delivered.
+        66 has been also added, as it seems to be a prefix for Mobile MTN. -->
+        <nationalNumberPattern>66\d{6}|9(?:0[069]|[35][0-2457-9]|[6-8]\d)\d{5}</nationalNumberPattern>
         <possibleNumberPattern>\d{8}</possibleNumberPattern>
         <exampleNumber>90011234</exampleNumber>
       </mobile>
@@ -892,7 +904,7 @@
       <availableFormats>
         <numberFormat leadingDigits="[1-9][1-9]"
                       pattern="(\d{2})(\d{4})(\d{4})">($1) $2-$3</numberFormat>
-        <numberFormat leadingDigits="400" pattern="(400\d)(\d{4})">$1-$2</numberFormat>
+        <numberFormat leadingDigits="400|3003" pattern="([34]00\d)(\d{4})">$1-$2</numberFormat>
         <numberFormat leadingDigits="[3589]00" nationalPrefixFormattingRule="$NP$FG"
                       pattern="([3589]00)(\d{2,3})(\d{4})">$1 $2 $3</numberFormat>
       </availableFormats>
@@ -901,7 +913,7 @@
         <possibleNumberPattern>\d{8,10}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
-        <nationalNumberPattern>400\d{5}|(?:[14689][1-9]|2[12478]|3[1-578]|5[13-5]|7[13-579])[2-5]\d{7}</nationalNumberPattern>
+        <nationalNumberPattern>(?:[14689][1-9]|2[12478]|3[1-578]|5[13-5]|7[13-579])[2-5]\d{7}</nationalNumberPattern>
         <exampleNumber>1123456789</exampleNumber>
       </fixedLine>
       <mobile>
@@ -917,6 +929,10 @@
         <nationalNumberPattern>[359]00\d{6,7}</nationalNumberPattern>
         <exampleNumber>300123456</exampleNumber>
       </premiumRate>
+      <sharedCost>
+        <nationalNumberPattern>(?:400\d|3003)\d{4}</nationalNumberPattern>
+        <exampleNumber>40041234</exampleNumber>
+      </sharedCost>
     </territory>
 
     <!-- Bahamas -->
@@ -1048,7 +1064,29 @@
     </territory>
 
     <!-- Congo, Dem. Rep. of the (formerly Zaire) -->
-    <territory id="CD" countryCode="243" internationalPrefix="00">
+    <!-- http://www.itu.int/oth/T0202000037/en -->
+    <territory id="CD" countryCode="243" internationalPrefix="00"
+               nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
+      <availableFormats>
+        <numberFormat leadingDigits="[89]"
+                      pattern="([89]\d{2})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
+        <numberFormat leadingDigits="[1-6]"
+                      pattern="([1-6]\d)(\d{5})">$1 $2</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[89]\d{8}|[1-6]\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{7,9}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>[1-6]\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{7}</possibleNumberPattern>
+        <exampleNumber>1234567</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <nationalNumberPattern>(?:8[0149]|9[7-9])\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+        <exampleNumber>991234567</exampleNumber>
+      </mobile>
     </territory>
 
     <!-- Central African Republic -->
@@ -1158,7 +1196,8 @@
         <exampleNumber>21234567</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:0[1-9]|4[4-9]|50|6[067])\d{6}</nationalNumberPattern>
+        <!-- Added the prefix 40. Supported by numbers found on the internet. -->
+        <nationalNumberPattern>(?:0[1-9]|4[04-9]|50|6[067])\d{6}</nationalNumberPattern>
         <exampleNumber>01234567</exampleNumber>
       </mobile>
     </territory>
@@ -1357,7 +1396,10 @@
         <exampleNumber>2211234</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>9[189]\d{5}</nationalNumberPattern>
+        <!-- 95 and 97 have been introduced as new mobile codes because we
+        have successfully sent SMS messages to these numbers, and there are
+        plenty of numbers on the internet that start with these prefixes. -->
+        <nationalNumberPattern>9[157-9]\d{5}</nationalNumberPattern>
         <exampleNumber>9911234</exampleNumber>
       </mobile>
     </territory>
@@ -1532,7 +1574,7 @@
     </territory>
 
     <!-- Denmark -->
-    <!-- http://en.itst.dk/numbering-issues-and-domain-aspects/numbering-issues/numbering-lists -->
+    <!-- http://en.itst.dk/telecom-internet-regulation/numbering-issues/numbering-lists -->
     <territory id="DK" countryCode="45" internationalPrefix="00">
       <availableFormats>
         <numberFormat pattern="([1-9]\d)(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
@@ -1546,7 +1588,9 @@
         <exampleNumber>32123456</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:2[0-9]|3[01]|4[0-2]|5[0-3]|6[01])\d{6}</nationalNumberPattern>
+        <!-- There are some overlaps for some number prefixes - the plan says
+        that they are 'mainly' used for a certain type of number. -->
+        <nationalNumberPattern>(?:2[0-9]|3[0-2]|4[0-2]|5[0-3]|6[01]|72|99)\d{6}</nationalNumberPattern>
         <exampleNumber>20123456</exampleNumber>
       </mobile>
       <tollFree>
@@ -1616,8 +1660,56 @@
     </territory>
 
     <!-- Algeria -->
+    <!-- http://www.itu.int/oth/T0202000003/en -->
+    <!-- www.arpt.dz -->
     <territory id="DZ" countryCode="213" internationalPrefix="00"
-               nationalPrefix="7">
+               nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
+      <availableFormats>
+        <!-- Formatting from www.pagesjaunes-dz.com. -->
+        <numberFormat leadingDigits="[1-4]"
+          pattern="([1-4]\d)(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
+        <numberFormat leadingDigits="[5-8]"
+          pattern="([5-8]\d{2})(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
+        <numberFormat leadingDigits="9"
+          pattern="(9\d)(\d{3})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>(?:[1-4]|[5-9]\d)\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8,9}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <!-- We include the VSAT lines here. -->
+        <nationalNumberPattern>(?:1\d|2[014-79]|3[0-8]|4[0135689])\d{6}|9619\d{5}</nationalNumberPattern>
+        <exampleNumber>12345678</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <nationalNumberPattern>(?:5[56]|6[69]|7[79])\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+        <exampleNumber>551234567</exampleNumber>
+      </mobile>
+      <tollFree>
+        <nationalNumberPattern>800\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+        <exampleNumber>800123456</exampleNumber>
+      </tollFree>
+      <!-- The Algerian plan doesn't specify where the costs start to be
+      considered "premium", so we draw an arbitrary line here and say that from
+      50 Da up they will be considered premium. -->
+      <sharedCost>
+        <nationalNumberPattern>80[12]1\d{5}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+        <exampleNumber>801123456</exampleNumber>
+      </sharedCost>
+      <premiumRate>
+        <nationalNumberPattern>80[3-689]1\d{5}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+        <exampleNumber>808123456</exampleNumber>
+      </premiumRate>
+      <voip>
+        <nationalNumberPattern>98[23]\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+        <exampleNumber>983123456</exampleNumber>
+      </voip>
     </territory>
 
     <!-- Ecuador -->
@@ -2132,8 +2224,26 @@
     </territory>
 
     <!-- Guinea -->
-    <territory id="GN" countryCode="224" internationalPrefix="00"
-               nationalPrefix="0">
+    <!-- http://www.itu.int/oth/T020200005B/en -->
+    <territory id="GN" countryCode="224" internationalPrefix="00">
+      <availableFormats>
+        <numberFormat pattern="(\d{2})(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[367]\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>30(?:24|3[12]|4[1-35-7]|5[13]|6[189]|[78]1|9[1478])\d{4}</nationalNumberPattern>
+        <exampleNumber>30241234</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <!-- WiMAX is in the plan - which is a wireless broadband protocol. Not
+        including this in the metadata for now unless this proves to be
+        necessary. These would start with 79. -->
+        <nationalNumberPattern>6(?:0(?:2\d|3[3467]|5[2457-9])|[2457]\d{2}|3(?:[14]0|35))\d{4}</nationalNumberPattern>
+        <exampleNumber>60201234</exampleNumber>
+      </mobile>
     </territory>
 
     <!-- Guadeloupe -->
@@ -2298,6 +2408,10 @@
         <possibleNumberPattern>\d{11}</possibleNumberPattern>
         <exampleNumber>90012345678</exampleNumber>
       </premiumRate>
+      <personalNumber>
+        <nationalNumberPattern>8[1-3]\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8}</possibleNumberPattern>
+      </personalNumber>
     </territory>
 
     <!-- Honduras -->
@@ -2434,9 +2548,10 @@
       </generalDesc>
       <fixedLine>
         <!-- Area codes taken from wikipedia, with missing ones added from
-        http://www.telkom.co.id/customer-services/area-and-country-code/?type=area
-        -->
-        <nationalNumberPattern>2[124]\d{7,8}|(?:2(?:[35][1-4]|6[0-8]|7[1-6]|8\d|9[1-8])|3(?:1|2[1-578]|3[1-68]|4[1-3]|5[1-8]|6[1-3568]|7[0-46]|8\d)|4(?:0[1-589]|1[01347-9]|2[0-36-8]|3[0-24-68]|5[1-378]|6[1-5]|7[134]|8[1245])|5(?:1[1-35-9]|2[25-8]|3[1246-9]|4[1-3589]|5[1-46]|6[1-8])|6(?:19?|[25]\d|3[1-469]|4[1-6])|7(?:1[1-46-9]|2[14-9]|[36]\d|4[1-8]|5[1-9]|7[1-36-9])|9(?:0[12]|1[0134-8]|2[0-479]|5[125-8]|6[23679]|7[159]|8[01346]))\d{5,8}</nationalNumberPattern>
+        http://www.telkom.co.id/customer-services/area-and-country-code/?type=area.
+        We also added 0770 after user feedback because it seems to be used on
+        Bintan island.  -->
+        <nationalNumberPattern>2[124]\d{7,8}|(?:2(?:[35][1-4]|6[0-8]|7[1-6]|8\d|9[1-8])|3(?:1|2[1-578]|3[1-68]|4[1-3]|5[1-8]|6[1-3568]|7[0-46]|8\d)|4(?:0[1-589]|1[01347-9]|2[0-36-8]|3[0-24-68]|5[1-378]|6[1-5]|7[134]|8[1245])|5(?:1[1-35-9]|2[25-8]|3[1246-9]|4[1-3589]|5[1-46]|6[1-8])|6(?:19?|[25]\d|3[1-469]|4[1-6])|7(?:1[1-46-9]|2[14-9]|[36]\d|4[1-8]|5[1-9]|7[0-36-9])|9(?:0[12]|1[0134-8]|2[0-479]|5[125-8]|6[23679]|7[159]|8[01346]))\d{5,8}</nationalNumberPattern>
         <possibleNumberPattern>\d{5,10}</possibleNumberPattern>
         <exampleNumber>612345678</exampleNumber>
       </fixedLine>
@@ -2607,38 +2722,40 @@
     <territory id="IN" countryCode="91" internationalPrefix="00"
                nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
        <availableFormats>
-         <numberFormat leadingDigits="8(?:0[01589]|1[024]|80)|9"
-                       pattern="(\d{2})(\d{2})(\d{6})">$1 $2 $3</numberFormat>
-        <!-- 2 digits area code -->
-        <numberFormat leadingDigits="11|2[02]|33|4[04]|79|80[2-6]"
-                      pattern="(\d{2})(\d{4})(\d{4})">$1 $2 $3</numberFormat>
-        <!-- 3 digits area code -->
-        <numberFormat
-            leadingDigits="1(?:2[0-249]|3[0-25]|4[145]|5[14]|6[14]|7[1257]|8[1346]|9[14]|[68][1-9])"
-            pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])"
-                      pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])"
-                      pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat
-            leadingDigits="4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])"
-            pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="5(?:1[25]|22|3[25]|4[28]|5[12]|6[25]|[78]1|9[15])"
-                      pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="6(?:12|[2345]1|57|6[13]|7[14]|80)"
-                      pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)"
-                      pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)"
-                      pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <!-- 4 digits area code -->
-        <!-- Fallback for fixed-line numbers. -->
-        <numberFormat leadingDigits="1(?:[2-579]|[68][1-9])|[2-8]"
-                      pattern="(\d{4})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="1600" nationalPrefixFormattingRule="$FG"
-                      pattern="(1600)(\d{2})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="1800" nationalPrefixFormattingRule="$FG"
-                      pattern="(1800)(\d{2,3})(\d{4})">$1 $2 $3</numberFormat>
+         <!-- Mobile numbers. -->
+         <numberFormat
+             leadingDigits="7(?:39|5(?:50|[6-9])|[67][02-9]|8[0-6])|8(?:0[01589]|1[024]|8(?:[079]|44)|9[057-9])|9"
+             pattern="(\d{2})(\d{2})(\d{6})">$1 $2 $3</numberFormat>
+         <!-- 2 digits area code -->
+         <numberFormat leadingDigits="11|2[02]|33|4[04]|79|80[2-6]"
+                       pattern="(\d{2})(\d{4})(\d{4})">$1 $2 $3</numberFormat>
+         <!-- 3 digits area code -->
+         <numberFormat
+             leadingDigits="1(?:2[0-249]|3[0-25]|4[145]|5[14]|6[14]|7[1257]|8[1346]|9[14]|[68][1-9])"
+             pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
+         <numberFormat leadingDigits="2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])"
+                       pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
+         <numberFormat leadingDigits="3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])"
+                       pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
+         <numberFormat
+             leadingDigits="4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])"
+             pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
+         <numberFormat leadingDigits="5(?:1[25]|22|3[25]|4[28]|5[12]|6[25]|[78]1|9[15])"
+                       pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
+         <numberFormat leadingDigits="6(?:12|[2345]1|57|6[13]|7[14]|80)"
+                       pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
+         <numberFormat leadingDigits="7(?:12|2[14]|3[134]|4[47]|5(?:1|5[1-9])|[67]1|88)"
+                       pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
+         <numberFormat leadingDigits="8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)"
+                       pattern="(\d{3})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
+         <!-- 4 digits area code -->
+         <!-- Fallback for fixed-line numbers. -->
+         <numberFormat leadingDigits="1(?:[2-579]|[68][1-9])|[2-8]"
+                       pattern="(\d{4})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
+         <numberFormat leadingDigits="1600" nationalPrefixFormattingRule="$FG"
+                       pattern="(1600)(\d{2})(\d{4})">$1 $2 $3</numberFormat>
+         <numberFormat leadingDigits="1800" nationalPrefixFormattingRule="$FG"
+                       pattern="(1800)(\d{2,3})(\d{4})">$1 $2 $3</numberFormat>
       </availableFormats>
       <generalDesc>
         <nationalNumberPattern>[1-9]\d{9,10}</nationalNumberPattern>
@@ -2648,16 +2765,20 @@
         <!-- This is a list of the 2 and 3 digit area codes and the first 3
         digits of 4 digit area codes, so we can check the following digit
         belongs to one of the operator-codes (2-6). Operator codes from
-        wikipedia, with the addition of 5 (HFCL Infotel). -->
-        <nationalNumberPattern>(?:11|2[02]|33|4[04]|79|80)[2-6]\d{7}|(?:1(?:2[0-249]|3[0-25]|4[145]|5[14]|6[014]|7[1257]|8[01346]|9[14])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:1[25]|22|3[25]|4[28]|5[12]|6[25]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)|7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)|8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91))[2-6]\d{6}|(?:1(?:2[35-8]|3[346-9]|4[236-9]|5[0235-9]|6[235-9]|7[34689]|8[257-9]|9[0235-9])|2(?:1[134689]|3[24-8]|4[2-8]|5[25689]|6[2-4679]|7[13-79]|8[2-479]|9[235-9])|3(?:01|1[79]|2[1-5]|4[25-8]|5[125689]|6[235-7]|7[157-9]|8[2-467])|4(?:1[14578]|2[5689]|3[2-467]|5[4-7]|6[35]|73|8[2689]|9[2389])|5(?:1[146-9]|2[14-8]|3[1346]|4[14-69]|5[46]|6[146-9]|7[2-4]|8[2-8]|9[246])|6(?:1[1358]|2[2457]|3[2-4]|4[235-7]|5[2-689]|6[24-58]|7[23-689]|8[1-6])|7(?:1[013-9]|2[0235-9]|3[2679]|4[1-35689]|5[2-46-9]|[67][02-9]|8[0-8]|9\d)|8(?:1[1357-9]|2[235-8]|3[03-57-9]|4[0-24-9]|5\d|6[2457-9]|7[1-6]|8[1256]|9[2-4]))\d[2-6]\d{5}</nationalNumberPattern>
+        wikipedia, with the addition of 5 (HFCL Infotel). Area codes starting
+        with a 7 are listed separately, since the prefixes need to be more
+        detailed as they would otherwise clash with mobile phone prefixes. -->
+        <nationalNumberPattern>(?:11|2[02]|33|4[04]|79|80)[2-6]\d{7}|(?:1(?:2[0-249]|3[0-25]|4[145]|5[14]|6[014]|7[1257]|8[01346]|9[14])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:1[25]|22|3[25]|4[28]|5[12]|6[25]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)|7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)|8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91))[2-6]\d{6}|(?:(?:1(?:2[35-8]|3[346-9]|4[236-9]|5[0235-9]|6[235-9]|7[34689]|8[257-9]|9[0235-9])|2(?:1[134689]|3[24-8]|4[2-8]|5[25689]|6[2-4679]|7[13-79]|8[2-479]|9[235-9])|3(?:01|1[79]|2[1-5]|4[25-8]|5[125689]|6[235-7]|7[157-9]|8[2-467])|4(?:1[14578]|2[5689]|3[2-467]|5[4-7]|6[35]|73|8[2689]|9[2389])|5(?:1[146-9]|2[14-8]|3[1346]|4[14-69]|5[46]|6[146-9]|7[2-4]|8[2-8]|9[246])|6(?:1[1358]|2[2457]|3[2-4]|4[235-7]|5[2-689]|6[24-58]|7[23-689]|8[1-6])|8(?:1[1357-9]|2[235-8]|3[03-57-9]|4[0-24-9]|5\d|6[2457-9]|7[1-6]|8[1256]|9[2-4]))\d|7(?:(?:1[013-9]|2[0235-9]|3[2679]|4[1-35689]|5[2-46-9]|[67][02-9]|9\d)\d|8(?:2[0-6]|[013-8]\d)))[2-6]\d{5}</nationalNumberPattern>
         <possibleNumberPattern>\d{6,10}</possibleNumberPattern>
         <exampleNumber>1123456789</exampleNumber>
       </fixedLine>
       <!--http://en.wikipedia.org/wiki/Mobile_telephone_numbering_in_India -->
       <mobile>
-        <!-- According to PhoneFilters tests, digits 3-5 can't be either 000 or 099.
+        <!-- A couple of additional prefixes not found on the wikipedia
+        page, namely 7696 and 779[56] are added because we have
+        successfully sent SMS messages to these.
         -->
-        <nationalNumberPattern>(?:9\d(?:0(?:0[1-9]|9[0-8]|[1-8]\d)|[1-9]\d{2})|8(?:0[01589]|1[024]|80)\d{2})\d{5}</nationalNumberPattern>
+        <nationalNumberPattern>(?:7(?:39[89]|5(?:50|6[6-8]|79|[89][7-9])|6(?:0[027]|20|3[19]|54|65|7[67]|9[6-9])|7(?:0[89]|3[589]|42|60|9[5-9])|8(?:[03][07-9]|14|2[7-9]|4[25]|6[09]))\d|9\d{4}|8(?:0[01589]\d|1[024]\d|8(?:[079]\d|44)|9[057-9]\d)\d)\d{5}</nationalNumberPattern>
         <possibleNumberPattern>\d{10}</possibleNumberPattern>
         <exampleNumber>9123456789</exampleNumber>
       </mobile>
@@ -2822,7 +2943,8 @@
         <exampleNumber>8765123456</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>876(?:(?:21|3[02-9]|[48]\d|5[78]|77)\d|7(?:0[07]|8[1-47-9]|9[0-36-9])|9(?:[01]9|9[0579]))\d{4}</nationalNumberPattern>
+        <!-- Adding 31 as the prefix was found to be valid by online number lookup sites. -->
+        <nationalNumberPattern>876(?:(?:21|[348]\d|5[78]|77)\d|7(?:0[07]|8[1-47-9]|9[0-36-9])|9(?:[01]9|9[0579]))\d{4}</nationalNumberPattern>
         <possibleNumberPattern>\d{10}</possibleNumberPattern>
         <exampleNumber>8762101234</exampleNumber>
       </mobile>
@@ -2840,12 +2962,15 @@
 
     <!-- Jordan -->
     <!-- http://www.trc.gov.jo/images/stories/pdf/National_Numbering_Plan_ar.pdf (In Arabic) -->
+    <!-- http://www.itu.int/oth/T020200006E/en -->
+    <!-- http://en.wikipedia.org/wiki/%2B962 -->
     <territory id="JO" countryCode="962" internationalPrefix="00"
                nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
       <availableFormats>
         <numberFormat leadingDigits="[2356]"
-                      pattern="([2356])(\d{3})(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="7[4789]"
+                      pattern="([2356])(\d{3})(\d{4})"
+                      nationalPrefixFormattingRule="($NP$FG)">$1 $2 $3</numberFormat>
+        <numberFormat leadingDigits="7[47-9]"
                       pattern="(7)(\d{2})(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4 $5</numberFormat>
         <numberFormat leadingDigits="70" pattern="(70\d)(\d{6})">$1 $2</numberFormat>
         <numberFormat leadingDigits="[89]" pattern="([89]\d{2})(\d{5})">$1 $2</numberFormat>
@@ -2860,7 +2985,9 @@
         <exampleNumber>62345678</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>7(?:4[5-7]|7[569]|8[5-8]|9[05-7])\d{6}</nationalNumberPattern>
+        <!-- Adding 777, 79[89] prefixes as we could successfully deliver SMS messages to
+             these mobile numbers. -->
+        <nationalNumberPattern>7(?:4[5-7]|7[5-79]|8[5-8]|9[05-9])\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
         <exampleNumber>790123456</exampleNumber>
       </mobile>
@@ -2952,8 +3079,7 @@
     </territory>
 
     <!-- Kenya -->
-    <!-- http://www.cck.go.ke/numbering_plan/ -->
-    <!-- http://www.cck.go.ke/UserFiles/File/Premium_Rate_Services.pdf -->
+    <!-- http://www.cck.go.ke/licensing/numbering/plan.html -->
     <territory id="KE" countryCode="254" internationalPrefix="000"
                nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
       <availableFormats>
@@ -2969,10 +3095,11 @@
       <fixedLine>
         <nationalNumberPattern>(?:20|4[0-6]|5\d|6[0-24-9])\d{4,7}</nationalNumberPattern>
         <possibleNumberPattern>\d{4,9}</possibleNumberPattern>
-        <exampleNumber>201234</exampleNumber>
+        <exampleNumber>202012345</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>7(?:1[0-5]|2\d|3[2-8]|5[0-2]|7[023])\d{6}</nationalNumberPattern>
+        <!-- Adding 716 after successful delivery by sms. -->
+        <nationalNumberPattern>7(?:1[0-6]|2\d|3[2-8]|5[0-2]|7[023])\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
         <exampleNumber>712123456</exampleNumber>
       </mobile>
@@ -3009,7 +3136,9 @@
         <exampleNumber>312123456</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>5[124-7]\d{7}|7(?:00|7\d)\d{6}</nationalNumberPattern>
+        <!-- Added 705 since we have successfully sent SMS messages to
+        numbers with this prefix. -->
+        <nationalNumberPattern>5[124-7]\d{7}|7(?:0[05]|7\d)\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
         <exampleNumber>700123456</exampleNumber>
       </mobile>
@@ -3026,13 +3155,13 @@
     <territory id="KH" countryCode="855" internationalPrefix="00[178]"
                nationalPrefix="0">
       <availableFormats>
-        <numberFormat leadingDigits="1\d[2-9]|[2-79]" nationalPrefixFormattingRule="$NP$FG"
+        <numberFormat leadingDigits="1\d[1-9]|[2-9]" nationalPrefixFormattingRule="$NP$FG"
                       pattern="(\d{2})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
         <numberFormat leadingDigits="1[89]0"
                       pattern="(1[89]00)(\d{3})(\d{3})">$1 $2 $3</numberFormat>
       </availableFormats>
       <generalDesc>
-        <nationalNumberPattern>[1-79]\d{7,9}</nationalNumberPattern>
+        <nationalNumberPattern>[1-9]\d{7,9}</nationalNumberPattern>
         <possibleNumberPattern>\d{6,10}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
@@ -3041,7 +3170,9 @@
         <exampleNumber>23456789</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:1[0-25689]|9[1-49])[2-9]\d{5}</nationalNumberPattern>
+        <!-- Adding 171, 13X, 85[2-689] and 921 prefixes as we could successfully deliver SMS
+             messages to these mobile numbers. -->
+        <nationalNumberPattern>(?:(?:1[0-35-9]|9[1-49])[1-9]|85[2-689])\d{5}</nationalNumberPattern>
         <possibleNumberPattern>\d{8}</possibleNumberPattern>
         <exampleNumber>91234567</exampleNumber>
       </mobile>
@@ -3121,35 +3252,56 @@
     <!-- Korea (Rep. of) -->
     <!-- http://www.itu.int/oth/T0202000072/en -->
     <!-- http://en.wikipedia.org/wiki/%2B82 -->
-    <territory id="KR" countryCode="82" internationalPrefix="00(?:[12]|700)"
-               nationalPrefix="0" nationalPrefixForParsing="0(?:8[1-6])?"
+    <!-- http://www.kcc.go.kr/user.do?mode=view&page=P02030300&dc=K02030300&boardId=1074&boardSeq=2349 -->
+    <!-- http://www.kcc.go.kr/user.do?mode=view&page=P02030300&dc=K02030300&boardId=1074&boardSeq=2240 -->
+    <!-- http://www.telecentro.co.kr/sub/index.php?job=detail&ebcf_id=faq&page=1&mid=0503&eb_seq=36 -->
+    <!-- Exceptions :
+        internationalPrefix
+            0031, 0033, 0071, 0073 - Special services of KT and DACOM, ignorable
+        nationalPrefix
+            1[4-6]XX-YYYY - Country-wide common number services, display as it is without hyphens -->
+    <territory id="KR" countryCode="82" internationalPrefix="00(?:[124-68]|[37]\d{2})"
+               nationalPrefix="0" nationalPrefixForParsing="0(?:8[1-46-8]|85\d{2})?"
                nationalPrefixFormattingRule="$NP$FG">
       <availableFormats>
-        <numberFormat leadingDigits="1" pattern="(1\d)(\d{4})(\d{4})">$1-$2-$3</numberFormat>
-        <numberFormat leadingDigits="1" pattern="(1\d)(\d{3})(\d{3,4})">$1-$2-$3</numberFormat>
-        <numberFormat leadingDigits="21" pattern="(2)(1\d{2,3})">$1-$2</numberFormat>
-        <numberFormat leadingDigits="2[2-9]"
-                      pattern="(2)([2-9]\d{2,3})(\d{4})">$1-$2-$3</numberFormat>
-        <numberFormat leadingDigits="[3-7]"
-                      pattern="([3-7]\d)(\d{3,4})(\d{4})">$1-$2-$3</numberFormat>
-        <numberFormat leadingDigits="8" pattern="(80)(\d{3})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="1(?:0|1[19]|[69]9|5(?:44|59|8))|[57]0"
+                      pattern="(\d{2})(\d{4})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="1(?:[169][2-8]|[78]|5(?:[1-3]|4[56]))|[68]0|[3-9][1-9][2-9]"
+                      pattern="(\d{2})(\d{3})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="1312"
+                      pattern="(\d{3})(\d)(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="131[13-9]"
+                      pattern="(\d{3})(\d{2})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="13[2-9]"
+                      pattern="(\d{3})(\d{3})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="30"
+                      pattern="(\d{2})(\d{2})(\d{3})(\d{4})">$1-$2-$3-$4</numberFormat>
+        <numberFormat leadingDigits="2(?:[26]|3(?:01|1[45]|2[17-9]|39|4|6[67]|7[078]))"
+                      pattern="(\d)(\d{4})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="2(?:3(?:0[02-9]|1[0-36-9]|2[02-6]|3[0-8]|6[0-589]|7[1-69]|[589])|[457-9])"
+                      pattern="(\d)(\d{3})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="21(?:[0-247-9]|3[124]|6[1269])"
+                      pattern="(\d)(\d{3})">$1-$2</numberFormat>
+        <numberFormat leadingDigits="21(?:3[035-9]|6[03-578])"
+                      pattern="(\d)(\d{4})">$1-$2</numberFormat>
+        <numberFormat leadingDigits="[3-9][1-9]1(?:[0-247-9]|3[124]|6[1269])"
+                      pattern="(\d{2})(\d{3})">$1-$2</numberFormat>
+        <numberFormat leadingDigits="[3-9][1-9]1(?:3[035-9]|6[03-578])"
+                      pattern="(\d{2})(\d{4})">$1-$2</numberFormat>
       </availableFormats>
       <generalDesc>
         <nationalNumberPattern>[1-79]\d{3,9}|8\d{8}</nationalNumberPattern>
         <possibleNumberPattern>\d{4,10}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
-        <!-- Despite the complex ITU document, I can find no evidence to suggest
-        that numbers starting with two-digit area codes are anything other than
-        7 or 8 digits long.-->
-        <nationalNumberPattern>2(?:1\d{2,3}|[2367]\d{6,7}|[4589]\d{6})|(?:[34][1-3]|5[13-5]|6[124])\d{7}|(?:52|63)\d{7,8}</nationalNumberPattern>
+        <nationalNumberPattern>(?:2|[34][1-3]|5[1-5]|6[1-4])(?:1\d{2,3}|[2-9]\d{6,7})</nationalNumberPattern>
         <possibleNumberPattern>\d{4,10}</possibleNumberPattern>
         <exampleNumber>22123456</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>1[0-26-9]\d{5,7}</nationalNumberPattern>
-        <possibleNumberPattern>\d{7,9}</possibleNumberPattern>
-        <exampleNumber>12345678</exampleNumber>
+        <nationalNumberPattern>1[0-25-9]\d{7,8}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9,10}</possibleNumberPattern>
+        <exampleNumber>1023456789</exampleNumber>
       </mobile>
       <tollFree>
         <nationalNumberPattern>80\d{7}</nationalNumberPattern>
@@ -3157,19 +3309,19 @@
         <exampleNumber>801234567</exampleNumber>
       </tollFree>
       <premiumRate>
-        <nationalNumberPattern>60\d{7,8}</nationalNumberPattern>
-        <possibleNumberPattern>\d{9,10}</possibleNumberPattern>
-        <exampleNumber>601234567</exampleNumber>
+        <nationalNumberPattern>60[2-9]\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+        <exampleNumber>602345678</exampleNumber>
       </premiumRate>
       <personalNumber>
-        <nationalNumberPattern>50\d{7,8}</nationalNumberPattern>
-        <possibleNumberPattern>\d{9,10}</possibleNumberPattern>
-        <exampleNumber>501234567</exampleNumber>
+        <nationalNumberPattern>50\d{8}</nationalNumberPattern>
+        <possibleNumberPattern>\d{10}</possibleNumberPattern>
+        <exampleNumber>5012345678</exampleNumber>
       </personalNumber>
       <voip>
-        <nationalNumberPattern>70\d{7,8}</nationalNumberPattern>
-        <possibleNumberPattern>\d{9,10}</possibleNumberPattern>
-        <exampleNumber>701234567</exampleNumber>
+        <nationalNumberPattern>70\d{8}</nationalNumberPattern>
+        <possibleNumberPattern>\d{10}</possibleNumberPattern>
+        <exampleNumber>7012345678</exampleNumber>
       </voip>
     </territory>
 
@@ -3268,7 +3420,7 @@
                nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
       <availableFormats>
         <numberFormat leadingDigits="20"
-                      pattern="(20)([2579])(\d{3})(\d{3})">$1 $2 $3 $4</numberFormat>
+                      pattern="(20)([2357-9])(\d{3})(\d{3})">$1 $2 $3 $4</numberFormat>
         <numberFormat leadingDigits="21|[3-57]"
                       pattern="([2-57]\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat>
       </availableFormats>
@@ -3282,7 +3434,9 @@
         <exampleNumber>21212862</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>20[2579]\d{6}</nationalNumberPattern>
+        <!-- Adding 20[38] prefix as we could successfully deliver SMS messages to these mobile
+             numbers. -->
+        <nationalNumberPattern>20[2357-9]\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
         <exampleNumber>202345678</exampleNumber>
       </mobile>
@@ -3290,8 +3444,44 @@
     </territory>
 
     <!-- Lebanon -->
+    <!-- http://www.itu.int/oth/T0202000077/en -->
+    <!-- http://en.wikipedia.org/wiki/%2B961 -->
     <territory id="LB" countryCode="961" internationalPrefix="00"
-               nationalPrefix="0">
+               nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
+      <availableFormats>
+        <numberFormat leadingDigits="[13-6]"
+                      pattern="([13-6])(\d{3})(\d{3})">$1 $2 $3</numberFormat>
+        <numberFormat leadingDigits="[7-9][01]"
+                      pattern="([7-9][01])(\d{3})(\d{3})">$1 $2 $3</numberFormat>
+        <numberFormat leadingDigits="[7-9][2-9]"
+                      pattern="([7-9][2-9])(\d{2})(\d{3})">$1 $2 $3</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[13-9]\d{6,7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{7,8}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>(?:[14-6]\d|[7-9][2-9])\d{5}</nationalNumberPattern>
+        <possibleNumberPattern>\d{7}</possibleNumberPattern>
+        <exampleNumber>1123456</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <!-- Adding 71[67] prefixes as we could successfully deliver SMS messages to these
+             mobile numbers. -->
+        <nationalNumberPattern>(3\d|7(?:0\d|1[167]))\d{5}</nationalNumberPattern>
+        <possibleNumberPattern>\d{7,8}</possibleNumberPattern>
+        <exampleNumber>71123456</exampleNumber>
+      </mobile>
+      <premiumRate>
+        <nationalNumberPattern>8[01]\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8}</possibleNumberPattern>
+        <exampleNumber>80123456</exampleNumber>
+      </premiumRate>
+      <sharedCost>
+        <nationalNumberPattern>9[01]\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8}</possibleNumberPattern>
+        <exampleNumber>90123456</exampleNumber>
+      </sharedCost>
     </territory>
 
     <!-- Saint Lucia -->
@@ -3307,7 +3497,9 @@
         <exampleNumber>7582345678</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>758(?:28[4-7]|384|4(?:6[01]|8[4-9])|5(?:1[89]|20|84)|7(?:1[2-9]|2[034]))\d{4}</nationalNumberPattern>
+        <!-- Adding 721 and 722 as these prefixes are found widely on the
+        internet and we successfully delivered SMSs to these numbers. -->
+        <nationalNumberPattern>758(?:28[4-7]|384|4(?:6[01]|8[4-9])|5(?:1[89]|20|84)|7(?:1[2-9]|2[0-4]))\d{4}</nationalNumberPattern>
         <possibleNumberPattern>\d{10}</possibleNumberPattern>
         <exampleNumber>7582845678</exampleNumber>
       </mobile>
@@ -3407,14 +3599,34 @@
     </territory>
 
     <!-- Lesotho -->
-    <territory id="LS" countryCode="266" internationalPrefix="00"
-               nationalPrefix="0">
+    <!-- http://www.itu.int/oth/T0202000078/en -->
+    <territory id="LS" countryCode="266" internationalPrefix="00">
+      <availableFormats>
+        <!-- Formatting following yellow pages: www.yellowpages.co.ls-->
+        <numberFormat pattern="(\d{4})(\d{4})">$1 $2</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[2568]\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>2\d{7}</nationalNumberPattern>
+        <exampleNumber>22123456</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <nationalNumberPattern>[56]\d{7}</nationalNumberPattern>
+        <exampleNumber>50123456</exampleNumber>
+      </mobile>
+      <tollFree>
+        <nationalNumberPattern>800[256]\d{4}</nationalNumberPattern>
+        <exampleNumber>80021234</exampleNumber>
+      </tollFree>
     </territory>
 
     <!-- Lithuania -->
     <!-- http://www.itu.int/oth/T020200007C/en -->
     <territory id="LT" countryCode="370" internationalPrefix="00"
-               nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
+               nationalPrefix="8" nationalPrefixFormattingRule="$NP $FG">
       <availableFormats>
         <!-- Two-digit area codes -->
         <numberFormat leadingDigits="37|4(?:1|5[45]|6[2-4])"
@@ -3513,7 +3725,9 @@
         <exampleNumber>22212345</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:6(?:50|7[12]|8[0-7]|9\d)|7(?:80|9\d))\d{5}</nationalNumberPattern>
+        <!-- Added 688 and 689 since we have been successfully sending SMSs
+        to these numbers. -->
+        <nationalNumberPattern>(?:6(?:50|7[12]|[89]\d)|7(?:80|9\d))\d{5}</nationalNumberPattern>
         <exampleNumber>65012345</exampleNumber>
       </mobile>
       <tollFree>
@@ -3619,11 +3833,11 @@
       <fixedLine>
         <!-- 20 70 seems a common pattern, in addition to 20 79. 21 25 seems
         also to exist. -->
-        <nationalNumberPattern>(?:2(?:0(?:2[0-589]|7[027-9])|1(?:2[5-7]|[3-9]\d))|442\d)\d{4}</nationalNumberPattern>
+        <nationalNumberPattern>(?:2(?:0(?:2[0-589]|7[027-9])|1(?:2[5-7]|[3-689]\d))|442\d)\d{4}</nationalNumberPattern>
         <exampleNumber>20212345</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:6(?:[569]\d)|7(?:[359][0-4]|4[014-7]|6\d|8[1-9]))\d{5}</nationalNumberPattern>
+        <nationalNumberPattern>(?:6(?:[569]\d)|7(?:[3579][0-4]|4[014-7]|6\d|8[1-9]))\d{5}</nationalNumberPattern>
         <exampleNumber>65012345</exampleNumber>
       </mobile>
       <tollFree>
@@ -3715,7 +3929,9 @@
         <exampleNumber>28212345</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>66\d{6}</nationalNumberPattern>
+        <!-- The 62 prefix is added as we successfully delivered SMS messages to these
+             numbers, and they are also widely present on the Internet. -->
+        <nationalNumberPattern>6[26]\d{6}</nationalNumberPattern>
         <exampleNumber>66123456</exampleNumber>
       </mobile>
       <!-- No tollFree or premiumRate information can be found.-->
@@ -3818,10 +4034,10 @@
       happen August 2010, and 7 digit numbers will be phased out by 1 November
       2010. -->
       <availableFormats>
-        <numberFormat pattern="([2-8]\d{2})(\d{4})">$1 $2</numberFormat>
+        <numberFormat pattern="([2-9]\d{2})(\d{4})">$1 $2</numberFormat>
       </availableFormats>
       <generalDesc>
-        <nationalNumberPattern>[2-8]\d{6}</nationalNumberPattern>
+        <nationalNumberPattern>[2-9]\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{7}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
@@ -3831,7 +4047,8 @@
         <exampleNumber>2012345</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:25\d|4(?:2[12389]|9\d)|7\d{2}|87[15-7]|9[13-8]\d)\d{4}</nationalNumberPattern>
+        <!--Adding 92 as we successfully sent SMSs to this prefix. -->
+        <nationalNumberPattern>(?:25\d|4(?:2[12389]|9\d)|7\d{2}|87[15-7]|9[1-8]\d)\d{4}</nationalNumberPattern>
         <exampleNumber>2512345</exampleNumber>
       </mobile>
       <tollFree>
@@ -4046,6 +4263,7 @@
     </territory>
 
     <!-- Namibia -->
+    <!-- http://www.itu.int/oth/T0202000093/en -->
     <territory id="NA" countryCode="264" internationalPrefix="00"
                nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
       <availableFormats>
@@ -4075,7 +4293,9 @@
         <exampleNumber>612012345</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>8(?:1(?:1[0-2]|[23]\d|50)|5\d{2})\d{5}</nationalNumberPattern>
+        <!-- The prefixes 8114, 814\d, 816[0-2] have been added after we
+        have successfully delivered SMS messages to these numbers. -->
+        <nationalNumberPattern>8(?:1(?:1[0-24]|[2-4]\d|50|6[0-2])|5\d{2})\d{5}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
         <exampleNumber>811012345</exampleNumber>
       </mobile>
@@ -4092,8 +4312,38 @@
     </territory>
 
     <!-- Niger -->
-    <territory id="NE" countryCode="227" internationalPrefix="00"
-               nationalPrefix="0">
+    <!-- http://www.itu.int/oth/T020200009B/en -->
+    <territory id="NE" countryCode="227" internationalPrefix="00">
+      <availableFormats>
+        <numberFormat>
+          <numberFormat leadingDigits="[29]|09"
+                        pattern="([029]\d)(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
+          <numberFormat leadingDigits="08"
+                        pattern="(08)(\d{3})(\d{3})">$1 $2 $3</numberFormat>
+        </numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[029]\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <!-- Adding 20 61 from online numbers. -->
+        <nationalNumberPattern>2(?:0(?:20|3[1-7]|4[134]|5[14]|6[14578]|7[1-578])|1(?:4[145]|5[14]|6[14-68]|7[169]|88))\d{4}</nationalNumberPattern>
+        <exampleNumber>20201234</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <!-- Added 90 and 97 from online data. -->
+        <nationalNumberPattern>9[03467]\d{6}</nationalNumberPattern>
+        <exampleNumber>93123456</exampleNumber>
+      </mobile>
+      <tollFree>
+        <nationalNumberPattern>08\d{6}</nationalNumberPattern>
+        <exampleNumber>08123456</exampleNumber>
+      </tollFree>
+      <premiumRate>
+        <nationalNumberPattern>09\d{6}</nationalNumberPattern>
+        <exampleNumber>09123456</exampleNumber>
+      </premiumRate>
     </territory>
 
     <!-- Norfolk Island -->
@@ -4101,7 +4351,7 @@
     </territory>
 
     <!-- Nigeria -->
-    <!-- http://www.itu.int/dms_pub/itu-t/oth/02/02/T020200009C0001MSWE.doc -->
+    <!-- http://www.itu.int/oth/T020200009C/en -->
     <territory id="NG" countryCode="234" internationalPrefix="009"
                nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
       <availableFormats>
@@ -4111,7 +4361,7 @@
           pattern="(9)(\d{3})(\d{4})">$1 $2 $3</numberFormat>
         <numberFormat leadingDigits="[3-6]|7(?:[1-79]|0[1-9])|8[2-9]"
           pattern="([3-8]\d)(\d{3})(\d{2,3})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="70[3-9]|8(?:0[1-9]|12)"
+        <numberFormat leadingDigits="70[3-9]|8(?:0[1-9]|1[23])"
           pattern="([78]\d{2})(\d{3})(\d{4})">$1 $2 $3</numberFormat>
         <numberFormat leadingDigits="702|819"
           pattern="([78]\d{3})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
@@ -4134,7 +4384,8 @@
         <exampleNumber>12345678</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:70[3-9]|8(?:0[2-9]|12))\d{7}|(?:702[1-9]|819[01])\d{6}</nationalNumberPattern>
+        <!-- 813 added because online businesses were also found with this prefix. -->
+        <nationalNumberPattern>(?:70[3-9]|8(?:0[2-9]|1[23]))\d{7}|(?:702[1-9]|819[01])\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{10}</possibleNumberPattern>
         <exampleNumber>8021234567</exampleNumber>
       </mobile>
@@ -4353,7 +4604,7 @@
         <numberFormat leadingDigits="5" pattern="(500)(\d{4})">$1 $2</numberFormat>
       </availableFormats>
       <generalDesc>
-        <nationalNumberPattern>(?:2[3-6]|5|9[25-9])\d{6}|800\d{5,6}</nationalNumberPattern>
+        <nationalNumberPattern>(?:2[3-6]|5|9[235-9])\d{6}|800\d{5,6}</nationalNumberPattern>
         <possibleNumberPattern>\d{7,9}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
@@ -4362,7 +4613,9 @@
         <exampleNumber>23123456</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>9[25-9]\d{6}</nationalNumberPattern>
+        <!-- Adding 93 as it seems numbers starting from 930 have started to be
+        issued. We successfully delivered numbers to this range. -->
+        <nationalNumberPattern>9[235-9]\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{8}</possibleNumberPattern>
         <exampleNumber>92123456</exampleNumber>
       </mobile>
@@ -4471,7 +4724,7 @@
         <exampleNumber>21234567</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>9(?:0[5-9]|1[025-9]|2[0-36-9]|3[235-8]|7[349])\d{7}</nationalNumberPattern>
+        <nationalNumberPattern>9(?:0[5-9]|1[025-9]|2[0-36-9]|3[0235-9]|7[349]|[89]9)\d{7}</nationalNumberPattern>
         <possibleNumberPattern>\d{10}</possibleNumberPattern>
         <exampleNumber>9051234567</exampleNumber>
       </mobile>
@@ -4529,14 +4782,12 @@
     <!--
     http://www.uke.gov.pl/uke/index.jsp?place=Lead24&news_cat_id=277&news_id=3791&layout=9&page=text
     (in Polish) -->
-    <territory id="PL" countryCode="48" internationalPrefix="0~0"
-               nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
+    <territory id="PL" countryCode="48" internationalPrefix="00">
       <availableFormats>
-        <numberFormat leadingDigits="[124-7]|3[2-4]|8[1-9]"
+        <numberFormat leadingDigits="[124]|3[2-4]|5[24-689]|6[1-3578]|7[014-7]|8[1-79]|9[145]"
           pattern="(\d{2})(\d{3})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
-        <numberFormat leadingDigits="80"
-          pattern="(80[01])(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
-        <numberFormat leadingDigits="39" pattern="(39\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat>
+        <numberFormat leadingDigits="39|5[013]|6[069]|7[289]|8[08]"
+                      pattern="(\d{3})(\d{3})(\d{3})">$1 $2 $3</numberFormat>
       </availableFormats>
       <generalDesc>
         <nationalNumberPattern>[1-9]\d{8}</nationalNumberPattern>
@@ -4547,7 +4798,7 @@
         <exampleNumber>123456789</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:5[01]|6[069]|7[289]|88)\d{7}</nationalNumberPattern>
+        <nationalNumberPattern>(?:5[013]|6[069]|7[289]|88)\d{7}</nationalNumberPattern>
         <exampleNumber>512345678</exampleNumber>
       </mobile>
       <tollFree>
@@ -4663,7 +4914,7 @@
         <exampleNumber>4123456</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:3[0-5]|[5-7]\d)\d{5}</nationalNumberPattern>
+        <nationalNumberPattern>[35-7]\d{6}</nationalNumberPattern>
         <exampleNumber>3123456</exampleNumber>
       </mobile>
       <tollFree>
@@ -4787,8 +5038,8 @@
     <!-- Russian Federation -->
     <!-- http://www.itu.int/oth/T02020000AD/en -->
     <!-- http://en.wikipedia.org/wiki/%2B7 -->
-    <territory id="RU" countryCode="7" internationalPrefix="00"
-               nationalPrefix="0" nationalPrefixFormattingRule="$NP ($FG)">
+    <territory id="RU" countryCode="7" internationalPrefix="8~10"
+               nationalPrefix="8" nationalPrefixFormattingRule="$NP ($FG)">
       <availableFormats>
         <!-- Formatting from wikipedia, confirmed on Goverment websites such
         as http://www.minjust.ru/ru/structure/contact/ -->
@@ -4897,8 +5148,38 @@
     </territory>
 
     <!-- Seychelles -->
-    <territory id="SC" countryCode="248" internationalPrefix="00"
-               nationalPrefix="0">
+    <!-- http://www.itu.int/oth/T02020000BA/en -->
+    <!-- No evidence can be found that they still use their national prefix, so
+    this is not currently supported. -->
+    <territory id="SC" countryCode="248" internationalPrefix="0[0-2]"
+      preferredInternationalPrefix="00">
+      <availableFormats>
+        <numberFormat pattern="(\d{3})(\d{3})">$1 $2</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[2-8]\d{5}</nationalNumberPattern>
+        <possibleNumberPattern>\d{6}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <!-- Includes Fixed Cellular. We are putting Fixed Services numbers
+        here for now, as we cannot find any evidence that they are more
+        expensive to call than other Fixed Line services. ISDN and DID services
+        are here too, since they seem to be also fixed-line phone numbers. -->
+        <nationalNumberPattern>(?:2(?:1[78]|2[14-69]|3[2-4]|4[1-36-8]|6[167]|[89]\d)|3(?:2[1-6]|4[4-6]|55|6[016]|7\d|8[0-589]|9[0-5])|5(?:5\d|6[0-2])|6(?:0[0-27-9]|1[0-478]|2[145]|3[02-4]|4[124]|6[015]|7\d|8[1-3])|78[0138])\d{3}</nationalNumberPattern>
+        <exampleNumber>217123</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <nationalNumberPattern>(?:5(?:[1247-9]\d|6[3-9])|7(?:[14679]\d|2[1-9]|8[24-79]))\d{3}</nationalNumberPattern>
+        <exampleNumber>510123</exampleNumber>
+      </mobile>
+      <tollFree>
+        <nationalNumberPattern>8000\d{2}</nationalNumberPattern>
+        <exampleNumber>800000</exampleNumber>
+      </tollFree>
+      <voip>
+        <nationalNumberPattern>4[1-37]\d{4}</nationalNumberPattern>
+        <exampleNumber>410123</exampleNumber>
+      </voip>
     </territory>
 
     <!-- Sudan -->
@@ -5008,7 +5289,7 @@
       <availableFormats>
         <numberFormat leadingDigits="[12]|3[4-8]|4[24-8]|5[4-8]|7[3-8]"
           pattern="(\d)(\d{3})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
-        <numberFormat leadingDigits="[347][01]|51|64"
+        <numberFormat leadingDigits="[37][01]|4[019]|51|64"
           pattern="([3-7]\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat>
         <numberFormat leadingDigits="[89]" pattern="([89]0)(\d{4,6})">$1 $2</numberFormat>
       </availableFormats>
@@ -5022,7 +5303,7 @@
         <exampleNumber>1123456</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:[347][01]|51|64)\d{6}</nationalNumberPattern>
+        <nationalNumberPattern>(?:[37][01]|4[019]|51|64)\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{8}</possibleNumberPattern>
         <exampleNumber>31234567</exampleNumber>
       </mobile>
@@ -5083,8 +5364,29 @@
     </territory>
 
     <!-- Sierra Leone -->
+    <!-- http://www.itu.int/oth/T02020000BB/en -->
     <territory id="SL" countryCode="232" internationalPrefix="00"
-               nationalPrefix="0">
+               nationalPrefix="0" nationalPrefixFormattingRule="($NP$FG)">
+      <availableFormats>
+        <!-- Following formatting of online yellow pages
+             www.leonedirect.com -->
+        <numberFormat pattern="(\d{2})(\d{6})">$1 $2</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[2-578]\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{6,8}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>[235]2[2-4][2-9]\d{4}</nationalNumberPattern>
+        <exampleNumber>22221234</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <!-- Adding prefix 50 because it was found in online numbers and this is
+        supported by http://www.wtng.info/wtng-232-sl.html - although the data
+        may be outdated, since no further information about Datatel can be found. -->
+        <nationalNumberPattern>(?:25|3[03]|44|5[056]|7[6-8]|88)[1-9]\d{5}</nationalNumberPattern>
+        <exampleNumber>25123456</exampleNumber>
+      </mobile>
     </territory>
 
     <!-- San Marino -->
@@ -5109,7 +5411,9 @@
         <exampleNumber>301012345</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>7(?:0[1256]0|6(?:1[23]|2[89]|3[3489]|4[6-9]|5[1-389]|6[6-9]|7[45]|8[3-8])|7(?:1[014-8]|2[0-7]|3[0-35-8]|4[0-6]|[56]\d|7[0-389]|[89][01]))\d{5}</nationalNumberPattern>
+        <!-- Adding 77 7[45]X and 77 9[0-6]X from online searches and from
+        numbers successfully delivered by the wireless team. -->
+        <nationalNumberPattern>7(?:0[1256]0|6(?:1[23]|2[89]|3[3489]|4[6-9]|5[1-389]|6[6-9]|7[45]|8[3-8])|7(?:1[014-8]|2[0-7]|3[0-35-8]|4[0-6]|[56]\d|7[0-589]|8[01]|9[0-6]))\d{5}</nationalNumberPattern>
         <exampleNumber>701012345</exampleNumber>
       </mobile>
       <voip>
@@ -5119,7 +5423,38 @@
     </territory>
 
     <!-- Somalia -->
+    <!-- http://www.itu.int/oth/T02020000C0/en -->
+    <!-- This document seems to cover only a small set of prefixes in Somalia.
+    Somalia has limited information available, and the numerous telecom carriers
+    were previously working under an unregulated environment. The extra prefixes
+    were added from the contact phone numbers of the countries main telecom
+    operators. See regression tests for more details. -->
     <territory id="SO" countryCode="252" internationalPrefix="00">
+      <availableFormats>
+        <!-- These follow formats online, such as www.hortel.net/contact_us.html
+        -->
+        <numberFormat leadingDigits="[13-5]"
+          pattern="([13-5])(\d{6})">$1 $2</numberFormat>
+        <!-- Unfortunately numbers beginning with 1 are hard to format based on
+        prefixes, since it depends on number length. -->
+        <numberFormat leadingDigits="[19]"
+          pattern="([19]\d)(\d{6})">$1 $2</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[13-59]\d{6,7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{7,8}</possibleNumberPattern>
+      </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>(?:5[57-9]|[134]\d)\d{5}</nationalNumberPattern>
+        <possibleNumberPattern>\d{7}</possibleNumberPattern>
+        <!-- Example numbers are test numbers from the document. -->
+        <exampleNumber>5522010</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <nationalNumberPattern>(?:9[01]|15)\d{6}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8}</possibleNumberPattern>
+        <exampleNumber>90792024</exampleNumber>
+      </mobile>
     </territory>
 
     <!-- Suriname -->
@@ -5171,7 +5506,10 @@
         <exampleNumber>112345678</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>9(?:3[23]|4[47]|55|66|88|99)\d{6}</nationalNumberPattern>
+        <!-- 945, 967 and 991 numbers are added as we successfully
+        delivered SMS messages to these numbers, and they are also widely
+        present on the Internet. -->
+        <nationalNumberPattern>9(?:3[23]|4[457]|55|6[67]|88|9[19])\d{6}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
         <exampleNumber>944567890</exampleNumber>
       </mobile>
@@ -5249,21 +5587,22 @@
          internationalPrefix="00|16">
       <availableFormats>
         <numberFormat
-          pattern="([2369]\d{2})(\d{2})(\d{2})">$1 $2 $3</numberFormat>
+          pattern="(\d{2})(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
       </availableFormats>
       <generalDesc>
-        <nationalNumberPattern>[2369]\d{6}</nationalNumberPattern>
-        <possibleNumberPattern>\d{7}</possibleNumberPattern>
+        <nationalNumberPattern>[2679]\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{8}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
-        <nationalNumberPattern>2(?:5[0-4]|6[89])\d{4}</nationalNumberPattern>
-        <exampleNumber>2511234</exampleNumber>
+        <nationalNumberPattern>22(?:[3789]0|5[0-5]|6[89])\d{4}</nationalNumberPattern>
+        <exampleNumber>22501234</exampleNumber>
       </fixedLine>
       <mobile>
-        <!-- The mobile ranges have been relaxed from the national numbering
-             plan following evidence from online numbers. -->
-        <nationalNumberPattern>(?:3[0-7]|6[27]|9\d)\d{5}</nationalNumberPattern>
-        <exampleNumber>6201234</exampleNumber>
+        <!-- Sotel Tchad "SALAM" (77 XX XX XX) is classified as a fixed operator in the plan, but it
+             also says numbers starting with 7 are mobile numbers. Putting under
+             mobile for now. Also adding 63[5-7] from sms evidence. -->
+        <nationalNumberPattern>(?:6(?:3[0-7]|6\d)|77\d|9(?:5[0-4]|9\d))\d{5}</nationalNumberPattern>
+        <exampleNumber>63012345</exampleNumber>
       </mobile>
     </territory>
 
@@ -5318,7 +5657,9 @@
         <exampleNumber>21234567</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>8[13-9]\d{7}</nationalNumberPattern>
+        <!-- 8[02] numbers are added as we successfully delivered SMS messages to these
+             numbers, and they are also widely present on the Internet. -->
+        <nationalNumberPattern>8\d{8}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
         <exampleNumber>812345678</exampleNumber>
       </mobile>
@@ -5349,9 +5690,9 @@
           pattern="([349]\d{2})(\d{2})(\d{4})">$1 $2 $3</numberFormat>
         <numberFormat leadingDigits="4[48]" pattern="(4[48])(\d{3})(\d{4})">$1 $2 $3</numberFormat>
         <numberFormat leadingDigits="3317" pattern="(331700)(\d)(\d{2})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="3(?:[1245]|3(?:[02-9]|1[0-589])"
+        <numberFormat leadingDigits="3(?:[1245]|3(?:[02-9]|1[0-589]))"
           pattern="(\d{4})(\d)(\d{4})">$1 $2 $3</numberFormat>
-        <numberFormat leadingDigits="9(?:19|[235-9])"
+        <numberFormat leadingDigits="9(?:19|[0235-9])"
           pattern="(9\d)(\d{3})(\d{4})">$1 $2 $3</numberFormat>
       </availableFormats>
       <generalDesc>
@@ -5363,7 +5704,9 @@
         <exampleNumber>372123456</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>9[1-35-9]\d{7}</nationalNumberPattern>
+        <!-- Adding 90 prefix as we could successfully deliver SMS messages to these mobile
+             numbers. -->
+        <nationalNumberPattern>9[0-35-9]\d{7}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
         <exampleNumber>917123456</exampleNumber>
       </mobile>
@@ -5381,18 +5724,27 @@
     <!-- Turkmenistan -->
     <!-- http://www.itu.int/oth/T02020000D7/en -->
     <territory id="TM" countryCode="993" internationalPrefix="8~10"
-               nationalPrefix="8" nationalPrefixFormattingRule="$NP$FG">
+               nationalPrefix="8" nationalPrefixFormattingRule="$NP $FG">
       <availableFormats>
         <!-- There doesn't seem to be a standardized format. The format below is based on the
              Turkmenistan embassy at
              http://www.turkmenistanembassy.org/turkmen/info/contact.html-->
-      <numberFormat pattern="([1-5]\d)(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
+      <numberFormat pattern="([1-6]\d)(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat>
       </availableFormats>
       <generalDesc>
-        <nationalNumberPattern>(?:12\d|243|[3-5]22)\d{5}</nationalNumberPattern>
+        <nationalNumberPattern>[1-6]\d{7}</nationalNumberPattern>
         <possibleNumberPattern>\d{8}</possibleNumberPattern>
-        <exampleNumber>12345678</exampleNumber>
       </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>(?:12\d|243|[3-5]22)\d{5}</nationalNumberPattern>
+        <exampleNumber>12345678</exampleNumber>
+      </fixedLine>
+      <mobile>
+        <!-- Adding 68 as we successfully sent SMS messages to numbers
+        with this prefix. -->
+        <nationalNumberPattern>6[6-8]\d{6}</nationalNumberPattern>
+        <exampleNumber>66123456</exampleNumber>
+      </mobile>
       <!-- No tollFree or premiumRate information can be found.-->
     </territory>
 
@@ -5565,7 +5917,7 @@
         is useful but not error-free. Have used local yellow pages guidelines,
         Google searches and regression tests to reverse-engineer these rules.
         -->
-        <numberFormat leadingDigits="39|4(?:[45][0-5]|87)|5(?:0|7[37])|6[36-8]|9[1-9]"
+        <numberFormat leadingDigits="39|4(?:[45][0-5]|87)|5(?:0|67|7[37])|6[36-8]|9[1-9]"
           pattern="([3-69]\d)(\d{3})(\d{4})">$1 $2 $3</numberFormat>
         <numberFormat
           leadingDigits="3(?:[1-46-8]2[013-9]|52)|4[1378]2|5(?:[124-7]2|64)|6(?:[49]2|[12][29]|5[24])|8|90"
@@ -5694,11 +6046,15 @@
         <possibleNumberPattern>\d{7,9}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
-        <nationalNumberPattern>(?:6[125679]|7[1-69])\d{7}</nationalNumberPattern>
+        <!-- Adding 70 prefix as suggested by http://www.ttts.uz/eng/telephone_codes/codes_uzb_eng
+        -->
+        <nationalNumberPattern>(?:6[125679]|7[0-69])\d{7}</nationalNumberPattern>
         <exampleNumber>612345678</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>9[0-37-9]\d{7}</nationalNumberPattern>
+        <!-- Adding 9[45] as suggested by
+        http://www.ucell.uz/en/for_subscribers/how_to_call.html -->
+        <nationalNumberPattern>9[0-57-9]\d{7}</nationalNumberPattern>
         <exampleNumber>912345678</exampleNumber>
       </mobile>
       <!-- No tollFree or premiumRate information can be found.-->
@@ -5824,7 +6180,9 @@
         <exampleNumber>2101234567</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>(?:9[0-8]|1(?:2\d|6[46-9]|99))\d{7}</nationalNumberPattern>
+        <!-- Adding 16[35] because we sent SMS messages successfully
+        to many numbers with these prefixes. -->
+        <nationalNumberPattern>(?:9[0-8]|1(?:2\d|6[3-9]|99))\d{7}</nationalNumberPattern>
         <possibleNumberPattern>\d{9,10}</possibleNumberPattern>
         <exampleNumber>912345678</exampleNumber>
       </mobile>
@@ -5990,10 +6348,13 @@
     <territory id="ZM" countryCode="260" internationalPrefix="00"
                nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
       <availableFormats>
-        <numberFormat pattern="([29]\d)(\d{7})">$1 $2</numberFormat>
+        <numberFormat leadingDigits="[29]"
+          pattern="([29]\d)(\d{7})">$1 $2</numberFormat>
+        <numberFormat leadingDigits="8"
+          pattern="(800)(\d{3})(\d{3})">$1 $2 $3</numberFormat>
       </availableFormats>
       <generalDesc>
-        <nationalNumberPattern>[29]\d{8}</nationalNumberPattern>
+        <nationalNumberPattern>[289]\d{8}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
@@ -6001,9 +6362,16 @@
         <exampleNumber>211234567</exampleNumber>
       </fixedLine>
       <mobile>
-        <nationalNumberPattern>9(?:55|66|7[7-9])\d{6}</nationalNumberPattern>
+        <!-- Adding extra prefixes 6[457-9] and 7[4-6] since SMS messages have
+        been successfully delivered to these numbers, and
+        numbers like this can be found on the Internet. -->
+        <nationalNumberPattern>9(?:55|6[4-9]|7[4-9])\d{6}</nationalNumberPattern>
         <exampleNumber>955123456</exampleNumber>
       </mobile>
+      <tollFree>
+        <nationalNumberPattern>800\d{6}</nationalNumberPattern>
+        <exampleNumber>800123456</exampleNumber>
+      </tollFree>
     </territory>
 
     <!-- Zimbabwe -->
diff --git a/java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto b/java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto
old mode 100755
new mode 100644
index 2cad064..6fd1591
--- a/java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto
+++ b/java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto
Binary files differ
diff --git a/java/resources/com/google/i18n/phonenumbers/test/PhoneNumberMetaDataForTesting.xml b/java/resources/com/google/i18n/phonenumbers/test/PhoneNumberMetaDataForTesting.xml
index 21d2da3..524507b 100644
--- a/java/resources/com/google/i18n/phonenumbers/test/PhoneNumberMetaDataForTesting.xml
+++ b/java/resources/com/google/i18n/phonenumbers/test/PhoneNumberMetaDataForTesting.xml
@@ -16,7 +16,8 @@
 
      MetaData on Phone Number Plan and formatting rules. This file is used
      solely for the purpose of unittesting, so data in this file is not
-     necessarily consistent with that of PhoneNumberMetaData.xml
+     necessarily consistent with that of
+     ../src/PhoneNumberMetaData.xml
 -->
 
 <phoneNumberMetadata>
@@ -233,6 +234,52 @@
       </premiumRate>
     </territory>
 
+    <!-- Korea (Rep. of) -->
+    <!-- http://www.itu.int/oth/T0202000072/en -->
+    <!-- http://en.wikipedia.org/wiki/%2B82 -->
+    <!-- http://www.kcc.go.kr/user.do?mode=view&page=P02030300&dc=K02030300&boardId=1074&boardSeq=2349 -->
+    <!-- http://www.kcc.go.kr/user.do?mode=view&page=P02030300&dc=K02030300&boardId=1074&boardSeq=2240 -->
+    <!-- http://www.telecentro.co.kr/sub/index.php?job=detail&ebcf_id=faq&page=1&mid=0503&eb_seq=36 -->
+    <!-- Exceptions :
+        internationalPrefix
+            0031, 0033, 0071, 0073 - Special services of KT and DACOM, ignorable
+        nationalPrefix
+            1[4-6]XX-YYYY - Country-wide common number services, display as it is without hyphens -->
+    <territory id="KR" countryCode="82" internationalPrefix="00(?:[124-68]|[37]\d{2})"
+               nationalPrefix="0" nationalPrefixForParsing="0(?:8[1-46-8]|85\d{2})?"
+               nationalPrefixFormattingRule="$NP$FG">
+      <availableFormats>
+        <numberFormat leadingDigits="1(?:0|1[19]|[69]9|5(?:44|59|8))|[57]0"
+                      pattern="(\d{2})(\d{4})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="1(?:[169][2-8]|[78]|5(?:[1-3]|4[56]))|[68]0|[3-9][1-9][2-9]"
+                      pattern="(\d{2})(\d{3})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="1312"
+                      pattern="(\d{3})(\d)(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="131[13-9]"
+                      pattern="(\d{3})(\d{2})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="13[2-9]"
+                      pattern="(\d{3})(\d{3})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="30"
+                      pattern="(\d{2})(\d{2})(\d{3})(\d{4})">$1-$2-$3-$4</numberFormat>
+        <numberFormat leadingDigits="2(?:[26]|3(?:01|1[45]|2[17-9]|39|4|6[67]|7[078]))"
+                      pattern="(\d)(\d{4})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="2(?:3(?:0[02-9]|1[0-36-9]|2[02-6]|3[0-8]|6[0-589]|7[1-69]|[589])|[457-9])"
+                      pattern="(\d)(\d{3})(\d{4})">$1-$2-$3</numberFormat>
+        <numberFormat leadingDigits="21(?:[0-247-9]|3[124]|6[1269])"
+                      pattern="(\d)(\d{3})">$1-$2</numberFormat>
+        <numberFormat leadingDigits="21(?:3[035-9]|6[03-578])"
+                      pattern="(\d)(\d{4})">$1-$2</numberFormat>
+        <numberFormat leadingDigits="[3-9][1-9]1(?:[0-247-9]|3[124]|6[1269])"
+                      pattern="(\d{2})(\d{3})">$1-$2</numberFormat>
+        <numberFormat leadingDigits="[3-9][1-9]1(?:3[035-9]|6[03-578])"
+                      pattern="(\d{2})(\d{4})">$1-$2</numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[1-79]\d{3,9}|8\d{8}</nationalNumberPattern>
+        <possibleNumberPattern>\d{4,10}</possibleNumberPattern>
+      </generalDesc>
+    </territory>
+
     <!-- Mexico -->
     <territory id="MX" countryCode="52" internationalPrefix="00"
                nationalPrefix="01" nationalPrefixForParsing="01|04[45](\d{10})"
diff --git a/java/resources/com/google/i18n/phonenumbers/test/generated_files/PhoneNumberMetadataProtoForTesting b/java/resources/com/google/i18n/phonenumbers/test/generated_files/PhoneNumberMetadataProtoForTesting
index 769c0fd..219407c 100644
--- a/java/resources/com/google/i18n/phonenumbers/test/generated_files/PhoneNumberMetadataProtoForTesting
+++ b/java/resources/com/google/i18n/phonenumbers/test/generated_files/PhoneNumberMetadataProtoForTesting
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java b/java/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java
index b850cd5..81cb10d 100644
--- a/java/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java
+++ b/java/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java
@@ -30,6 +30,7 @@
 import java.io.IOException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.regex.Pattern;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -84,24 +85,32 @@
     }
   }
 
+  private static String validateRE(String regex) {
+    Pattern regexPattern = Pattern.compile(regex);
+    // return regex itself if it is of correct regex syntax
+    return regex;
+  }
+
   private static PhoneMetadata loadCountryMetadata(String regionCode, Element element) {
     PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
     metadata.setId(regionCode);
     metadata.setCountryCode(Integer.parseInt(element.getAttribute("countryCode")));
-    metadata.setInternationalPrefix(element.getAttribute("internationalPrefix"));
+    metadata.setInternationalPrefix(validateRE(element.getAttribute("internationalPrefix")));
     if (element.hasAttribute("preferredInternationalPrefix")) {
       String preferredInternationalPrefix = element.getAttribute("preferredInternationalPrefix");
       metadata.setPreferredInternationalPrefix(preferredInternationalPrefix);
     }
     String nationalPrefix = "";
+    String nationalPrefixFormattingRule = "";
     if (element.hasAttribute("nationalPrefix")) {
       nationalPrefix = element.getAttribute("nationalPrefix");
       metadata.setNationalPrefix(nationalPrefix);
-      metadata.setNationalPrefixFormattingRule(
-          getNationalPrefixFormattingRuleFromElement(element, nationalPrefix));
+       nationalPrefixFormattingRule =
+          validateRE(getNationalPrefixFormattingRuleFromElement(element, nationalPrefix));
 
       if (element.hasAttribute("nationalPrefixForParsing")) {
-        metadata.setNationalPrefixForParsing(element.getAttribute("nationalPrefixForParsing"));
+        metadata.setNationalPrefixForParsing(
+            validateRE(element.getAttribute("nationalPrefixForParsing")));
         if (element.hasAttribute("nationalPrefixTransformRule")) {
           metadata.setNationalPrefixTransformRule(
               element.getAttribute("nationalPrefixTransformRule"));
@@ -122,17 +131,16 @@
         Element numberFormatElement = (Element) numberFormatElements.item(i);
         NumberFormat.Builder format = NumberFormat.newBuilder();
         if (numberFormatElement.hasAttribute("nationalPrefixFormattingRule")) {
-          format.setNationalPrefixFormattingRule(
-              getNationalPrefixFormattingRuleFromElement(numberFormatElement, nationalPrefix));
+          format.setNationalPrefixFormattingRule(validateRE(
+              getNationalPrefixFormattingRuleFromElement(numberFormatElement, nationalPrefix)));
         } else {
-          format.setNationalPrefixFormattingRule(metadata.getNationalPrefixFormattingRule());
+          format.setNationalPrefixFormattingRule(nationalPrefixFormattingRule);
         }
         if (numberFormatElement.hasAttribute("leadingDigits")) {
-          format.setLeadingDigits(numberFormatElement.getAttribute("leadingDigits"));
+          format.setLeadingDigits(validateRE(numberFormatElement.getAttribute("leadingDigits")));
         }
-        format.setPattern(numberFormatElement.getAttribute("pattern"));
-        String formatValue = numberFormatElement.getFirstChild().getNodeValue();
-        format.setFormat(formatValue);
+        format.setPattern(validateRE(numberFormatElement.getAttribute("pattern")));
+        format.setFormat(validateRE(numberFormatElement.getFirstChild().getNodeValue()));
         metadata.addNumberFormat(format.build());
       }
     }
@@ -144,10 +152,10 @@
         Element numberFormatElement = (Element) intlNumberFormatElements.item(i);
         NumberFormat.Builder format = NumberFormat.newBuilder();
         if (numberFormatElement.hasAttribute("leadingDigits")) {
-          format.setLeadingDigits(numberFormatElement.getAttribute("leadingDigits"));
+          format.setLeadingDigits(validateRE(numberFormatElement.getAttribute("leadingDigits")));
         }
-        format.setPattern(numberFormatElement.getAttribute("pattern"));
-        format.setFormat(numberFormatElement.getFirstChild().getNodeValue());
+        format.setPattern(validateRE(numberFormatElement.getAttribute("pattern")));
+        format.setFormat(validateRE(numberFormatElement.getFirstChild().getNodeValue()));
         metadata.addIntlNumberFormat(format.build());
       }
     }
@@ -215,14 +223,14 @@
       Element element = (Element) phoneNumberDescList.item(0);
       NodeList possiblePattern = element.getElementsByTagName("possibleNumberPattern");
       if (possiblePattern.getLength() > 0) {
-        numberDesc.setPossibleNumberPattern(possiblePattern.
-            item(0).getFirstChild().getNodeValue());
+        numberDesc.setPossibleNumberPattern(
+            validateRE(possiblePattern.item(0).getFirstChild().getNodeValue()));
       }
 
       NodeList validPattern = element.getElementsByTagName("nationalNumberPattern");
       if (validPattern.getLength() > 0) {
-        numberDesc.setNationalNumberPattern(validPattern.
-            item(0).getFirstChild().getNodeValue());
+        numberDesc.setNationalNumberPattern(
+            validateRE(validPattern.item(0).getFirstChild().getNodeValue()));
       }
 
       if (!liteBuild) {
diff --git a/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
index 073a45a..f55723a 100644
--- a/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
+++ b/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
@@ -24,6 +24,7 @@
 import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection;
 import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
 import com.google.protobuf.MessageLite;
 
 import java.io.ByteArrayOutputStream;
@@ -161,6 +162,7 @@
       new ImmutableSet.Builder<Integer>()
       .add(39)  // Italy
       .add(225)  // Cote d'Ivoire
+      .add(227)  // Niger
       .add(228)  // Togo
       .add(240)  // Equatorial Guinea
       .add(241)  // Gabon
@@ -483,6 +485,90 @@
   }
 
   /**
+   * Gets the length of the geographical area code from the national_number field of the PhoneNumber
+   * object passed in, so that clients could use it to split a national significant number into
+   * geographical area code and subscriber number. It works in such a way that the resultant
+   * subscriber number should be diallable, at least on some devices. An example of how this could
+   * be used:
+   *
+   * PhoneNumberUtil phoneUtil.PhoneNumberUtil.getInstance();
+   * PhoneNumber number = phoneUtil.parse("16502530000", RegionCode.US);
+   * String nationalSignificantNumber = PhoneNumberUtil.getNationalSignificantNumber(number);
+   * String areaCode;
+   * String subscriberNumber;
+   *
+   * int areaCodeLength = phoneUtil.getLengthOfGeographicalAreaCode(number);
+   * if (areaCodeLength > 0) {
+   *   areaCode = nationalSignificantNumber.substring(0, areaCodeLength);
+   *   subscriberNumber = nationalSignificantNumber.substring(areaCodeLength);
+   * } else {
+   *   areaCode = "";
+   *   subscriberNumber = nationalSignificantNumber;
+   * }
+   *
+   * N.B.: area code is a very ambiguous concept, so the I18N team generally recommends against
+   * using it for most purposes, but recommends using the more general national_number instead. Read
+   * the following carefully before deciding to use this method:
+   *
+   *  - geographical area codes change over time, and this method honors those changes; therefore,
+   *    it doesn't guarantee the stability of the result it produces.
+   *  - subscriber numbers may not be diallable from all devices (notably mobile devices, which
+   *    typically requires the full national_number to be dialled in most countries).
+   *  - most non-geographical numbers have no area codes.
+   *  - some geographical numbers have no area codes.
+   *
+   * @param number  the PhoneNumber object for which clients want to know the length of the area
+   *     code in the national_number field.
+   * @return  the length of area code of the PhoneNumber object passed in.
+   */
+  public int getLengthOfGeographicalAreaCode(PhoneNumber number) {
+    String regionCode = getRegionCodeForNumber(number);
+    if (regionCode == null || regionCode.equalsIgnoreCase("ZZ")) {
+      return 0;
+    }
+    PhoneMetadata metadata = getMetadataForRegion(regionCode);
+    // For NANPA countries, national prefix is the same as country code, but it is not stored in
+    // the metadata.
+    if (!metadata.hasNationalPrefix() && !isNANPACountry(regionCode)) {
+      return 0;
+    }
+
+    PhoneNumberType type = getNumberTypeHelper(String.valueOf(number.getNationalNumber()),
+                                               metadata);
+    // Most numbers other than the two types below have to be dialled in full.
+    if (type != PhoneNumberType.FIXED_LINE && type != PhoneNumberType.FIXED_LINE_OR_MOBILE) {
+      return 0;
+    }
+
+    PhoneNumber copiedProto;
+    if (number.hasExtension()) {
+      // We don't want to alter the proto given to us, but we don't want to include the extension
+      // when we format it, so we copy it and clear the extension here.
+      PhoneNumber.Builder protoBuilder = PhoneNumber.newBuilder();
+      protoBuilder.mergeFrom(number);
+      protoBuilder.clearExtension();
+      copiedProto = protoBuilder.build();
+    } else {
+      copiedProto = number;
+    }
+
+    String nationalSignificantNumber = format(copiedProto,
+                                              PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);
+    Pattern nonDigitPattern = Pattern.compile("(\\D+)");
+    String[] numberGroups = nonDigitPattern.split(nationalSignificantNumber);
+    // The pattern will start with "+COUNTRY_CODE " so the first group will always be the empty
+    // string (before the + symbol) and the second group will be the country code. The third group
+    // will be area code if it is not the last group.
+    if (numberGroups.length <= 3) {
+      return 0;
+    }
+    // Note all countries that use leading zero in national number don't use national prefix, so
+    // they won't have an area code, which means clients don't need to worry about appending the
+    // leading zero to the geographical area code they derive from the length we return here.
+    return numberGroups[2].length();
+  }  
+
+  /**
    * Normalizes a string of characters representing a phone number by replacing all characters found
    * in the accompanying map with the values therein, and stripping all other characters if
    * removeNonMatches is true.
@@ -493,7 +579,7 @@
    * @param removeNonMatches           indicates whether characters that are not able to be replaced
    *                                   should be stripped from the number. If this is false, they
    *                                   will be left unchanged in the number.
-   * @return the normalized string version of the phone number
+   * @return  the normalized string version of the phone number
    */
   private static String normalizeHelper(String number,
                                         Map<Character, Character> normalizationReplacements,
@@ -562,7 +648,7 @@
    * supplied is used only for the resultant log message.
    */
   private boolean isValidRegionCode(String regionCode, int countryCode, String number) {
-    if (regionCode == null || regionCode.equals("ZZ")) {
+    if (regionCode == null || regionCode.equalsIgnoreCase("ZZ")) {
       LOGGER.log(Level.WARNING,
                  "Number " + number + "has invalid or missing country code (" + countryCode + ")");
       return false;
@@ -581,11 +667,11 @@
    *
    * @param number         the phone number to be formatted
    * @param numberFormat   the format the phone number should be formatted into
-   * @return the formatted phone number
+   * @return  the formatted phone number
    */
   public String format(PhoneNumber number, PhoneNumberFormat numberFormat) {
     int countryCode = number.getCountryCode();
-    String nationalSignificantNumber = getUnformattedNationalNumber(number);
+    String nationalSignificantNumber = getNationalSignificantNumber(number);
     if (numberFormat == PhoneNumberFormat.E164) {
       // Early exit for E164 case since no formatting of the national number needs to be applied.
       // Extensions are not formatted.
@@ -616,7 +702,7 @@
    * @param number                        the phone number to be formatted
    * @param numberFormat                  the format the phone number should be formatted into
    * @param userDefinedFormats            formatting rules specified by clients
-   * @return the formatted phone number
+   * @return  the formatted phone number
    */
   public String formatByPattern(PhoneNumber number,
                                 PhoneNumberFormat numberFormat,
@@ -626,7 +712,7 @@
     // share a country code is contained by only one country for performance reasons. For example,
     // for NANPA countries it will be contained in the metadata for US.
     String regionCode = getRegionCodeForCountryCode(countryCode);
-    String nationalSignificantNumber = getUnformattedNationalNumber(number);
+    String nationalSignificantNumber = getNationalSignificantNumber(number);
     if (!isValidRegionCode(regionCode, countryCode, nationalSignificantNumber)) {
       return nationalSignificantNumber;
     }
@@ -670,15 +756,16 @@
    * @param number               the phone number to be formatted
    * @param countryCallingFrom   the ISO 3166-1 two-letter country code that denotes the foreign
    *                             country where the call is being placed
-   * @return the formatted phone number
+   * @return  the formatted phone number
    */
   public String formatOutOfCountryCallingNumber(PhoneNumber number,
                                                 String countryCallingFrom) {
-    if (countryCallingFrom == null || countryCallingFrom.equals("ZZ")) {
+    if (countryCallingFrom == null || countryCallingFrom.equalsIgnoreCase("ZZ")) {
       LOGGER.log(Level.WARNING,
                  "Trying to format number from invalid region. International formatting applied.");
       return format(number, PhoneNumberFormat.INTERNATIONAL);
     }
+    countryCallingFrom = countryCallingFrom.toUpperCase();
     int countryCode = number.getCountryCode();
     if (countryCode == NANPA_COUNTRY_CODE && isNANPACountry(countryCallingFrom)) {
       // For NANPA countries, return the national format for these countries but prefix it with the
@@ -718,7 +805,7 @@
     } else {
       regionCode = getRegionCodeForCountryCode(countryCode);
     }
-    String nationalSignificantNumber = getUnformattedNationalNumber(number);
+    String nationalSignificantNumber = getNationalSignificantNumber(number);
     if (!isValidRegionCode(regionCode, countryCode, nationalSignificantNumber)) {
       return nationalSignificantNumber;
     }
@@ -748,7 +835,15 @@
                                formattedExtension);
   }
 
-  static String getUnformattedNationalNumber(PhoneNumber number) {
+  
+  /**
+   * Gets the national significant number of the a phone number. Note a national significant number
+   * doesn't contain a national prefix or any formatting.
+   *
+   * @param number  the PhoneNumber object for which the national significant number is needed
+   * @return  the national significant number of the PhoneNumber object passed in
+   */
+  public static String getNationalSignificantNumber(PhoneNumber number) {
     // The leading zero in the national (significant) number of an Italian phone number has a
     // special meaning. Unlike the rest of the world, it indicates the number is a landline
     // number. There have been plans to migrate landline numbers to start with the digit two since
@@ -837,6 +932,7 @@
    *    does not contain such information.
    */
   public PhoneNumber getExampleNumber(String regionCode) {
+    regionCode = regionCode.toUpperCase();
     return getExampleNumberForType(regionCode, PhoneNumberType.FIXED_LINE);
   }
 
@@ -850,6 +946,7 @@
    *     does not contain such information.
    */
   public PhoneNumber getExampleNumberForType(String regionCode, PhoneNumberType type) {
+    regionCode = regionCode.toUpperCase();
     PhoneNumberDesc desc = getNumberDescByType(getMetadataForRegion(regionCode), type);
     try {
       if (desc.hasExampleNumber()) {
@@ -917,7 +1014,7 @@
    */
   public PhoneNumberType getNumberType(PhoneNumber number) {
     String regionCode = getRegionCodeForNumber(number);
-    String nationalSignificantNumber = getUnformattedNationalNumber(number);
+    String nationalSignificantNumber = getNationalSignificantNumber(number);
     if (!isValidRegionCode(regionCode, number.getCountryCode(), nationalSignificantNumber)) {
       return PhoneNumberType.UNKNOWN;
     }
@@ -1003,7 +1100,7 @@
   public boolean isValidNumber(PhoneNumber number) {
     String regionCode = getRegionCodeForNumber(number);
     return isValidRegionCode(regionCode, number.getCountryCode(),
-                             getUnformattedNationalNumber(number))
+                             getNationalSignificantNumber(number))
            && isValidNumberForRegion(number, regionCode);
   }
 
@@ -1021,12 +1118,13 @@
    * @return  a boolean that indicates whether the number is of a valid pattern
    */
   public boolean isValidNumberForRegion(PhoneNumber number, String regionCode) {
+    regionCode = regionCode.toUpperCase();
     if (number.getCountryCode() != getCountryCodeForRegion(regionCode)) {
       return false;
     }
     PhoneMetadata metadata = getMetadataForRegion(regionCode);
     PhoneNumberDesc generalNumDesc = metadata.getGeneralDesc();
-    String nationalSignificantNumber = getUnformattedNationalNumber(number);
+    String nationalSignificantNumber = getNationalSignificantNumber(number);
 
     // For countries where we don't have metadata for PhoneNumberDesc, we treat any number passed
     // in as a valid number if its national significant number is between the minimum and maximum
@@ -1053,7 +1151,9 @@
       case NANPA_COUNTRY_CODE:
         // Override this and try the US case first, since it is more likely than other countries,
         // for performance reasons.
-        if (isValidNumberForRegion(number, "US")) {
+        String nationalNumber = getNationalSignificantNumber(number);
+        if (getNumberTypeHelper(nationalNumber,
+                                getMetadataForRegion("US")) != PhoneNumberType.UNKNOWN) {
           return "US";
         }
         Set<String> nanpaExceptUS = new HashSet<String>(nanpaCountries);
@@ -1098,11 +1198,11 @@
    * @return  the country calling code for the country/region denoted by regionCode
    */
   public int getCountryCodeForRegion(String regionCode) {
-    if (regionCode == null || regionCode.equals("ZZ")) {
+    if (regionCode == null || regionCode.equalsIgnoreCase("ZZ")) {
       LOGGER.log(Level.SEVERE, "Invalid or missing country code provided.");
       return 0;
     }
-    PhoneMetadata metadata = getMetadataForRegion(regionCode);
+    PhoneMetadata metadata = getMetadataForRegion(regionCode.toUpperCase());
     if (metadata == null) {
       LOGGER.log(Level.SEVERE, "Unsupported country code provided.");
       return 0;
@@ -1117,6 +1217,7 @@
    * @return  true if regionCode is one of the countries under NANPA
    */
   public boolean isNANPACountry(String regionCode) {
+    regionCode = regionCode.toUpperCase();
     return nanpaCountries.contains(regionCode);
   }
 
@@ -1159,7 +1260,7 @@
    * @return  a ValidationResult object which indicates whether the number is possible
    */
   public ValidationResult isPossibleNumberWithReason(PhoneNumber number) {
-    String nationalNumber = getUnformattedNationalNumber(number);
+    String nationalNumber = getNationalSignificantNumber(number);
     int countryCode = number.getCountryCode();
     // Note: For Russian Fed and NANPA numbers, we just use the rules from the default region (US or
     // Russia) since the getRegionCodeForNumber will not work if the number is possible but not
@@ -1202,6 +1303,7 @@
    * @return  true if the number is possible
    */
   public boolean isPossibleNumber(String number, String countryDialingFrom) {
+    countryDialingFrom = countryDialingFrom.toUpperCase();
     try {
       return isPossibleNumber(parse(number, countryDialingFrom));
     } catch (NumberParseException e) {
@@ -1225,6 +1327,7 @@
    *     specific country "as you type"
    */
   public AsYouTypeFormatter getAsYouTypeFormatter(String regionCode) {
+    regionCode = regionCode.toUpperCase();
     return new AsYouTypeFormatter(regionCode);
   }
 
@@ -1264,19 +1367,34 @@
    * @param nationalNumber  a string buffer to store the national significant number in, in the case
    *     that a country code was extracted. The number is appended to any existing contents. If no
    *     country code was extracted, this will be left unchanged.
+   * @param storeCountryCodeSource  true if the country_code_source field of phoneNumber should be
+   *     populated.
+   * @param phoneNumber  the PhoneNumber.Builder object that needs to be populated with country code
+   *     and country code source. Note the country code is always populated, whereas country code
+   *     source is only populated when keepCountryCodeSource is true.
    * @return  the country code extracted or 0 if none could be extracted
    */
   @VisibleForTesting
   int maybeExtractCountryCode(String number, PhoneMetadata defaultRegionMetadata,
-                              StringBuffer nationalNumber)
+                              StringBuffer nationalNumber, boolean storeCountryCodeSource,
+                              PhoneNumber.Builder phoneNumber)
       throws NumberParseException {
+    if (number.length() == 0) {
+      return 0;
+    }
     StringBuffer fullNumber = new StringBuffer(number);
     // Set the default prefix to be something that will never match.
     String possibleCountryIddPrefix = "NonMatch";
     if (defaultRegionMetadata != null) {
       possibleCountryIddPrefix = defaultRegionMetadata.getInternationalPrefix();
     }
-    if (maybeStripInternationalPrefixAndNormalize(fullNumber, possibleCountryIddPrefix)) {
+
+    CountryCodeSource countryCodeSource =
+        maybeStripInternationalPrefixAndNormalize(fullNumber, possibleCountryIddPrefix);
+    if (storeCountryCodeSource) {
+      phoneNumber.setCountryCodeSource(countryCodeSource);
+    }
+    if (countryCodeSource != CountryCodeSource.FROM_DEFAULT_COUNTRY) {
       if (fullNumber.length() < MIN_LENGTH_FOR_NSN) {
         throw new NumberParseException(NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
                                        "Phone number had an IDD, but after this was not "
@@ -1284,6 +1402,7 @@
       }
       int potentialCountryCode = extractCountryCode(fullNumber, nationalNumber);
       if (potentialCountryCode != 0) {
+        phoneNumber.setCountryCode(potentialCountryCode);
         return potentialCountryCode;
       }
 
@@ -1311,12 +1430,17 @@
               validNumberPattern);
           if (validNumberPattern.matcher(potentialNationalNumber).matches()) {
             nationalNumber.append(potentialNationalNumber);
+            if (storeCountryCodeSource) {
+              phoneNumber.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN);
+            }
+            phoneNumber.setCountryCode(defaultCountryCode);
             return defaultCountryCode;
           }
         }
       }
     }
     // No country code present.
+    phoneNumber.setCountryCode(0);
     return 0;
   }
 
@@ -1324,8 +1448,7 @@
    * Strips the IDD from the start of the number if present. Helper function used by
    * maybeStripInternationalPrefixAndNormalize.
    */
-  private boolean parsePrefixAsIdd(Pattern iddPattern,
-                                   StringBuffer number) {
+  private boolean parsePrefixAsIdd(Pattern iddPattern, StringBuffer number) {
     Matcher m = iddPattern.matcher(number);
     if (m.lookingAt()) {
       int matchEnd = m.end();
@@ -1352,31 +1475,36 @@
    *     dialing prefix from
    * @param possibleIddPrefix  the international direct dialing prefix from the country we
    *     think this number may be dialed in
-   * @return  true if an international dialing prefix could be removed from the number, otherwise
-   *     false if the number did not seem to be in international format
+   * @return  the corresponding CountryCodeSource if an international dialing prefix could be
+   *     removed from the number, otherwise CountryCodeSource.FROM_DEFAULT_COUNTRY if the number
+   *     did not seem to be in international format.
    */
   @VisibleForTesting
-  boolean maybeStripInternationalPrefixAndNormalize(StringBuffer number, String possibleIddPrefix) {
+  CountryCodeSource maybeStripInternationalPrefixAndNormalize(
+      StringBuffer number,
+      String possibleIddPrefix) {
     if (number.length() == 0) {
-      return false;
+      return CountryCodeSource.FROM_DEFAULT_COUNTRY;
     }
     if (number.charAt(0) == PLUS_SIGN) {
       number.deleteCharAt(0);
       // Can now normalize the rest of the number since we've consumed the "+" sign at the start.
       normalize(number);
-      return true;
+      return CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN;
     }
     // Attempt to parse the first digits as an international prefix.
     Pattern iddPattern = Pattern.compile(possibleIddPrefix);
     if (parsePrefixAsIdd(iddPattern, number)) {
       normalize(number);
-      return true;
+      return CountryCodeSource.FROM_NUMBER_WITH_IDD;
     }
     // If still not found, then try and normalize the number and then try again. This shouldn't be
     // done before, since non-numeric characters (+ and ~) may legally be in the international
     // prefix.
     normalize(number);
-    return parsePrefixAsIdd(iddPattern, number);
+    return parsePrefixAsIdd(iddPattern, number)
+        ? CountryCodeSource.FROM_NUMBER_WITH_IDD
+        : CountryCodeSource.FROM_DEFAULT_COUNTRY;
   }
 
   /**
@@ -1472,16 +1600,17 @@
    */
   public PhoneNumber parse(String numberToParse, String defaultCountry)
       throws NumberParseException {
-    if (defaultCountry == null || defaultCountry.equals("ZZ")) {
+    if (defaultCountry == null || defaultCountry.equalsIgnoreCase("ZZ")) {
       throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
                                      "No default country was supplied.");
     }
-    return parseHelper(numberToParse, defaultCountry, false);
+    return parseHelper(numberToParse, defaultCountry.toUpperCase(), false);
   }
 
   /**
    * Parses a string and returns it in proto buffer format. This method differs from parse() in that
-   * it always populates the raw_input field of the protocol buffer with numberToParse.
+   * it always populates the raw_input field of the protocol buffer with numberToParse as well as
+   * the country_code_source field.
    *
    * @param numberToParse     number that we are attempting to parse. This can contain formatting
    *                          such as +, ( and -, as well as a phone number extension.
@@ -1496,11 +1625,11 @@
    */
   public PhoneNumber parseAndKeepRawInput(String numberToParse, String defaultCountry)
       throws NumberParseException {
-    if (defaultCountry == null || defaultCountry.equals("ZZ")) {
+    if (defaultCountry == null || defaultCountry.equalsIgnoreCase("ZZ")) {
       throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
                                      "No default country was supplied.");
     }
-    return parseHelper(numberToParse, defaultCountry, true);
+    return parseHelper(numberToParse, defaultCountry.toUpperCase(), true);
   }
 
   /**
@@ -1563,10 +1692,12 @@
     // been created, and just remove the prefix, rather than taking in a string and then outputting
     // a string buffer.
     int countryCode = maybeExtractCountryCode(nationalNumber.toString(), countryMetadata,
-                                              normalizedNationalNumber);
+                                              normalizedNationalNumber, keepRawInput, phoneNumber);
     if (countryCode != 0) {
       String phoneNumberRegion = getRegionCodeForCountryCode(countryCode);
-      countryMetadata = getMetadataForRegion(phoneNumberRegion);
+      if (!phoneNumberRegion.equals(defaultCountry)) {
+        countryMetadata = getMetadataForRegion(phoneNumberRegion);
+      }
     } else {
       // If no extracted country code, use the region supplied instead. The national number is just
       // the normalized version of the number we were given to parse.
@@ -1574,6 +1705,9 @@
       normalizedNationalNumber.append(nationalNumber);
       if (defaultCountry != null) {
         countryCode = countryMetadata.getCountryCode();
+        phoneNumber.setCountryCode(countryCode);
+      } else if (keepRawInput) {
+        phoneNumber.clearCountryCodeSource();
       }
     }
     if (normalizedNationalNumber.length() < MIN_LENGTH_FOR_NSN) {
@@ -1588,11 +1722,6 @@
                                countryMetadata.getNationalPrefixTransformRule(),
                                validNumberPattern);
     }
-    phoneNumber.setCountryCode(countryCode);
-    if (isLeadingZeroCountry(countryCode) &&
-        normalizedNationalNumber.charAt(0) == '0') {
-      phoneNumber.setItalianLeadingZero(true);
-    }
     int lengthOfNationalNumber = normalizedNationalNumber.length();
     if (lengthOfNationalNumber < MIN_LENGTH_FOR_NSN) {
       throw new NumberParseException(NumberParseException.ErrorType.TOO_SHORT_NSN,
@@ -1604,6 +1733,10 @@
                                      "The string supplied is too long to be a "
                                      + "phone number.");
     }
+    if (isLeadingZeroCountry(countryCode) &&
+        normalizedNationalNumber.charAt(0) == '0') {
+      phoneNumber.setItalianLeadingZero(true);
+    }
     phoneNumber.setNationalNumber(Long.parseLong(normalizedNationalNumber.toString()));
     return phoneNumber.build();
   }
@@ -1634,10 +1767,12 @@
     firstNumber.mergeFrom(firstNumberIn);
     PhoneNumber.Builder secondNumber = PhoneNumber.newBuilder();
     secondNumber.mergeFrom(secondNumberIn);
-    // First clear raw_input field and any empty-string extensions so that we can use the
-    // proto-buffer equality method.
+    // First clear raw_input and country_code_source field and any empty-string extensions so that
+    // we can use the proto-buffer equality method.
     firstNumber.clearRawInput();
+    firstNumber.clearCountryCodeSource();
     secondNumber.clearRawInput();
+    secondNumber.clearCountryCodeSource();
     if (firstNumber.hasExtension() &&
         firstNumber.getExtension().equals("")) {
         firstNumber.clearExtension();
diff --git a/java/src/com/google/i18n/phonenumbers/Phonenumber.java b/java/src/com/google/i18n/phonenumbers/Phonenumber.java
index 8ff7833..aa79615 100644
--- a/java/src/com/google/i18n/phonenumbers/Phonenumber.java
+++ b/java/src/com/google/i18n/phonenumbers/Phonenumber.java
@@ -25,6 +25,49 @@
       return defaultInstance;
     }
     
+    public enum CountryCodeSource
+        implements com.google.protobuf.Internal.EnumLite {
+      FROM_NUMBER_WITH_PLUS_SIGN(0, 1),
+      FROM_NUMBER_WITH_IDD(1, 5),
+      FROM_NUMBER_WITHOUT_PLUS_SIGN(2, 10),
+      FROM_DEFAULT_COUNTRY(3, 20),
+      ;
+
+
+      public final int getNumber() { return value; }
+
+      public static CountryCodeSource valueOf(int value) {
+        switch (value) {
+          case 1: return FROM_NUMBER_WITH_PLUS_SIGN;
+          case 5: return FROM_NUMBER_WITH_IDD;
+          case 10: return FROM_NUMBER_WITHOUT_PLUS_SIGN;
+          case 20: return FROM_DEFAULT_COUNTRY;
+          default: return null;
+        }
+      }
+
+      public static com.google.protobuf.Internal.EnumLiteMap<CountryCodeSource>
+          internalGetValueMap() {
+        return internalValueMap;
+      }
+      private static com.google.protobuf.Internal.EnumLiteMap<CountryCodeSource>
+          internalValueMap =
+            new com.google.protobuf.Internal.EnumLiteMap<CountryCodeSource>() {
+              public CountryCodeSource findValueByNumber(int number) {
+                return CountryCodeSource.valueOf(number)
+      ;        }
+            };
+
+      private final int index;
+      private final int value;
+      private CountryCodeSource(int index, int value) {
+        this.index = index;
+        this.value = value;
+      }
+
+      // @@protoc_insertion_point(enum_scope:i18n.phonenumbers.PhoneNumber.CountryCodeSource)
+    }
+
     // required int32 country_code = 1;
     public static final int COUNTRY_CODE_FIELD_NUMBER = 1;
     private boolean hasCountryCode;
@@ -60,7 +103,15 @@
     public boolean hasRawInput() { return hasRawInput; }
     public java.lang.String getRawInput() { return rawInput_; }
 
+    // optional .i18n.phonenumbers.PhoneNumber.CountryCodeSource country_code_source = 6;
+    public static final int COUNTRY_CODE_SOURCE_FIELD_NUMBER = 6;
+    private boolean hasCountryCodeSource;
+    private com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource countryCodeSource_;
+    public boolean hasCountryCodeSource() { return hasCountryCodeSource; }
+    public com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource getCountryCodeSource() { return countryCodeSource_; }
+
     private void initFields() {
+      countryCodeSource_ = com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN;
     }
     public final boolean isInitialized() {
       if (!hasCountryCode) return false;
@@ -86,6 +137,9 @@
       if (hasRawInput()) {
         output.writeString(5, getRawInput());
       }
+      if (hasCountryCodeSource()) {
+        output.writeEnum(6, getCountryCodeSource().getNumber());
+      }
     }
     
     private int memoizedSerializedSize = -1;
@@ -114,6 +168,10 @@
         size += com.google.protobuf.CodedOutputStream
           .computeStringSize(5, getRawInput());
       }
+      if (hasCountryCodeSource()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(6, getCountryCodeSource().getNumber());
+      }
       memoizedSerializedSize = size;
       return size;
     }
@@ -273,6 +331,9 @@
         if (other.hasRawInput()) {
           setRawInput(other.getRawInput());
         }
+        if (other.hasCountryCodeSource()) {
+          setCountryCodeSource(other.getCountryCodeSource());
+        }
         return this;
       }
       
@@ -311,6 +372,14 @@
               setRawInput(input.readString());
               break;
             }
+            case 48: {
+              int rawValue = input.readEnum();
+              com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource value = com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource.valueOf(rawValue);
+              if (value != null) {
+                setCountryCodeSource(value);
+              }
+              break;
+            }
           }
         }
       }
@@ -412,6 +481,27 @@
         return this;
       }
 
+      // optional .i18n.phonenumbers.PhoneNumber.CountryCodeSource country_code_source = 6;
+      public boolean hasCountryCodeSource() {
+        return result.hasCountryCodeSource();
+      }
+      public com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource getCountryCodeSource() {
+        return result.getCountryCodeSource();
+      }
+      public Builder setCountryCodeSource(com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        result.hasCountryCodeSource = true;
+        result.countryCodeSource_ = value;
+        return this;
+      }
+      public Builder clearCountryCodeSource() {
+        result.hasCountryCodeSource = false;
+        result.countryCodeSource_ = com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN;
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:i18n.phonenumbers.PhoneNumber)
     }
     
diff --git a/java/src/com/google/i18n/phonenumbers/phonemetadata.proto b/java/src/com/google/i18n/phonenumbers/phonemetadata.proto
index 3e744e3..44f9764 100644
--- a/java/src/com/google/i18n/phonenumbers/phonemetadata.proto
+++ b/java/src/com/google/i18n/phonenumbers/phonemetadata.proto
@@ -51,9 +51,18 @@
   // This field specifies how the national prefix ($NP) together with the first
   // group ($FG) in the national significant number should be formatted in
   // the NATIONAL format when a national prefix exists for a certain country.
-  // When present, it overrides the national_prefix_formatting_rule specified
-  // in PhoneNumberDesc. See the comment in PhoneNumberDesc for more information
-  // on how this rule is specified.
+  // For example, when this field contains "($NP$FG)", a number from Beijing,
+  // China (whose $NP = 0), which would by default be formatted without
+  // national prefix as 10 1234 5678 in NATIONAL format, will instead be
+  // formatted as (010) 1234 5678; to format it as (0)10 1234 5678, the field
+  // would contain "($NP)$FG". Note $FG should always be present in this field,
+  // but $NP can be omitted. For example, having "$FG" could indicate the
+  // number should be formatted in NATIONAL format without the national prefix.
+  // This is commonly used to override the rule from generalDesc.
+  //
+  // When this field is missing, a number will be formatted without national
+  // prefix in NATIONAL format. This field does not affect how a number
+  // is formatted in other formats, such as INTERNATIONAL.
   optional string national_prefix_formatting_rule = 4;
 }
 
@@ -184,24 +193,7 @@
   // 15 (inserted after the area code of 343) is used.
   repeated NumberFormat intl_number_format = 20;
 
-  // This field specifies how the national prefix ($NP) together with the first
-  // group ($FG) in the national significant number should be formatted in
-  // the NATIONAL format when a national prefix exists for a certain country.
-  // For example, when this field contains "($NP$FG)", a number from Beijing,
-  // China (whose $NP = 0), which would by default be formatted without
-  // national prefix as 10 1234 5678 in NATIONAL format, will instead be
-  // formatted as (010) 1234 5678; to format it as (0)10 1234 5678, the field
-  // would contain "($NP)$FG". Note $FG should always be present in this field,
-  // but $NP can be omitted. For example, having "$FG" could indicate the
-  // number should be formatted in NATIONAL format without the national prefix.
-  // This is commonly used to override the rule from generalDesc.
-  //
-  // When this field is missing, a number will be formatted without national
-  // prefix in NATIONAL format. This field does not affect how a number
-  // is formatted in other formats, such as INTERNATIONAL.
-  //
-  // This field applies to all numberFormats unless overridden by the
-  // national_prefix_formatting_rule in a specific numberFormat.
+  // Deprecated.
   optional string national_prefix_formatting_rule = 21;
 }
 
diff --git a/java/src/com/google/i18n/phonenumbers/phonenumber.proto b/java/src/com/google/i18n/phonenumbers/phonenumber.proto
index 27b5996..1628cc3 100644
--- a/java/src/com/google/i18n/phonenumbers/phonenumber.proto
+++ b/java/src/com/google/i18n/phonenumbers/phonenumber.proto
@@ -55,6 +55,31 @@
 // canonicalized by the library. For example, it could be used to store alphanumerical numbers
 // such as "1-800-GOOG-411".
   optional string raw_input = 5;
+
+// The source from which the country_code is derived. This is not set in the general parsing method,
+// but in the method that parses and keeps raw_input. New fields could be added upon request.
+  enum CountryCodeSource {
+    // The country_code is derived based on a phone number with a leading "+", e.g. the French
+    // number "+33 (0)1 42 68 53 00".
+    FROM_NUMBER_WITH_PLUS_SIGN = 1;
+
+    // The country_code is derived based on a phone number with a leading IDD, e.g. the French
+    // number "011 33 (0)1 42 68 53 00", as it is dialled from US.
+    FROM_NUMBER_WITH_IDD = 5;
+
+    // The country_code is derived based on a phone number without a leading "+", e.g. the French
+    // number "33 (0)1 42 68 53 00" when defaultCountry is supplied as France.
+    FROM_NUMBER_WITHOUT_PLUS_SIGN = 10;
+
+    // The country_code is derived NOT based on the phone number itself, but from the defaultCountry
+    // parameter provided in the parsing function by the clients. This happens mostly for numbers
+    // written in the national format (without country code). For example, this would be set when
+    // parsing the French number "(0)1 42 68 53 00", when defaultCountry is supplied as France.
+    FROM_DEFAULT_COUNTRY = 20;
+  }
+
+// The source from which the country_code is derived.
+  optional CountryCodeSource country_code_source = 6;
 }
 
 // Examples
diff --git a/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java b/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
index d464cd2..f8758bc 100644
--- a/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
+++ b/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
@@ -196,7 +196,7 @@
   }
 
   public void testAsYouTypeFormatterGBTollFree() {
-    AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("GB");
+    AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("gb");
     assertEquals("0", formatter.inputDigit('0'));
     assertEquals("08", formatter.inputDigit('8'));
     assertEquals("080", formatter.inputDigit('0'));
@@ -282,4 +282,94 @@
     assertEquals("+54 9 11 2312 123\u2008", formatter.inputDigit('3'));
     assertEquals("+54 9 11 2312 1234", formatter.inputDigit('4'));
   }
+
+  public void testAsYouTypeFormatterKR() {
+    // +82 51 234 5678
+    AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("KR");
+    assertEquals("+", formatter.inputDigit('+'));
+    assertEquals("+8", formatter.inputDigit('8'));
+    assertEquals("+82", formatter.inputDigit('2'));
+    assertEquals("+825", formatter.inputDigit('5'));
+    assertEquals("+8251", formatter.inputDigit('1'));
+    assertEquals("+82 512", formatter.inputDigit('2'));
+    assertEquals("+82 51-23\u2008-\u2008\u2008\u2008\u2008", formatter.inputDigit('3'));
+    assertEquals("+82 51-234-\u2008\u2008\u2008\u2008", formatter.inputDigit('4'));
+    assertEquals("+82 51-234-5\u2008\u2008\u2008", formatter.inputDigit('5'));
+    assertEquals("+82 51-234-56\u2008\u2008", formatter.inputDigit('6'));
+    assertEquals("+82 51-234-567\u2008", formatter.inputDigit('7'));
+    assertEquals("+82 51-234-5678", formatter.inputDigit('8'));
+
+    // +82 2 531 5678
+    formatter.clear();
+    assertEquals("+", formatter.inputDigit('+'));
+    assertEquals("+8", formatter.inputDigit('8'));
+    assertEquals("+82", formatter.inputDigit('2'));
+    assertEquals("+822", formatter.inputDigit('2'));
+    assertEquals("+8225", formatter.inputDigit('5'));
+    assertEquals("+82 253", formatter.inputDigit('3'));
+    assertEquals("+82 2-531-\u2008\u2008\u2008\u2008", formatter.inputDigit('1'));
+    assertEquals("+82 2-531-5\u2008\u2008\u2008", formatter.inputDigit('5'));
+    assertEquals("+82 2-531-56\u2008\u2008", formatter.inputDigit('6'));
+    assertEquals("+82 2-531-567\u2008", formatter.inputDigit('7'));
+    assertEquals("+82 2-531-5678", formatter.inputDigit('8'));
+
+    // +82 2 3665 5678
+    formatter.clear();
+    assertEquals("+", formatter.inputDigit('+'));
+    assertEquals("+8", formatter.inputDigit('8'));
+    assertEquals("+82", formatter.inputDigit('2'));
+    assertEquals("+822", formatter.inputDigit('2'));
+    assertEquals("+8223", formatter.inputDigit('3'));
+    assertEquals("+82 236", formatter.inputDigit('6'));
+    assertEquals("+82 2-366\u2008-\u2008\u2008\u2008\u2008", formatter.inputDigit('6'));
+    assertEquals("+82 2-3665-\u2008\u2008\u2008\u2008", formatter.inputDigit('5'));
+    assertEquals("+82 2-3665-5\u2008\u2008\u2008", formatter.inputDigit('5'));
+    assertEquals("+82 2-3665-56\u2008\u2008", formatter.inputDigit('6'));
+    assertEquals("+82 2-3665-567\u2008", formatter.inputDigit('7'));
+    assertEquals("+82 2-3665-5678", formatter.inputDigit('8'));
+
+    // 02-114 : This is too short to format. Checking that there are no side-effects.
+    formatter.clear();
+    assertEquals("0", formatter.inputDigit('0'));
+    assertEquals("02", formatter.inputDigit('2'));
+    assertEquals("021", formatter.inputDigit('1'));
+    assertEquals("0211", formatter.inputDigit('1'));
+    assertEquals("02114", formatter.inputDigit('4'));
+
+    // 02-1300
+    formatter.clear();
+    assertEquals("0", formatter.inputDigit('0'));
+    assertEquals("02", formatter.inputDigit('2'));
+    assertEquals("021", formatter.inputDigit('1'));
+    assertEquals("0213", formatter.inputDigit('3'));
+    assertEquals("02130", formatter.inputDigit('0'));
+    assertEquals("02-1300", formatter.inputDigit('0'));
+
+    // 011-456-7890
+    formatter.clear();
+    assertEquals("0", formatter.inputDigit('0'));
+    assertEquals("01", formatter.inputDigit('1'));
+    assertEquals("011", formatter.inputDigit('1'));
+    assertEquals("0114", formatter.inputDigit('4'));
+    assertEquals("01145", formatter.inputDigit('5'));
+    assertEquals("011-456-\u2008\u2008\u2008\u2008", formatter.inputDigit('6'));
+    assertEquals("011-456-7\u2008\u2008\u2008", formatter.inputDigit('7'));
+    assertEquals("011-456-78\u2008\u2008", formatter.inputDigit('8'));
+    assertEquals("011-456-789\u2008", formatter.inputDigit('9'));
+    assertEquals("011-456-7890", formatter.inputDigit('0'));
+
+    // 011-9876-7890
+    formatter.clear();
+    assertEquals("0", formatter.inputDigit('0'));
+    assertEquals("01", formatter.inputDigit('1'));
+    assertEquals("011", formatter.inputDigit('1'));
+    assertEquals("0119", formatter.inputDigit('9'));
+    assertEquals("01198", formatter.inputDigit('8'));
+    assertEquals("011-987\u2008-\u2008\u2008\u2008\u2008", formatter.inputDigit('7'));
+    assertEquals("011-9876-\u2008\u2008\u2008\u2008", formatter.inputDigit('6'));
+    assertEquals("011-9876-7\u2008\u2008\u2008", formatter.inputDigit('7'));
+    assertEquals("011-9876-78\u2008\u2008", formatter.inputDigit('8'));
+    assertEquals("011-9876-789\u2008", formatter.inputDigit('9'));
+    assertEquals("011-9876-7890", formatter.inputDigit('0'));
+  }
 }
diff --git a/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java b/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
index 746a3ed..44b57c8 100644
--- a/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
+++ b/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
@@ -19,6 +19,7 @@
 import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat;
 import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
 import com.google.protobuf.MessageLite;
 import junit.framework.TestCase;
 
@@ -119,10 +120,70 @@
     assertEquals("$1 $2 $3 $4", metadata.getIntlNumberFormat(3).getFormat());
   }
 
+  public void testGetLengthOfGeographicalAreaCode() {
+    // Google MTV, which has area code "650".
+    PhoneNumber usNumber1 =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(6502530000L).build();
+    assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(usNumber1));
+
+    // A North America toll-free number, which has no area code.
+    PhoneNumber usNumber2 =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(8002530000L).build();
+    assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(usNumber2));
+
+    // An invalid US number (1 digit shorter), which has no area code.
+    PhoneNumber usNumber3 =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(650253000L).build();
+    assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(usNumber3));
+
+    // Google London, which has area code "20".
+    PhoneNumber ukNumber1 =
+        PhoneNumber.newBuilder().setCountryCode(44).setNationalNumber(2070313000L).build();
+    assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(ukNumber1));
+
+    // A UK mobile phone, which has no area code.
+    PhoneNumber ukNumber2 =
+        PhoneNumber.newBuilder().setCountryCode(44).setNationalNumber(7123456789L).build();
+    assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(ukNumber2));
+
+    // Google Buenos Aires, which has area code "11".
+    PhoneNumber arNumber =
+        PhoneNumber.newBuilder().setCountryCode(54).setNationalNumber(1155303000L).build();
+    assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(arNumber));
+
+    // Google Sydney, which has area code "2".
+    PhoneNumber auNumber =
+        PhoneNumber.newBuilder().setCountryCode(61).setNationalNumber(293744000L).build();
+    assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(auNumber));
+
+    // Google Singapore. Singapore has no area code and no national prefix.
+    PhoneNumber sgNumber =
+        PhoneNumber.newBuilder().setCountryCode(65).setNationalNumber(65218000L).build();
+    assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(sgNumber));
+  }
+
+  public void testGetNationalSignificantNumber() {
+    PhoneNumber usNumber =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(6502530000L).build();
+    assertEquals("6502530000", PhoneNumberUtil.getNationalSignificantNumber(usNumber));
+
+    // An Italian mobile number.
+    PhoneNumber itNumber1 =
+        PhoneNumber.newBuilder().setCountryCode(39).setNationalNumber(312345678L).build();
+    assertEquals("312345678", PhoneNumberUtil.getNationalSignificantNumber(itNumber1));
+
+    // An Italian fixed line number.
+    PhoneNumber itNumber2 =
+        PhoneNumber.newBuilder().setCountryCode(39).setNationalNumber(236618300L)
+            .setItalianLeadingZero(true).build();
+    assertEquals("0236618300", PhoneNumberUtil.getNationalSignificantNumber(itNumber2));
+  }
+
   public void testGetExampleNumber() throws IOException {
     PhoneNumber deNumber =
         PhoneNumber.newBuilder().setCountryCode(49).setNationalNumber(30123456).build();
     assertEquals(deNumber, phoneUtil.getExampleNumber("DE"));
+    assertEquals(deNumber, phoneUtil.getExampleNumber("de"));
 
     assertEquals(deNumber,
                  phoneUtil.getExampleNumberForType("DE",
@@ -415,6 +476,8 @@
                  phoneUtil.formatOutOfCountryCallingNumber(arNumber2, "AU"));
     assertEquals("011 15 8765-4321 ext. 1234",
                  phoneUtil.formatOutOfCountryCallingNumber(arNumber2, "AR"));
+    assertEquals("011 15 8765-4321 ext. 1234",
+                 phoneUtil.formatOutOfCountryCallingNumber(arNumber2, "ar"));
   }
 
   public void testFormatOutOfCountryWithPreferredIntlPrefix() {
@@ -687,6 +750,7 @@
         PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(2423232345L).build();
     assertTrue(phoneUtil.isValidNumber(bsNumber1));
     assertTrue(phoneUtil.isValidNumberForRegion(bsNumber1, "BS"));
+    assertTrue(phoneUtil.isValidNumberForRegion(bsNumber1, "bs"));
     assertFalse(phoneUtil.isValidNumberForRegion(bsNumber1, "US"));
     PhoneNumber bsNumber2 =
         PhoneNumber.newBuilder(bsNumber1).setNationalNumber(2421232345L).build();
@@ -739,6 +803,7 @@
   public void testGetCountryCodeForRegion() {
     assertEquals(1, phoneUtil.getCountryCodeForRegion("US"));
     assertEquals(64, phoneUtil.getCountryCodeForRegion("NZ"));
+    assertEquals(64, phoneUtil.getCountryCodeForRegion("nz"));
     assertEquals(0, phoneUtil.getCountryCodeForRegion(null));
     assertEquals(0, phoneUtil.getCountryCodeForRegion("ZZ"));
     // CS is already deprecated so the library doesn't support it.
@@ -748,6 +813,7 @@
   public void testIsNANPACountry() {
     assertTrue(phoneUtil.isNANPACountry("US"));
     assertTrue(phoneUtil.isNANPACountry("BS"));
+    assertTrue(phoneUtil.isNANPACountry("bs"));
   }
 
   public void testIsPossibleNumber() {
@@ -771,6 +837,7 @@
     assertTrue(phoneUtil.isPossibleNumber("(020) 7031 3000", "GB"));
     assertTrue(phoneUtil.isPossibleNumber("7031 3000", "GB"));
     assertTrue(phoneUtil.isPossibleNumber("3331 6005", "NZ"));
+    assertTrue(phoneUtil.isPossibleNumber("3331 6005", "nz"));
   }
 
   public void testIsPossibleNumberWithReason() {
@@ -895,56 +962,67 @@
                  strippedNumber, numberToStrip.toString());
   }
 
-  public void testMaybeStripInternationalPrefix() {
+    public void testMaybeStripInternationalPrefix() {
     String internationalPrefix = "00[39]";
     StringBuffer numberToStrip = new StringBuffer("0034567700-3898003");
     // Note the dash is removed as part of the normalization.
     StringBuffer strippedNumber = new StringBuffer("45677003898003");
-    assertEquals(true, phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                                           internationalPrefix));
+    assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
+                 phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+                                                                     internationalPrefix));
     assertEquals("The number supplied was not stripped of its international prefix.",
                  strippedNumber.toString(), numberToStrip.toString());
-    // Now the number no longer starts with an IDD prefix, so it should now report false.
-    assertEquals(false, phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                                            internationalPrefix));
+    // Now the number no longer starts with an IDD prefix, so it should now report
+    // FROM_DEFAULT_COUNTRY.
+    assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
+                 phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+                                                                     internationalPrefix));
 
     numberToStrip = new StringBuffer("00945677003898003");
-    assertEquals(true, phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                                           internationalPrefix));
+    assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
+                 phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+                                                                     internationalPrefix));
     assertEquals("The number supplied was not stripped of its international prefix.",
                  strippedNumber.toString(), numberToStrip.toString());
     // Test it works when the international prefix is broken up by spaces.
     numberToStrip = new StringBuffer("00 9 45677003898003");
-    assertEquals(true, phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                                           internationalPrefix));
+    assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
+                 phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+                                                                     internationalPrefix));
     assertEquals("The number supplied was not stripped of its international prefix.",
                  strippedNumber.toString(), numberToStrip.toString());
-    // Now the number no longer starts with an IDD prefix, so it should now report false.
-    assertEquals(false, phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                                            internationalPrefix));
+    // Now the number no longer starts with an IDD prefix, so it should now report
+    // FROM_DEFAULT_COUNTRY.
+    assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
+                 phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+                                                                     internationalPrefix));
 
     // Test the + symbol is also recognised and stripped.
     numberToStrip = new StringBuffer("+45677003898003");
     strippedNumber = new StringBuffer("45677003898003");
-    assertEquals(true, phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                                           internationalPrefix));
+    assertEquals(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN,
+                 phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+                                                                     internationalPrefix));
     assertEquals("The number supplied was not stripped of the plus symbol.",
                  strippedNumber.toString(), numberToStrip.toString());
 
     // If the number afterwards is a zero, we should not strip this - no country code begins with 0.
     numberToStrip = new StringBuffer("0090112-3123");
     strippedNumber = new StringBuffer("00901123123");
-    assertEquals(false, phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                                            internationalPrefix));
+    assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
+                 phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+                                                                     internationalPrefix));
     assertEquals("The number supplied had a 0 after the match so shouldn't be stripped.",
                  strippedNumber.toString(), numberToStrip.toString());
     // Here the 0 is separated by a space from the IDD.
     numberToStrip = new StringBuffer("009 0-112-3123");
-    assertEquals(false, phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                                            internationalPrefix));
+    assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
+                 phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+                                                                     internationalPrefix));
   }
 
   public void testMaybeExtractCountryCode() {
+    PhoneNumber.Builder number = PhoneNumber.newBuilder();
     PhoneMetadata metadata = phoneUtil.getMetadataForRegion("US");
     // Note that for the US, the IDD is 011.
     try {
@@ -954,7 +1032,10 @@
       StringBuffer numberToFill = new StringBuffer();
       assertEquals("Did not extract country code " + countryCode + " correctly.",
                    countryCode,
-                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill));
+                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+                                                     number));
+      assertEquals("Did not figure out CountryCodeSource correctly",
+                   CountryCodeSource.FROM_NUMBER_WITH_IDD, number.getCountryCodeSource());
       // Should strip and normalize national significant number.
       assertEquals("Did not strip off the country code correctly.",
                    strippedNumber,
@@ -962,30 +1043,38 @@
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
+    number.clear();
     try {
       String phoneNumber = "+6423456789";
       int countryCode = 64;
       StringBuffer numberToFill = new StringBuffer();
       assertEquals("Did not extract country code " + countryCode + " correctly.",
                    countryCode,
-                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill));
+                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+                                                     number));
+      assertEquals("Did not figure out CountryCodeSource correctly",
+                   CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
+    number.clear();
     try {
       String phoneNumber = "2345-6789";
       StringBuffer numberToFill = new StringBuffer();
       assertEquals("Should not have extracted a country code - no international prefix present.",
                    0,
-                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill));
+                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+                                                     number));
+    assertEquals("Did not figure out CountryCodeSource correctly",
+                   CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
+    number.clear();
     try {
       String phoneNumber = "0119991123456789";
       StringBuffer numberToFill = new StringBuffer();
-      phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
-                                        numberToFill);
+      phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number);
       fail("Should have thrown an exception, no valid country code present.");
     } catch (NumberParseException e) {
       // Expected.
@@ -993,34 +1082,58 @@
                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
                    e.getErrorType());
     }
+    number.clear();
     try {
       String phoneNumber = "(1 610) 619 4466";
       int countryCode = 1;
       StringBuffer numberToFill = new StringBuffer();
       assertEquals("Should have extracted the country code of the region passed in",
                    countryCode,
-                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill));
+                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+                                                     number));
+      assertEquals("Did not figure out CountryCodeSource correctly",
+                   CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN,
+                   number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
+    number.clear();
+    try {
+      String phoneNumber = "(1 610) 619 4466";
+      int countryCode = 1;
+      StringBuffer numberToFill = new StringBuffer();
+      assertEquals("Should have extracted the country code of the region passed in",
+                   countryCode,
+                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
+                                                     number));
+      assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
+    } catch (NumberParseException e) {
+      fail("Should not have thrown an exception: " + e.toString());
+    }
+    number.clear();
     try {
       String phoneNumber = "(1 610) 619 446";
       StringBuffer numberToFill = new StringBuffer();
       assertEquals("Should not have extracted a country code - invalid number after extraction " +
                    "of uncertain country code.",
                    0,
-                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill));
+                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
+                                                     number));
+      assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
+    number.clear();
     try {
       String phoneNumber = "(1 610) 619 43 446";
       StringBuffer numberToFill = new StringBuffer();
       assertEquals("Should not have extracted a country code - invalid number both before and " +
                    "after extraction of uncertain country code.",
                    0,
-                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
-                                                     numberToFill));
+                   phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+                                                     number));
+      assertEquals("Did not figure out CountryCodeSource correctly",
+                   CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
@@ -1032,10 +1145,36 @@
 
     // National prefix attached.
     assertEquals(nzNumber, phoneUtil.parse("033316005", "NZ"));
+    assertEquals(nzNumber, phoneUtil.parse("033316005", "nz"));
     assertEquals(nzNumber, phoneUtil.parse("33316005", "NZ"));
     // National prefix attached and some formatting present.
     assertEquals(nzNumber, phoneUtil.parse("03-331 6005", "NZ"));
     assertEquals(nzNumber, phoneUtil.parse("03 331 6005", "NZ"));
+
+    // Testing international prefixes.
+    // Should strip country code.
+    assertEquals(nzNumber, phoneUtil.parse("0064 3 331 6005", "NZ"));
+    // Try again, but this time we have an international number with Region Code US. It should
+    // recognise the country code and parse accordingly.
+    assertEquals(nzNumber, phoneUtil.parse("01164 3 331 6005", "US"));
+    assertEquals(nzNumber, phoneUtil.parse("+64 3 331 6005", "US"));
+
+    PhoneNumber nzNumber2 =
+        PhoneNumber.newBuilder().setCountryCode(64).setNationalNumber(64123456L).build();
+    assertEquals(nzNumber2, phoneUtil.parse("64(0)64123456", "NZ"));
+    // Check that using a "/" is fine in a phone number.
+    PhoneNumber deNumber =
+        PhoneNumber.newBuilder().setCountryCode(49).setNationalNumber(12345678L).build();
+    assertEquals(deNumber, phoneUtil.parse("123/45678", "DE"));
+
+    // Check it doesn't use the '1' as a country code when parsing if the phone number was already
+    // possible.
+    PhoneNumber usNumber =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(1234567890L).build();
+    assertEquals(usNumber, phoneUtil.parse("123-456-7890", "US"));
+  }
+
+   public void testParseNumberWithAlphaCharacters() throws Exception {
     // Test case with alpha characters.
     PhoneNumber tollfreeNumber =
         PhoneNumber.newBuilder().setCountryCode(64).setNationalNumber(800332005L).build();
@@ -1048,20 +1187,9 @@
     assertEquals(premiumNumber, phoneUtil.parse("0900 332 600a5", "NZ"));
     assertEquals(premiumNumber, phoneUtil.parse("0900 332 600A5", "NZ"));
     assertEquals(premiumNumber, phoneUtil.parse("0900 a332 600A5", "NZ"));
+  }
 
-    // Testing international prefixes.
-    // Should strip country code.
-    assertEquals(nzNumber, phoneUtil.parse("0064 3 331 6005", "NZ"));
-    // Try again, but this time we have an international number with Region Code US. It should
-    // recognise the country code and parse accordingly.
-    assertEquals(nzNumber, phoneUtil.parse("01164 3 331 6005", "US"));
-    assertEquals(nzNumber, phoneUtil.parse("+64 3 331 6005", "US"));
-
-    // Test for http://b/issue?id=2247493
-    PhoneNumber nzNumber2 =
-        PhoneNumber.newBuilder().setCountryCode(64).setNationalNumber(64123456L).build();
-    assertEquals(nzNumber2, phoneUtil.parse("64(0)64123456", "NZ"));
-
+  public void testParseWithInternationalPrefixes() throws Exception {
     PhoneNumber usNumber =
         PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(6503336000L).build();
     assertEquals(usNumber, phoneUtil.parse("+1 (650) 333-6000", "NZ"));
@@ -1075,12 +1203,9 @@
     assertEquals(usNumber, phoneUtil.parse("0191-650-333-6000", "SG"));
     // Calling the US number from Poland
     assertEquals(usNumber, phoneUtil.parse("0~01-650-333-6000", "PL"));
-    // Check it doesn't use the '1' as a country code when parsing if the phone number was already
-    // possible.
-    PhoneNumber usNumber2 =
-        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(1234567890L).build();
-    assertEquals(usNumber2, phoneUtil.parse("123-456-7890", "US"));
+  }
 
+  public void testParseWithLeadingZero() throws Exception {
     PhoneNumber itNumber =
         PhoneNumber.newBuilder().setCountryCode(39).setNationalNumber(236618300L)
             .setItalianLeadingZero(true).build();
@@ -1090,12 +1215,9 @@
     PhoneNumber itNumber2 =
         PhoneNumber.newBuilder().setCountryCode(39).setNationalNumber(312345678L).build();
     assertEquals(itNumber2, phoneUtil.parse("312 345 678", "IT"));
+  }
 
-    // Check that using a "/" is fine in a phone number.
-    PhoneNumber deNumber =
-        PhoneNumber.newBuilder().setCountryCode(49).setNationalNumber(12345678L).build();
-    assertEquals(deNumber, phoneUtil.parse("123/45678", "DE"));
-
+  public void testParseNationalNumberArgentina() throws Exception {
     // Test parsing mobile numbers of Argentina.
     PhoneNumber arNumber =
         PhoneNumber.newBuilder().setCountryCode(54).setNationalNumber(93435551212L).build();
@@ -1122,7 +1244,9 @@
         PhoneNumber.newBuilder().setCountryCode(54).setNationalNumber(2312340000L).build();
     assertEquals(arNumber5, phoneUtil.parse("+54 23 1234 0000", "AR"));
     assertEquals(arNumber5, phoneUtil.parse("023 1234 0000", "AR"));
+  }
 
+  public void testParseWithXInNumber() throws Exception {
     // Test that having an 'x' in the phone number at the start is ok and that it just gets removed.
     PhoneNumber arNumber6 =
         PhoneNumber.newBuilder().setCountryCode(54).setNationalNumber(123456789L).build();
@@ -1137,7 +1261,9 @@
     // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
     // code is written in the form of xx have a national significant number of length larger than 7.
     assertEquals(arFromUs, phoneUtil.parse("011xx5481429712", "US"));
+  }
 
+  public void testParseNumbersMexico() throws Exception {
     // Test parsing fixed-line numbers of Mexico.
     PhoneNumber mxNumber =
         PhoneNumber.newBuilder().setCountryCode(52).setNationalNumber(4499780001L).build();
@@ -1151,24 +1277,6 @@
     assertEquals(mxNumber2, phoneUtil.parse("+52 1 33 1234-5678", "MX"));
     assertEquals(mxNumber2, phoneUtil.parse("044 (33) 1234-5678", "MX"));
     assertEquals(mxNumber2, phoneUtil.parse("045 33 1234-5678", "MX"));
-
-    // Test that if a number has two extensions specified, we ignore the second.
-    PhoneNumber usWithTwoExtensionsNumber =
-        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(2121231234L)
-            .setExtension("508").build();
-    assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/x1234",
-                                                            "US"));
-    assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/ x1234",
-                                                            "US"));
-    assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508\\x1234",
-                                                            "US"));
-
-    // Test parsing numbers in the form (645) 123-1234-910# works, where the last 3 digits before
-    // the # are an extension.
-    PhoneNumber usWithExtension =
-        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(6451231234L)
-            .setExtension("910").build();
-    assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234-910#", "US"));
   }
 
   public void testFailedParseOnInvalidNumbers() {
@@ -1317,24 +1425,64 @@
                  phoneUtil.parse("(800) 901-3355 ,extension 7246433", "US"));
     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , 7246433", "US"));
     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 ext: 7246433", "US"));
+
+    // Test that if a number has two extensions specified, we ignore the second.
+    PhoneNumber usWithTwoExtensionsNumber =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(2121231234L)
+            .setExtension("508").build();
+    assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/x1234",
+                                                            "US"));
+    assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/ x1234",
+                                                            "US"));
+    assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508\\x1234",
+                                                            "US"));
+
+    // Test parsing numbers in the form (645) 123-1234-910# works, where the last 3 digits before
+    // the # are an extension.
+    PhoneNumber usWithExtension2 =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(6451231234L)
+            .setExtension("910").build();
+    assertEquals(usWithExtension2, phoneUtil.parse("+1 (645) 123 1234-910#", "US"));
   }
 
   public void testParseAndKeepRaw() throws Exception {
-    PhoneNumber alphaNumericNumber =
+    PhoneNumber alphaNumericNumber1 =
         PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(180074935247L)
-            .setRawInput("1800 six-flags").build();
-    assertEquals(alphaNumericNumber,
+            .setRawInput("1800 six-flags")
+            .setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).build();
+    assertEquals(alphaNumericNumber1,
                  phoneUtil.parseAndKeepRawInput("1800 six-flags", "US"));
+
+    PhoneNumber alphaNumericNumber2 =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(8007493524L)
+            .setRawInput("1800 six-flag")
+            .setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN).build();
+    assertEquals(alphaNumericNumber2,
+                 phoneUtil.parseAndKeepRawInput("1800 six-flag", "US"));
+
+    PhoneNumber alphaNumericNumber3 =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(8007493524L)
+            .setRawInput("+1800 six-flag")
+            .setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN).build();
+    assertEquals(alphaNumericNumber3,
+                 phoneUtil.parseAndKeepRawInput("+1800 six-flag", "CN"));
+
+    PhoneNumber alphaNumericNumber4 =
+        PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(18007493524L)
+            .setRawInput("1800 six-flag")
+            .setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_IDD).build();
+    assertEquals(alphaNumericNumber4,
+                 phoneUtil.parseAndKeepRawInput("001800 six-flag", "NZ"));
   }
 
   public void testCountryWithNoNumberDesc() {
-    // Andorra is a country where we don't have PhoneNumberDesc info in the meta data.
+    // Andorra is a country where we don't have PhoneNumberDesc info in the metadata.
     PhoneNumber adNumber =
         PhoneNumber.newBuilder().setCountryCode(376).setNationalNumber(12345L).build();
     assertEquals("+376 12345", phoneUtil.format(adNumber,
                                                 PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL));
     assertEquals("+37612345", phoneUtil.format(adNumber,
-                                                PhoneNumberUtil.PhoneNumberFormat.E164));
+                                               PhoneNumberUtil.PhoneNumberFormat.E164));
     assertEquals("12345", phoneUtil.format(adNumber,
                                            PhoneNumberUtil.PhoneNumberFormat.NATIONAL));
     assertEquals(PhoneNumberUtil.PhoneNumberType.UNKNOWN,