Commits

Patrick Mézard  committed a1588f4 Merge

Merge with r468

  • Participants
  • Parent commits a2fb75d, 280edd5

Comments (0)

Files changed (51)

File csharp/PhoneNumbers.Test/CountryCodeToRegionCodeMapForTesting.cs

         // indicated with "isMainCountryForCode" in the metadata should be first.
         internal static Dictionary<int, List<String>> GetCountryCodeToRegionCodeMap()
         {
-            // The capacity is set to 22 as there are 17 different country codes,
+            // The capacity is set to 24 as there are 18 different country codes,
             // and this offers a load factor of roughly 0.75.
-            var countryCodeToRegionCodeMap = new Dictionary<int, List<String>>(22);
+            var countryCodeToRegionCodeMap = new Dictionary<int, List<String>>(24);
 
             List<String> listWithRegionCode;
             listWithRegionCode = new List<String>(2);
             listWithRegionCode.Add("001");
             countryCodeToRegionCodeMap[800] = listWithRegionCode;
 
+            listWithRegionCode = new List<String>(1);
+            listWithRegionCode.Add("001");
+            countryCodeToRegionCodeMap[979] = listWithRegionCode;
+
             return countryCodeToRegionCodeMap;
         }
     }

File csharp/PhoneNumbers.Test/TestExampleNumbers.cs

         [Test]
         public void TestEmergency()
         {
+            ShortNumberUtil shortUtil = new ShortNumberUtil(phoneNumberUtil);
             int wrongTypeCounter = 0;
             foreach(var regionCode in phoneNumberUtil.GetSupportedRegions())
             {
                 {
                     String exampleNumber = desc.ExampleNumber;
                     if (!new PhoneRegex(desc.PossibleNumberPattern).MatchAll(exampleNumber).Success ||
-                        !new PhoneRegex(desc.NationalNumberPattern).MatchAll(exampleNumber).Success)
+                        !shortUtil.IsEmergencyNumber(exampleNumber, regionCode))
                     {
                         wrongTypeCounter++;
                     // LOGGER.log(Level.SEVERE, "Emergency example number test failed for " + regionCode);

File csharp/PhoneNumbers.Test/TestPhoneNumberUtil.cs

                 .SetRawInput("000-000-0000").Build();
         private static readonly PhoneNumber INTERNATIONAL_TOLL_FREE =
             new PhoneNumber.Builder().SetCountryCode(800).SetNationalNumber(12345678L).Build();
+        // We set this to be the same length as numbers for the other non-geographical country prefix that
+        // we have in our test metadata. However, this is not considered valid because they differ in
+        // their country calling code.
         private static readonly PhoneNumber INTERNATIONAL_TOLL_FREE_TOO_LONG =
             new PhoneNumber.Builder().SetCountryCode(800).SetNationalNumber(1234567890L).Build();
+        private static readonly PhoneNumber UNIVERSAL_PREMIUM_RATE =
+            new PhoneNumber.Builder().SetCountryCode(979).SetNationalNumber(123456789L).Build();
+
 
         private static PhoneNumber.Builder Update(PhoneNumber p)
         {
         public void TestGetExampleNumberForNonGeoEntity()
         {
             Assert.AreEqual(INTERNATIONAL_TOLL_FREE, phoneUtil.GetExampleNumberForNonGeoEntity(800));
+            Assert.AreEqual(UNIVERSAL_PREMIUM_RATE, phoneUtil.GetExampleNumberForNonGeoEntity(979));
         }
 
         [Test]
         [Test]
         public void TestNormaliseRemovePunctuation()
         {
-            String inputNumber = "034-56&+#234";
+            String inputNumber = "034-56&+#2\u00AD34";
             String expectedOutput = "03456234";
             Assert.AreEqual(expectedOutput,
                 PhoneNumberUtil.Normalize(inputNumber),
             phoneUtil.ParseAndKeepRawInput("0011 16502530000", RegionCode.AU);
             Assert.AreEqual("0011 1 650 253 0000",
             phoneUtil.FormatInOriginalFormat(outOfCountryNumberFromAU2, RegionCode.AU));
+
+            // Test the star sign is not removed from or added to the original input by this method.
+            PhoneNumber starNumber = phoneUtil.ParseAndKeepRawInput("*1234", RegionCode.JP);
+            Assert.AreEqual("*1234", phoneUtil.FormatInOriginalFormat(starNumber, RegionCode.JP));
+            PhoneNumber numberWithoutStar = phoneUtil.ParseAndKeepRawInput("1234", RegionCode.JP);
+            Assert.AreEqual("1234", phoneUtil.FormatInOriginalFormat(numberWithoutStar, RegionCode.JP));
         }
 
         [Test]
             premiumRateNumber = Update(premiumRateNumber).SetCountryCode(49).SetNationalNumber(90091234567L).Build();
             Assert.AreEqual(PhoneNumberType.PREMIUM_RATE,
                 phoneUtil.GetNumberType(premiumRateNumber));
+
+            Assert.AreEqual(PhoneNumberType.PREMIUM_RATE,
+                 phoneUtil.GetNumberType(UNIVERSAL_PREMIUM_RATE));
         }
 
         [Test]
             Assert.That(phoneUtil.IsValidNumber(IT_NUMBER));
             Assert.That(phoneUtil.IsValidNumber(GB_MOBILE));
             Assert.That(phoneUtil.IsValidNumber(INTERNATIONAL_TOLL_FREE));
+            Assert.That(phoneUtil.IsValidNumber(UNIVERSAL_PREMIUM_RATE));
 
             PhoneNumber nzNumber = new PhoneNumber.Builder().SetCountryCode(64).SetNationalNumber(21387835L).Build();
             Assert.That(phoneUtil.IsValidNumber(nzNumber));
             Assert.AreEqual(RegionCode.GB, phoneUtil.GetRegionCodeForCountryCode(44));
             Assert.AreEqual(RegionCode.DE, phoneUtil.GetRegionCodeForCountryCode(49));
             Assert.AreEqual(RegionCode.UN001, phoneUtil.GetRegionCodeForCountryCode(800));
+            Assert.AreEqual(RegionCode.UN001, phoneUtil.GetRegionCodeForCountryCode(979));
         }
 
         [Test]
             Assert.AreEqual(RegionCode.US, phoneUtil.GetRegionCodeForNumber(US_NUMBER));
             Assert.AreEqual(RegionCode.GB, phoneUtil.GetRegionCodeForNumber(GB_MOBILE));
             Assert.AreEqual(RegionCode.UN001, phoneUtil.GetRegionCodeForNumber(INTERNATIONAL_TOLL_FREE));
+            Assert.AreEqual(RegionCode.UN001, phoneUtil.GetRegionCodeForNumber(UNIVERSAL_PREMIUM_RATE));
         }
 
         [Test]
             // Try with number that we don't have metadata for.
             var adNumber = new PhoneNumber.Builder().SetCountryCode(376).SetNationalNumber(12345L).Build();
             Assert.AreEqual(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
-            phoneUtil.IsPossibleNumberWithReason(adNumber));
-            adNumber = Update(adNumber).SetCountryCode(376).SetNationalNumber(13L).Build();
+                phoneUtil.IsPossibleNumberWithReason(adNumber));
+            adNumber = Update(adNumber).SetCountryCode(376).SetNationalNumber(1L).Build();
             Assert.AreEqual(PhoneNumberUtil.ValidationResult.TOO_SHORT,
-            phoneUtil.IsPossibleNumberWithReason(adNumber));
+                phoneUtil.IsPossibleNumberWithReason(adNumber));
             adNumber = Update(adNumber).SetCountryCode(376).SetNationalNumber(12345678901234567L).Build();
             Assert.AreEqual(PhoneNumberUtil.ValidationResult.TOO_LONG,
-            phoneUtil.IsPossibleNumberWithReason(adNumber));
+                phoneUtil.IsPossibleNumberWithReason(adNumber));
         }
 
         [Test]
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("tel:331-6005;phone-context=+64-3", RegionCode.NZ));
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("tel:331-6005;phone-context=+64-3", RegionCode.US));
 
+            // Test parsing RFC3966 format with optional user-defined parameters. The parameters will appear
+            // after the context if present.
+            Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("tel:03-331-6005;phone-context=+64;a=%A1",
+                RegionCode.NZ));
+            // Test parsing RFC3966 with an ISDN subaddress.
+            Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("tel:03-331-6005;isub=12345;phone-context=+64",
+                RegionCode.NZ));
+            Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("tel:+64-3-331-6005;isub=12345", RegionCode.NZ));
+
             // Testing international prefixes.
             // Should strip country calling code.
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("0064 3 331 6005", RegionCode.NZ));
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("+0064 3 331 6005", RegionCode.NZ));
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("+ 00 64 3 331 6005", RegionCode.NZ));
 
+            Assert.AreEqual(US_LOCAL_NUMBER,
+                phoneUtil.Parse("tel:253-0000;phone-context=www.google.com", RegionCode.US));
+            Assert.AreEqual(US_LOCAL_NUMBER,
+                phoneUtil.Parse("tel:253-0000;isub=12345;phone-context=www.google.com", RegionCode.US));
+            // This is invalid because no "+" sign is present as part of phone-context. The phone context
+            // is simply ignored in this case just as if it contains a domain.
+            Assert.AreEqual(US_LOCAL_NUMBER,
+                phoneUtil.Parse("tel:2530000;isub=12345;phone-context=1-650", RegionCode.US));
+            Assert.AreEqual(US_LOCAL_NUMBER,
+                phoneUtil.Parse("tel:2530000;isub=12345;phone-context=1234.com", RegionCode.US));
+
             PhoneNumber nzNumber = new PhoneNumber.Builder()
                 .SetCountryCode(64).SetNationalNumber(64123456L).Build();
             Assert.AreEqual(nzNumber, phoneUtil.Parse("64(0)64123456", RegionCode.NZ));
         {
             // Using a full-width plus sign.
             Assert.AreEqual(US_NUMBER, phoneUtil.Parse("\uFF0B1 (650) 253-0000", RegionCode.SG));
+            // Using a soft hyphen U+00AD.
+            Assert.AreEqual(US_NUMBER, phoneUtil.Parse("1 (650) 253\u00AD-0000", RegionCode.US));
             // The whole number, including punctuation, is here represented in full-width form.
             Assert.AreEqual(US_NUMBER, phoneUtil.Parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
                                                 "\u3000\uFF12\uFF15\uFF13\uFF0D\uFF10\uFF10\uFF10" +
             }
             try
             {
-                String domainRfcPhoneContext = "tel:555-1234;phone-context:www.google.com";
-                phoneUtil.Parse(domainRfcPhoneContext, RegionCode.US);
-                Assert.Fail("Domain provided for phone context - should fail.");
+                String domainRfcPhoneContext = "tel:555-1234;phone-context=www.google.com";
+                phoneUtil.Parse(domainRfcPhoneContext, RegionCode.ZZ);
+                Assert.Fail("'Unknown' region code not allowed: should fail.");
             }
             catch (NumberParseException e)
             {
                 // Expected this exception.
-                Assert.AreEqual(ErrorType.NOT_A_NUMBER,
+                Assert.AreEqual(ErrorType.INVALID_COUNTRY_CODE,
                    e.ErrorType,
                    "Wrong error type stored in exception.");
             }
             {
                 // This is invalid because no "+" sign is present as part of phone-context. This should not
                 // succeed in being parsed.
-                String invalidRfcPhoneContext = "tel:555-1234;phone-context:1-331";
-                phoneUtil.Parse(invalidRfcPhoneContext, RegionCode.US);
-                Assert.Fail("No leading plus provided in phone context - should fail.");
+                String invalidRfcPhoneContext = "tel:555-1234;phone-context=1-331";
+                phoneUtil.Parse(invalidRfcPhoneContext, RegionCode.ZZ);
+                Assert.Fail("'Unknown' region code not allowed: should fail.");
             }
             catch (NumberParseException e)
             {
                 // Expected this exception.
-                Assert.AreEqual(ErrorType.NOT_A_NUMBER,
+                Assert.AreEqual(ErrorType.INVALID_COUNTRY_CODE,
                    e.ErrorType,
                    "Wrong error type stored in exception.");
             }
-            catch (ArgumentNullException)
-            {
-                Assert.Fail("No leading plus provided in phone context - but should not throw a null pointer " +
-                    "exception.");
-            }
         }
 
         [Test]
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("Tel: +64 3 331 6005", RegionCode.ZZ));
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("+64 3 331 6005", null));
             Assert.AreEqual(INTERNATIONAL_TOLL_FREE, phoneUtil.Parse("+800 1234 5678", null));
+            Assert.AreEqual(UNIVERSAL_PREMIUM_RATE, phoneUtil.Parse("+979 123 456 789", null));
 
             // Test parsing RFC3966 format with a phone context.
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("tel:03-331-6005;phone-context=+64", RegionCode.ZZ));
             Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("  tel:03-331-6005;phone-context=+64", RegionCode.ZZ));
+            Assert.AreEqual(NZ_NUMBER, phoneUtil.Parse("tel:03-331-6005;isub=12345;phone-context=+64",
+                RegionCode.ZZ));
 
             // It is important that we set the carrier code to an empty string, since we used
             // ParseAndKeepRawInput and no carrier code was found.
                 phoneUtil.IsNumberMatch("+643 331-6005", "+6433316005"));
             Assert.AreEqual(PhoneNumberUtil.MatchType.EXACT_MATCH,
                 phoneUtil.IsNumberMatch("+64 3 331-6005", "+6433316005"));
+            Assert.AreEqual(PhoneNumberUtil.MatchType.EXACT_MATCH,
+                 phoneUtil.IsNumberMatch("+64 3 331-6005", "tel:+64-3-331-6005;isub=123"));
             // Test alpha numbers.
             Assert.AreEqual(PhoneNumberUtil.MatchType.EXACT_MATCH,
                 phoneUtil.IsNumberMatch("+1800 siX-Flags", "+1 800 7493 5247"));
             // Extension different, all else the same.
             Assert.AreEqual(PhoneNumberUtil.MatchType.NO_MATCH,
                 phoneUtil.IsNumberMatch("+64 3 331-6005 extn 1234", "0116433316005#1235"));
+            Assert.AreEqual(PhoneNumberUtil.MatchType.NO_MATCH,
+                 phoneUtil.IsNumberMatch(
+                     "+64 3 331-6005 extn 1234", "tel:+64-3-331-6005;ext=1235"));
             // NSN matches, but extension is different - not the same number.
             Assert.AreEqual(PhoneNumberUtil.MatchType.NO_MATCH,
                 phoneUtil.IsNumberMatch("+64 3 331-6005 ext.1235", "3 331 6005#1234"));
             Assert.AreEqual(PhoneNumberUtil.MatchType.NSN_MATCH,
                 phoneUtil.IsNumberMatch("+64 3 331-6005", "03 331 6005"));
             Assert.AreEqual(PhoneNumberUtil.MatchType.NSN_MATCH,
+                 phoneUtil.IsNumberMatch(
+                     "+64 3 331-6005", "tel:03-331-6005;isub=1234;phone-context=abc.nz"));
+            Assert.AreEqual(PhoneNumberUtil.MatchType.NSN_MATCH,
                 phoneUtil.IsNumberMatch(NZ_NUMBER, "03 331 6005"));
             // Here the second number possibly starts with the country calling code for New Zealand,
             // although we are unsure.
             // Short NSN matches with the country not specified for either one or both numbers.
             Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
                 phoneUtil.IsNumberMatch("+64 3 331-6005", "331 6005"));
+            Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+                 phoneUtil.IsNumberMatch("+64 3 331-6005", "tel:331-6005;phone-context=abc.nz"));
+            Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+                 phoneUtil.IsNumberMatch("+64 3 331-6005",
+                     "tel:331-6005;isub=1234;phone-context=abc.nz"));
+            Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+                 phoneUtil.IsNumberMatch("+64 3 331-6005",
+                     "tel:331-6005;isub=1234;phone-context=abc.nz;a=%A1"));
             // We did not know that the "0" was a national prefix since neither number has a country code,
             // so this is considered a SHORT_NSN_MATCH.
             Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
             Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
                 phoneUtil.IsNumberMatch("3 331-6005", "331 6005"));
             Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+                 phoneUtil.IsNumberMatch("3 331-6005", "tel:331-6005;phone-context=abc.nz"));
+            Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
                 phoneUtil.IsNumberMatch("3 331-6005", "+64 331 6005"));
             // Short NSN match with the country specified.
             Assert.AreEqual(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,

File csharp/PhoneNumbers.Test/TestShortNumberUtil.cs

         [Test]
         public void testIsEmergencyNumber_US()
         {
-            Assert.True(shortUtil.isEmergencyNumber("911", RegionCode.US));
-            Assert.True(shortUtil.isEmergencyNumber("119", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber("999", RegionCode.US));
+            Assert.True(shortUtil.IsEmergencyNumber("911", RegionCode.US));
+            Assert.True(shortUtil.IsEmergencyNumber("119", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("999", RegionCode.US));
         }
 
         [Test]
         public void testIsEmergencyNumberLongNumber_US()
         {
-            Assert.False(shortUtil.isEmergencyNumber("9116666666", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber("1196666666", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber("9996666666", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("9116666666", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("1196666666", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("9996666666", RegionCode.US));
         }
 
         [Test]
         public void testIsEmergencyNumberWithFormatting_US()
         {
-            Assert.True(shortUtil.isEmergencyNumber("9-1-1", RegionCode.US));
-            Assert.True(shortUtil.isEmergencyNumber("*911", RegionCode.US));
-            Assert.True(shortUtil.isEmergencyNumber("1-1-9", RegionCode.US));
-            Assert.True(shortUtil.isEmergencyNumber("*119", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber("9-9-9", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber("*999", RegionCode.US));
+            Assert.True(shortUtil.IsEmergencyNumber("9-1-1", RegionCode.US));
+            Assert.True(shortUtil.IsEmergencyNumber("*911", RegionCode.US));
+            Assert.True(shortUtil.IsEmergencyNumber("1-1-9", RegionCode.US));
+            Assert.True(shortUtil.IsEmergencyNumber("*119", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("9-9-9", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("*999", RegionCode.US));
         }
 
         [Test]
         public void testIsEmergencyNumberWithPlusSign_US()
         {
-            Assert.False(shortUtil.isEmergencyNumber("+911", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber("\uFF0B911", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber(" +911", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber("+119", RegionCode.US));
-            Assert.False(shortUtil.isEmergencyNumber("+999", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("+911", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("\uFF0B911", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber(" +911", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("+119", RegionCode.US));
+            Assert.False(shortUtil.IsEmergencyNumber("+999", RegionCode.US));
         }
 
         [Test]
         public void testIsEmergencyNumber_BR()
         {
-            Assert.True(shortUtil.isEmergencyNumber("911", RegionCode.BR));
-            Assert.True(shortUtil.isEmergencyNumber("190", RegionCode.BR));
-            Assert.False(shortUtil.isEmergencyNumber("999", RegionCode.BR));
+            Assert.True(shortUtil.IsEmergencyNumber("911", RegionCode.BR));
+            Assert.True(shortUtil.IsEmergencyNumber("190", RegionCode.BR));
+            Assert.False(shortUtil.IsEmergencyNumber("999", RegionCode.BR));
         }
 
         [Test]
         public void testIsEmergencyNumberLongNumber_BR()
         {
-            Assert.False(shortUtil.isEmergencyNumber("9111", RegionCode.BR));
-            Assert.False(shortUtil.isEmergencyNumber("1900", RegionCode.BR));
-            Assert.False(shortUtil.isEmergencyNumber("9996", RegionCode.BR));
+            Assert.False(shortUtil.IsEmergencyNumber("9111", RegionCode.BR));
+            Assert.False(shortUtil.IsEmergencyNumber("1900", RegionCode.BR));
+            Assert.False(shortUtil.IsEmergencyNumber("9996", RegionCode.BR));
         }
 
         [Test]
         public void testIsEmergencyNumber_AO()
         {
             // Angola doesn't have any metadata for emergency numbers in the test metadata.
-            Assert.False(shortUtil.isEmergencyNumber("911", RegionCode.AO));
-            Assert.False(shortUtil.isEmergencyNumber("222123456", RegionCode.AO));
-            Assert.False(shortUtil.isEmergencyNumber("923123456", RegionCode.AO));
+            Assert.False(shortUtil.IsEmergencyNumber("911", RegionCode.AO));
+            Assert.False(shortUtil.IsEmergencyNumber("222123456", RegionCode.AO));
+            Assert.False(shortUtil.IsEmergencyNumber("923123456", RegionCode.AO));
         }
 
         [Test]
         public void testIsEmergencyNumber_ZW()
         {
             // Zimbabwe doesn't have any metadata in the test metadata.
-            Assert.False(shortUtil.isEmergencyNumber("911", RegionCode.ZW));
-            Assert.False(shortUtil.isEmergencyNumber("01312345", RegionCode.ZW));
-            Assert.False(shortUtil.isEmergencyNumber("0711234567", RegionCode.ZW));
+            Assert.False(shortUtil.IsEmergencyNumber("911", RegionCode.ZW));
+            Assert.False(shortUtil.IsEmergencyNumber("01312345", RegionCode.ZW));
+            Assert.False(shortUtil.IsEmergencyNumber("0711234567", RegionCode.ZW));
         }
     }
 }

File csharp/PhoneNumbers/CountryCodeToRegionCodeMap.cs

         // indicated with "isMainCountryForCode" in the metadata should be first.
         public static Dictionary<int, List<String>> GetCountryCodeToRegionCodeMap()
         {
-            // The capacity is set to 281 as there are 211 different country codes,
+            // The capacity is set to 286 as there are 215 different country codes,
             // and this offers a load factor of roughly 0.75.
-            var countryCodeToRegionCodeMap = new Dictionary<int, List<String>>(281);
+            var countryCodeToRegionCodeMap = new Dictionary<int, List<String>>(286);
 
             List<String> listWithRegionCode = new List<String>(25);
             listWithRegionCode.Add("US");
             countryCodeToRegionCodeMap[856] = listWithRegionCode;
 
             listWithRegionCode = new List<String>(1);
+            listWithRegionCode.Add("001");
+            countryCodeToRegionCodeMap[870] = listWithRegionCode;
+
+            listWithRegionCode = new List<String>(1);
+            listWithRegionCode.Add("001");
+            countryCodeToRegionCodeMap[878] = listWithRegionCode;
+
+            listWithRegionCode = new List<String>(1);
             listWithRegionCode.Add("BD");
             countryCodeToRegionCodeMap[880] = listWithRegionCode;
 
             listWithRegionCode = new List<String>(1);
             listWithRegionCode.Add("001");
-            countryCodeToRegionCodeMap[803] = listWithRegionCode;
+            countryCodeToRegionCodeMap[881] = listWithRegionCode;
+
+            listWithRegionCode = new List<String>(1);
+            listWithRegionCode.Add("001");
+            countryCodeToRegionCodeMap[882] = listWithRegionCode;
+
+            listWithRegionCode = new List<String>(1);
+            listWithRegionCode.Add("001");
+            countryCodeToRegionCodeMap[883] = listWithRegionCode;
 
             listWithRegionCode = new List<String>(1);
             listWithRegionCode.Add("TW");

File csharp/PhoneNumbers/PhoneNumberMetaData.xml

         <nationalNumberPattern>
           (?:
             6(?:
-              0[0-5]|
-              [68]0
+              0[0-7]|
+              6[0-2]|
+              8[01]
             )|
             7(?:
               [02-68]\d|
     <territory id="CZ" countryCode="420" internationalPrefix="00">
       <availableFormats>
         <numberFormat pattern="([2-9]\d{2})(\d{3})(\d{3})">
-          <format>$1 $2 $3</format>
-        </numberFormat>
-      </availableFormats>
-      <generalDesc>
-        <nationalNumberPattern>[2-9]\d{8}</nationalNumberPattern>
-        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+          <leadingDigits>
+            [2-8]|
+            9[015-7]
+          </leadingDigits>
+          <format>$1 $2 $3</format>
+        </numberFormat>
+        <numberFormat pattern="(96\d)(\d{3})(\d{3})(\d{3})">
+          <leadingDigits>96</leadingDigits>
+          <format>$1 $2 $3 $4</format>
+        </numberFormat>
+        <numberFormat pattern="(9\d)(\d{3})(\d{3})(\d{3})">
+          <leadingDigits>9[36]</leadingDigits>
+          <format>$1 $2 $3 $4</format>
+        </numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>
+          [2-8]\d{8}|
+          9\d{8,11}
+        </nationalNumberPattern>
+        <possibleNumberPattern>\d{9,12}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
         <nationalNumberPattern>
           (?:
             60[1-8]|
             7(?:
-              0[25]|
+              0[2-5]|
               [2379]\d
             )
           )\d{6}
         <!-- Numbers belonging to private communication networks are included here. These are
              classified as Institutional networks, belonging to institutions like the police, armed
              forces and railways, along with a couple of formerly government-owned banks. These
-             numbers are reachable by the public.  -->
+             numbers are reachable by the public. -->
         <nationalNumberPattern>
           9(?:
             5[056]|
         </nationalNumberPattern>
         <exampleNumber>972123456</exampleNumber>
       </uan>
+      <voicemail>
+        <nationalNumberPattern>
+          9(?:
+            3\d{9}|
+            6\d{7,10}
+          )
+        </nationalNumberPattern>
+        <possibleNumberPattern>\d{9,12}</possibleNumberPattern>
+        <exampleNumber>93123456789</exampleNumber>
+      </voicemail>
+      <shortCode>
+        <nationalNumberPattern>
+          1(?:
+            1(?:
+              6\d{3}|
+              8\d
+            )|
+            2\d{2,3}|
+            3\d{3,4}|
+            4\d{3}|
+            99
+          )
+        </nationalNumberPattern>
+        <possibleNumberPattern>\d{4,6}</possibleNumberPattern>
+        <exampleNumber>116123</exampleNumber>
+      </shortCode>
       <emergency>
         <nationalNumberPattern>
           1(?:
         <nationalNumberPattern>[5-9]\d{8}</nationalNumberPattern>
         <possibleNumberPattern>\d{9}</possibleNumberPattern>
       </generalDesc>
-      <fixedLine>
-        <nationalNumberPattern>
-          (?:
-            8(?:
-              [13]0|
-              [28][0-8]|
-              [47][1-9]|
-              5[01346-9]|
-              6[0457-9]
-            )|
-            9(?:
-              [1238][0-8]|
-              [47][1-9]|
-              [56]\d
-            )
-          )\d{6}
+      <!-- The pattern is complex because the Lleida Networks mobile ranges are inside the
+           fixed-line ranges. -->
+      <fixedLine>
+        <nationalNumberPattern>
+          8(?:
+            [13]0|
+            [28][0-8]|
+            [47][1-9]|
+            5[01346-9]|
+            6[0457-9]
+          )\d{6}|
+          9(?:
+            [1238][0-8]\d{6}|
+            4[1-9]\d{6}|
+            5\d{7}|
+            6(?:
+              [0-8]\d{6}|
+              9(?:
+                0(?:
+                  [0-57-9]\d{4}|
+                  6(?:
+                    0[0-8]|
+                    1[1-9]|
+                    [2-9]\d
+                  )\d{2}
+                )|
+                [1-9]\d{5}
+              )
+            )|
+            7(?:
+              [124-9]\d{2}|
+              3(?:
+                [0-8]\d|
+                9[1-9]
+              )
+            )\d{4}
+          )
         </nationalNumberPattern>
         <exampleNumber>810123456</exampleNumber>
       </fixedLine>
-      <mobile>
-        <nationalNumberPattern>
-          (?:
-            6\d|
-            7[1-4]
-          )\d{7}
+      <!-- The ranges 969060900 to 969061099 and 973900000 to 973909999 are mobile according to
+           information received from Lleida Networks. -->
+      <mobile>
+        <nationalNumberPattern>
+          (?:
+            6\d{6}|
+            7[1-4]\d{5}|
+            9(?:
+              6906(?:
+                09|
+                10
+              )|
+              7390\d{2}
+            )
+          )\d{2}
         </nationalNumberPattern>
         <exampleNumber>612345678</exampleNumber>
       </mobile>
           <leadingDigits>[1269]</leadingDigits>
           <format>$1 $2</format>
         </numberFormat>
-        <numberFormat pattern="(5[05]\d)(\d{5})">
+        <numberFormat pattern="(5[015]\d)(\d{5})">
           <leadingDigits>5</leadingDigits>
           <format>$1 $2</format>
         </numberFormat>
-        <numberFormat pattern="(65816)(\d{6})">
-          <leadingDigits>65816</leadingDigits>
-          <format>$1 $2</format>
-        </numberFormat>
-      </availableFormats>
-      <generalDesc>
-        <nationalNumberPattern>
-          [12569]\d{6,7}|
-          65816\d{6}
-        </nationalNumberPattern>
-        <possibleNumberPattern>\d{7,8}|\d{11}</possibleNumberPattern>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>
+          [12569]\d{6,7}
+        </nationalNumberPattern>
+        <possibleNumberPattern>\d{7,8}</possibleNumberPattern>
       </generalDesc>
       <fixedLine>
         <nationalNumberPattern>
             18\d|
             2(?:
               [23]\d{2}|
-              4[1-35-9]\d|
+              4(?:
+                [1-35-9]\d|
+                44
+              )|
               5(?:
                 0[034]|
                 [2-46]\d|
           (?:
             5(?:
               0[0-2568]|
+              11|
               5\d
             )|
             6(?:
               0[034679]|
-              5(?:
-                [015-79]|
-                8(?:
-                  [02-9]|
-                  1[0-57-9]
-                )
-              )|
+              5[015-9]|
               6\d|
               7[067]|
               9[069]
         <exampleNumber>50012345</exampleNumber>
       </mobile>
       <!-- No tollFree or premiumRate information can be found. -->
-      <voicemail>
-        <!-- Wataniya Telecom -->
-        <nationalNumberPattern>65816\d{6}</nationalNumberPattern>
-        <possibleNumberPattern>\d{11}</possibleNumberPattern>
-        <exampleNumber>65816123456</exampleNumber>
-      </voicemail>
       <shortCode>
         <nationalNumberPattern>
           1(?:
       </mobile>
     </territory>
 
+    <!-- BebbiCell (Formerly Global Networks Switzerland AG) +88234 -->
+    <!-- http://www.itu.int/oth/T0202000054/en -->
+    <!-- http://www.gsm.aq/numberplan.php -->
+    <!-- http://www.global.aq -->
+    <!-- Maritime Communications Partner (MCP) +88232 -->
+    <!-- http://www.itu.int/oth/T02020000F4/en -->
+    <!-- Oration Technologies +88237 -->
+    <!-- http://www.itu.int/oth/T02020000A0/en -->
+    <!-- Telespazio S.p.A. +88213 -->
+    <!-- http://www.itu.int/oth/T02020000CC/en -->
+    <!-- Thuraya +88216 -->
+    <!-- http://www.itu.int/oth/T02020000CF/en -->
+    <territory id="001" countryCode="882">
+      <availableFormats>
+        <numberFormat pattern="(\d{2})(\d{4})(\d{3})">
+          <leadingDigits>3[23]</leadingDigits>
+          <format>$1 $2 $3</format>
+        </numberFormat>
+        <numberFormat pattern="(\d{2})(\d{5})">
+          <leadingDigits>
+            16|
+            342
+          </leadingDigits>
+          <format>$1 $2</format>
+        </numberFormat>
+        <numberFormat pattern="(\d{2})(\d{4})(\d{4})">
+          <leadingDigits>34[57]</leadingDigits>
+          <format>$1 $2 $3</format>
+        </numberFormat>
+        <numberFormat pattern="(\d{3})(\d{4})(\d{4})">
+          <leadingDigits>348</leadingDigits>
+          <format>$1 $2 $3</format>
+        </numberFormat>
+        <numberFormat pattern="(\d{2})(\d{2})(\d{4})">
+          <leadingDigits>1</leadingDigits>
+          <format>$1 $2 $3</format>
+        </numberFormat>
+        <numberFormat pattern="(\d{2})(\d{3,4})(\d{4})">
+          <leadingDigits>16</leadingDigits>
+          <format>$1 $2 $3</format>
+        </numberFormat>
+        <numberFormat pattern="(\d{2})(\d{4,5})(\d{5})">
+          <leadingDigits>16</leadingDigits>
+          <format>$1 $2 $3</format>
+        </numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>[13]\d{6,11}</nationalNumberPattern>
+        <possibleNumberPattern>\d{7,12}</possibleNumberPattern>
+        <exampleNumber>32123456</exampleNumber>
+      </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>NA</nationalNumberPattern>
+        <possibleNumberPattern>NA</possibleNumberPattern>
+      </fixedLine>
+      <mobile>
+        <!-- Bebbicell Mobile numbers, MCP & Oration. We are guessing the number length for
+             Oration based on numbers found online. -->
+        <nationalNumberPattern>
+          3(?:
+            2\d{3}|
+            37\d{2}|
+            4(?:
+              2|
+              7\d{3}
+            )
+          )\d{4}
+        </nationalNumberPattern>
+        <possibleNumberPattern>\d{7,10}</possibleNumberPattern>
+      </mobile>
+      <voip>
+        <!-- Telespazio S.p.A., Thuraya and Bebbicell VOIP numbers. -->
+        <nationalNumberPattern>
+          1(?:
+            3(?:
+              0[0347]|
+              [13][0139]|
+              2[035]|
+              4[013568]|
+              6[0459]|
+              7[06]|
+              8[15678]|
+              9[0689]
+            )\d{4}|
+            6\d{5,10}
+          )|
+          345\d{7}
+        </nationalNumberPattern>
+        <possibleNumberPattern>\d{7,12}</possibleNumberPattern>
+      </voip>
+      <voicemail>
+        <nationalNumberPattern>348[57]\d{7}</nationalNumberPattern>
+        <possibleNumberPattern>\d{11}</possibleNumberPattern>
+      </voicemail>
+    </territory>
+
     <!-- http://www.itu.int/oth/T02020000F3/en -->
     <!-- http://www.republicwireless.com/world-wi-fi-number -->
     <territory id="001" countryCode="883">

File csharp/PhoneNumbers/PhoneNumberMetaDataForTesting.xml

         <nationalNumberPattern>\d{8}</nationalNumberPattern>
       </tollFree>
     </territory>
+
+    <!-- Universal International Premium Rate Number -->
+    <territory id="001" countryCode="979">
+      <availableFormats>
+        <numberFormat pattern="(\d)(\d{4})(\d{4})">
+          <format>$1 $2 $3</format>
+        </numberFormat>
+      </availableFormats>
+      <generalDesc>
+        <nationalNumberPattern>\d{9}</nationalNumberPattern>
+        <possibleNumberPattern>\d{9}</possibleNumberPattern>
+        <exampleNumber>123456789</exampleNumber>
+      </generalDesc>
+      <fixedLine>
+        <nationalNumberPattern>NA</nationalNumberPattern>
+        <possibleNumberPattern>NA</possibleNumberPattern>
+      </fixedLine>
+      <mobile>
+        <nationalNumberPattern>NA</nationalNumberPattern>
+        <possibleNumberPattern>NA</possibleNumberPattern>
+      </mobile>
+      <premiumRate>
+        <nationalNumberPattern>\d{9}</nationalNumberPattern>
+      </premiumRate>
+    </territory>
   </territories>
 </phoneNumberMetadata>

File csharp/PhoneNumbers/PhoneNumberUtil.cs

         // Flags to use when compiling regular expressions for phone numbers.
         internal static readonly RegexOptions REGEX_FLAGS = RegexOptions.IgnoreCase | RegexOptions.CultureInvariant;
         // The minimum and maximum length of the national significant number.
-        internal const int MIN_LENGTH_FOR_NSN = 3;
+        internal const int MIN_LENGTH_FOR_NSN = 2;
         // The ITU says the maximum length should be 15, but we have found longer numbers in Germany.
         internal const int MAX_LENGTH_FOR_NSN = 16;
         // The maximum length of the country calling code.
 
         const String RFC3966_EXTN_PREFIX = ";ext=";
         private const String RFC3966_PREFIX = "tel:";
-        // We include the "+" here since RFC3966 format specifies that the context must be specified in
-        // international format.
-        private const String RFC3966_PHONE_CONTEXT = ";phone-context=+";
-
+        private const String RFC3966_PHONE_CONTEXT = ";phone-context=";
+        private const String RFC3966_ISDN_SUBADDRESS = ";isub=";
+        
         // A map that contains characters that are essential when dialling. That means any of the
         // characters in this map must not be removed from a number when dialing, otherwise the call will
         // not reach the intended destination.
         // placeholder for carrier information in some phone numbers. Full-width variants are also
         // present.
         internal const String VALID_PUNCTUATION = "-x\u2010-\u2015\u2212\u30FC\uFF0D-\uFF0F " +
-            "\u00A0\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E";
+            "\u00A0\u00AD\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E";
 
         private const String DIGITS = "\\p{Nd}";
 
             var diallableCharMap = new Dictionary<char, char>();
             foreach (var k in asciiDigitMappings)
                 diallableCharMap[k.Key] = k.Value;
-            diallableCharMap['+'] = '+';
+            diallableCharMap[PLUS_SIGN] = PLUS_SIGN;
             diallableCharMap['*'] = '*';
             DIALLABLE_CHAR_MAPPINGS = diallableCharMap;
 
                     foreach (var m in meta.MetadataList)
                     {
                         if(isNonGeoRegion)
-                            countryCodeToNonGeographicalMetadataMap[countryCallingCode] = m;
+                            countryCodeToNonGeographicalMetadataMap[m.CountryCode] = m;
                         else
                             regionToMetadataMap[m.Id] = m;
                     }
 
         /**
         * Checks to see if the string of characters could possibly be a phone number at all. At the
-        * moment, checks to see that the string begins with at least 3 digits, ignoring any punctuation
+        * moment, checks to see that the string begins with at least 2 digits, ignoring any punctuation
         * commonly found in phone numbers.
         * This method does not require the number to be normalized in advance - but does assume that
         * leading non-number symbols have been removed, such as by the method extractPossibleNumber.
             // If no digit is inserted/removed/modified as a result of our formatting, we return the
             // formatted phone number; otherwise we return the raw input the user entered.
             return (formattedNumber != null &&
-                NormalizeDigitsOnly(formattedNumber).Equals(NormalizeDigitsOnly(rawInput)))
+                NormalizeHelper(formattedNumber, DIALLABLE_CHAR_MAPPINGS, true /* remove non matches */)
+                    .Equals(NormalizeHelper(
+                        rawInput, DIALLABLE_CHAR_MAPPINGS, true /* remove non matches */)))
                 ? formattedNumber
                 : rawInput;
         }
             }
             if (countryCodeSource != CountryCodeSource.FROM_DEFAULT_COUNTRY)
             {
-                if (fullNumber.Length < MIN_LENGTH_FOR_NSN)
+                if (fullNumber.Length <= MIN_LENGTH_FOR_NSN)
                 {
                     throw new NumberParseException(ErrorType.TOO_SHORT_AFTER_IDD,
                            "Phone number had an IDD, but after this was not "
         * particular region is not performed. This can be done separately with {@link #isValidNumber}.
         *
         * @param numberToParse     number that we are attempting to parse. This can contain formatting
-        *                          such as +, ( and -, as well as a phone number extension.
+        *                          such as +, ( and -, as well as a phone number extension. It can also
+        *                          be provided in RFC3966 format.
         * @param defaultRegion     region that we are expecting the number to be from. This is only used
         *                          if the number being parsed is not written in international format.
         *                          The country_code for the number in this case would be stored as that
                 throw new NumberParseException(ErrorType.TOO_LONG,
                     "The string supplied was too long to parse.");
 
-            int indexOfPhoneContext = numberToParse.IndexOf(RFC3966_PHONE_CONTEXT);
             StringBuilder nationalNumber = new StringBuilder();
-            if (indexOfPhoneContext > 0)
-            {
-                // Prefix the number with the phone context. The offset here is because the context we are
-                // expecting to match should start with a "+" sign, and we want to include this at the start
-                // of the number.
-                nationalNumber.Append(numberToParse.Substring(indexOfPhoneContext +
-                    RFC3966_PHONE_CONTEXT.Length - 1));
-                // Now append everything between the "tel:" prefix and the phone-context.
-                var rfcOffset = numberToParse.IndexOf(RFC3966_PREFIX) + RFC3966_PREFIX.Length;
-                nationalNumber.Append(numberToParse.Substring(
-                    rfcOffset, indexOfPhoneContext - rfcOffset));
-                // Note that phone-contexts that are URLs will not be parsed - isViablePhoneNumber will throw
-                // an exception below.
-            }
-            else
-            {
-                // Extract a possible number from the string passed in (this strips leading characters that
-                // could not be the start of a phone number.)
-                nationalNumber.Append(ExtractPossibleNumber(numberToParse));
-            }
+            BuildNationalNumberForParsing(numberToParse, nationalNumber);
 
             if (!IsViablePhoneNumber(nationalNumber.ToString()))
                 throw new NumberParseException(ErrorType.NOT_A_NUMBER,
         }
 
         /**
+        * Converts numberToParse to a form that we can parse and write it to nationalNumber if it is
+        * written in RFC3966; otherwise extract a possible number out of it and write to nationalNumber.
+        */
+        private void BuildNationalNumberForParsing(String numberToParse, StringBuilder nationalNumber)
+        {
+            int indexOfPhoneContext = numberToParse.IndexOf(RFC3966_PHONE_CONTEXT);
+            if (indexOfPhoneContext > 0)
+            {
+                int phoneContextStart = indexOfPhoneContext + RFC3966_PHONE_CONTEXT.Length;
+                // If the phone context contains a phone number prefix, we need to capture it, whereas domains
+                // will be ignored.
+                if (numberToParse[phoneContextStart] == PLUS_SIGN)
+                {
+                    // Additional parameters might follow the phone context. If so, we will remove them here
+                    // because the parameters after phone context are not important for parsing the
+                    // phone number.
+                    int phoneContextEnd = numberToParse.IndexOf(';', phoneContextStart);
+                    if (phoneContextEnd > 0)
+                    {
+                        nationalNumber.Append(numberToParse.Substring(phoneContextStart, phoneContextEnd - phoneContextStart));
+                    }
+                    else
+                    {
+                        nationalNumber.Append(numberToParse.Substring(phoneContextStart));
+                    }
+                }
+
+                // Now append everything between the "tel:" prefix and the phone-context. This should include
+                // the national number, an optional extension or isdn-subaddress component.
+                int indexOfPrefix = numberToParse.IndexOf(RFC3966_PREFIX) + RFC3966_PREFIX.Length;
+                nationalNumber.Append(numberToParse.Substring(indexOfPrefix, indexOfPhoneContext - indexOfPrefix));
+            }
+            else
+            {
+                // Extract a possible number from the string passed in (this strips leading characters that
+                // could not be the start of a phone number.)
+                nationalNumber.Append(ExtractPossibleNumber(numberToParse));
+            }
+
+            // Delete the isdn-subaddress and everything after it if it is present. Note extension won't
+            // appear at the same time with isdn-subaddress according to paragraph 5.3 of the RFC3966 spec,
+            int indexOfIsdn = nationalNumber.ToString().IndexOf(RFC3966_ISDN_SUBADDRESS);
+            if (indexOfIsdn > 0)
+            {
+                nationalNumber.Remove(indexOfIsdn, nationalNumber.Length - indexOfIsdn);
+            }
+            // If both phone context and isdn-subaddress are absent but other parameters are present, the
+            // parameters are left in nationalNumber. This is because we are concerned about deleting
+            // content from a potential number string when there is no strong evidence that the number is
+            // actually written in RFC3966.
+        }
+
+        /**
         * Takes two phone numbers and compares them for equality.
         *
         * <p>Returns EXACT_MATCH if the country_code, NSN, presence of a leading zero for Italian numbers

File csharp/PhoneNumbers/Properties/AssemblyInfo.cs

 //
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
-// [assembly: AssemblyVersion("4.8.0.33")]
-[assembly: AssemblyVersion("4.8.0.33")]
-[assembly: AssemblyFileVersion("4.8.0.33")]
+// [assembly: AssemblyVersion("4.8.0.34")]
+[assembly: AssemblyVersion("4.8.0.34")]
+[assembly: AssemblyFileVersion("4.8.0.34")]

File csharp/PhoneNumbers/ShortNumberUtil.cs

         * @param regionCode  the region where the phone number is being dialed
         * @return  if the number exactly matches an emergency services number in the given region.
         */
-        public bool isEmergencyNumber(String number, String regionCode)
+        public bool IsEmergencyNumber(String number, String regionCode)
         {
             return MatchesEmergencyNumberHelper(number, regionCode, false /* doesn't allow prefix match */);
         }

File csharp/PhoneNumbers/res/221_en

 # Generated from:
 # http://en.wikipedia.org/wiki/+221 [373996724]
 
-2218|Dakar
-2219|Outside Dakar
+221338|Dakar
+221339|Outside Dakar

File csharp/PhoneNumbers/res/224_en

 # Generated from:
 # http://en.wikipedia.org/wiki/+224 [373997051]
 
-22424|Fria
-22431|Boké
-22432|Kamsar
-22441|Conakry
-22442|Sangoya
-22443|Conakry
-22445|Conakry
-22446|Boussoura
-22447|Conakry
-22451|Labé
-22453|Pita
-22461|Kindia
-224613|Télimélé
-22468|Mamou
-22469|Dalaba
-22471|Kankan
-22481|Faranah
-22491|N'Zérékoré
-22494|Macenta
-22497|Guéckédou
-22498|Kissidougou
+2243024|Fria
+2243031|Boké
+2243032|Kamsar
+2243041|Conakry
+2243042|Conakry
+2243043|Conakry
+2243045|Conakry
+2243046|Boussoura
+2243047|Conakry
+2243051|Labé
+2243053|Pita
+2243061|Kindia
+22430613|Télimélé
+2243068|Mamou
+2243069|Dalaba
+2243071|Kankan
+2243081|Faranah
+2243091|N'Zérékoré
+2243094|Macenta
+2243097|Guéckédou
+2243098|Kissidougou

File csharp/PhoneNumbers/res/226_en

 # limitations under the License.
 
 # Generated from:
-# http://en.wikipedia.org/wiki/+226 [374115628]
+# http://en.wikipedia.org/wiki/+226 [482669671] Except where overruled by
+# http://www.onatel.bf/onatelsa/plandenumerotation_burkina.pdf
+# Where there are many cities for a prefix, we only kept the more significant
+# ones.
 
-22630|Ouagadougou
-22631|Ouagadougou
-22632|Ouagadougou
-22633|Ouagadougou
-22634|Ouagadougou
-22635|Ouagadougou
-22636|Ouagadougou
-22637|Ouagadougou
-22638|Ouagadougou
-22644|Koudougou
-22645|Kaya
-22649|Kaya
-22652|Dédougou
-22653|Tougan
-22654|Tougan
-22655|Ouahigouya
-22656|Ouahigouya
-22666|Dori
-22670|Koupéla
-22671|Tenkodogo
-22677|Fada
-22679|Kantchari
-22686|Diébougou
-22687|Gaoua
-22688|Banfora
-22696|Orodara
+2262049|Kaya
+2262052|Dédougou
+2262053|Boromo/Djibasso/Nouna
+2262090|Gaoua
+2262091|Banfora
+2262096|Orodara
+2262097|Bobo-Dioulasso
+2262098|Bobo-Dioulasso
+2262099|Béréba/Fo/Houndé
+2264045|Kaya
+2264046|Falagountou/Dori
+2264054|Yako
+2264055|Ouahigouya
+2264056|Djibo
+2264070|Pouytenga/Koupéla
+2264071|Tenkodogo
+2264077|Fada/Diabo
+2264079|Kantchari
+226503|Ouagadougou
+2265040|Pô/Kombissiri/Koubri
+2265041|Léo/Sapouy
+2265042|Ouagadougou
+2265043|Ouagadougou
+2265044|Koudougou
+2265045|Ouagadougou
+2265046|Ouagadougou
+2265047|Ouagadougou
+2265048|Ouagadougou
+2265049|Ouagadougou

File csharp/PhoneNumbers/res/242_en

 
 # Translated from fr/242.txt using Freebase and Wikipedia.
 
-24221|Cuvette
-24222|Likouala/Sangha
-24223|Pool
-24224|Plateaux
-24225|Bouenza/Lekoumou/Niari
-24228|Brazzaville
-24229|Pointe-Noire
+2422221|Cuvette
+2422222|Likouala/Sangha
+2422223|Pool
+2422224|Plateaux
+2422225|Bouenza/Lekoumou/Niari
+2422228|Brazzaville
+2422229|Pointe-Noire

File csharp/PhoneNumbers/res/244_en

 
 # Translated from pt/244.txt using Freebase and Wikipedia.
 
-24431|Cabinda
-24432|Zaire
-244321|Soyo
-24433|Uige
-24434|Bengo
-244348|Caxito
-24435|Cuanza Norte
-244358|N'Dalatando
-24436|Cuanza Sul
-244363|Sumbe
-244364|Porto Amboim
-24441|Huambo
-24448|Bie
-244485|Kuito
-24449|Cuando Cubango
-24451|Malange
-244526|Dundo
-24453|Lunda Sul
-244535|Saurimo
-24454|Moxico
-244546|Luena
-24461|Huila
-244612|Lubango
-24464|Namibe
-244643|Tombua
-24465|Cunene
-244652|St. Clara/Cunene
-244655|Ondjiva
-24472|Benguela
-244722|Lobito
-244726|Bela Vista
-244728|Baia Farta
-244729|Catumbela
-244777|Dama Universal
+24422|Luanda
+244231|Cabinda
+244232|Zaire
+2442321|Soyo
+244233|Uige
+244234|Bengo
+2442348|Caxito
+244235|Cuanza Norte
+2442358|N'Dalatando
+244236|Cuanza Sul
+2442363|Sumbe
+2442364|Porto Amboim
+244241|Huambo
+244248|Bie
+2442485|Kuito
+244249|Cuando Cubango
+2442498|Menongue
+244251|Malange
+244252|Lunda Norte
+2442524|Lucapa
+2442526|Dundo
+244253|Lunda Sul
+2442535|Saurimo
+244254|Moxico
+2442546|Luena
+244261|Huila
+2442612|Lubango
+244264|Namibe
+2442643|Tombua
+244265|Cunene
+2442652|Kuroka
+2442655|Ondjiva
+244272|Benguela
+2442722|Lobito
+2442726|Bela Vista
+2442728|Baia Farta
+2442729|Catumbela
+2442777|Dama Universal

File csharp/PhoneNumbers/res/244_pt

 # limitations under the License.
 
 # Generated from:
-# http://www.angolatelecom.com/AngolaTelecom/PT/telList/natIndicative/c (2011-07-22)
+# http://www.angolatelecom.com/AngolaTelecom/PT/telList/natIndicative/c (2012-06-20)
 # http://en.wikipedia.org/wiki/+244 [440874733]
+# Names were then checked on Portuguese wikipedia to find the most common
+# Portuguese spelling: http://pt.wikipedia.org/wiki/Prov%C3%ADncias_de_Angola.
+# St. Clara has apparently been renamed as Curoca.
 
-24431|Cabinda
-24432|Zaire
-244321|Soyo
-24433|Uige
-24434|Bengo
-244348|Caxito
-24435|Kuanza Norte
-244358|N'Dalatando
-24436|Kuanza Sul
-244363|Sumbe
-244364|Porto Amboim
-24441|Huambo
-24448|Bie
-244485|Kuito
-24449|Kuando Kubango
-24451|Malange
-244526|Dundo
-24453|Lunda Sul
-244535|Saurimo
-24454|Moxico
-244546|Luena
-24461|Huila
-244612|Lubango
-24464|Namibe
-244643|Tombua
-24465|Cunene
-244652|St. Clara/Cunene
-244655|Ondjiva
-24472|Benguela
-244722|Lobito
-244726|Bela Vista
-244728|Baia Farta
-244729|Catumbela
-244777|Dama Universal
+24422|Luanda
+244231|Cabinda
+244232|Zaire
+2442321|Soyo
+244233|Uíge
+244234|Bengo
+2442348|Caxito
+244235|Kwanza-Norte
+2442358|N'Dalatando
+244236|Kwanza-Sul
+2442363|Sumbe
+2442364|Porto Amboim
+244241|Huambo
+244248|Bié
+2442485|Kuito
+244249|Cuando-Cubango
+2442498|Menongue
+244251|Malanje
+244252|Lunda-Norte
+2442524|Lucapa
+2442526|Dundo
+244253|Lunda-Sul
+2442535|Saurimo
+244254|Moxico
+2442546|Luena
+244261|Huíla
+2442612|Lubango
+244264|Namibe
+2442643|Tombua
+244265|Cunene
+2442652|Curoca
+2442655|Ondjiva
+244272|Benguela
+2442722|Lobito
+2442726|Bela Vista
+2442728|Baía Farta
+2442729|Catumbela
+2442777|Dama Universal

File csharp/PhoneNumbers/res/245_en

 
 # Translated from pt/245.txt using Freebase and Wikipedia.
 
-24522|S. Luzia
-24525|Brá
-24531|Mansoa/Manssabá
-24532|Bigene/Bissorã
-24533|Bula/Ingore
-24535|Farim
-24541|Bafatá/Bambadinca
-24551|Gabú
-24552|Sonaco
-24553|Pirada
-24561|Bedanda/Buba/Cacine/Catio/Fulacunda/Tite
-24562|Quebo
-24581|Bolama
-24582|Bubaque
-24583|Caravela
-24584|Uno
-24591|Canchungo
-24592|Cacheu
-24593|S. Domingos
+245320|Bissau
+245321|Bissau
+245322|St. Luzia
+245325|Brá
+245331|Mansôa
+245332|Bigene/Bissora
+245334|Mansaba
+245335|Farim
+245341|Bafatá
+245342|Bambadinca
+245351|Gabu
+245352|Sonaco
+245353|Pirada
+245354|Pitche
+245370|Buba
+245391|Canchungo
+245392|Cacheu
+245393|S. Domingos
+245394|Bula
+245396|Ingoré

File csharp/PhoneNumbers/res/245_pt

 # limitations under the License.
 
 # Generated from:
-# http://en.wikipedia.org/wiki/+245 [374256913]
+# http://www.itu.int/oth/T020200005C/en
 
-24522|S. Luzia
-24525|Brá
-24531|Mansoa/Manssabá
-24532|Bigene/Bissorã
-24533|Bula/Ingore
-24535|Farim
-24541|Bafatá/Bambadinca
-24551|Gabú
-24552|Sonaco
-24553|Pirada
-24561|Bedanda/Buba/Cacine/Catio/Fulacunda/Tite
-24562|Quebo
-24581|Bolama
-24582|Bubaque
-24583|Caravela
-24584|Uno
-24591|Canchungo
-24592|Cacheu
-24593|S. Domingos
+245320|Bissau
+245321|Bissau
+245322|Sta. Luzia
+245325|Brá
+245331|Mansôa
+245332|Bigene/Bissorã
+245334|Mansaba
+245335|Farim
+245341|Bafatá
+245342|Bambadinca
+245351|Gabú
+245352|Sonaco
+245353|Pirada
+245354|Pitche
+245370|Buba
+245391|Canchungo
+245392|Cacheu
+245393|S. Domingos
+245394|Bula
+245396|Ingoré

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/221_en

Binary file modified.

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/224_en

Binary file modified.

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/226_en

Binary file modified.

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/242_en

Binary file modified.

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/244_en

Binary file modified.

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/244_pt

Binary file modified.

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/245_en

Binary file modified.

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/245_pt

Binary file modified.

File java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/config

Binary file modified.

File java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java

   // countries sharing a calling code, such as the NANPA countries, the one
   // indicated with "isMainCountryForCode" in the metadata should be first.
   static Map<Integer, List<String>> getCountryCodeToRegionCodeMap() {
-    // The capacity is set to 285 as there are 214 different country codes,
+    // The capacity is set to 286 as there are 215 different country codes,
     // and this offers a load factor of roughly 0.75.
     Map<Integer, List<String>> countryCodeToRegionCodeMap =
-        new HashMap<Integer, List<String>>(285);
+        new HashMap<Integer, List<String>>(286);
 
     ArrayList<String> listWithRegionCode;
 
 
     listWithRegionCode = new ArrayList<String>(1);
     listWithRegionCode.add("001");
+    countryCodeToRegionCodeMap.put(882, listWithRegionCode);
+
+    listWithRegionCode = new ArrayList<String>(1);
+    listWithRegionCode.add("001");
     countryCodeToRegionCodeMap.put(883, listWithRegionCode);
 
     listWithRegionCode = new ArrayList<String>(1);

File java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java

   /** Flags to use when compiling regular expressions for phone numbers. */
   static final int REGEX_FLAGS = Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE;
   // The minimum and maximum length of the national significant number.
-  private static final int MIN_LENGTH_FOR_NSN = 3;
+  private static final int MIN_LENGTH_FOR_NSN = 2;
   // The ITU says the maximum length should be 15, but we have found longer numbers in Germany.
   static final int MAX_LENGTH_FOR_NSN = 16;
   // The maximum length of the country calling code.
 
   private static final String RFC3966_EXTN_PREFIX = ";ext=";
   private static final String RFC3966_PREFIX = "tel:";
-  // We include the "+" here since RFC3966 format specifies that the context must be specified in
-  // international format.
-  private static final String RFC3966_PHONE_CONTEXT = ";phone-context=+";
+  private static final String RFC3966_PHONE_CONTEXT = ";phone-context=";
+  private static final String RFC3966_ISDN_SUBADDRESS = ";isub=";
 
   // A map that contains characters that are essential when dialling. That means any of the
   // characters in this map must not be removed from a number when dialing, otherwise the call will
 
     HashMap<Character, Character> diallableCharMap = new HashMap<Character, Character>();
     diallableCharMap.putAll(asciiDigitMappings);
-    diallableCharMap.put('+', '+');
+    diallableCharMap.put(PLUS_SIGN, PLUS_SIGN);
     diallableCharMap.put('*', '*');
     DIALLABLE_CHAR_MAPPINGS = Collections.unmodifiableMap(diallableCharMap);
 
   // placeholder for carrier information in some phone numbers. Full-width variants are also
   // present.
   static final String VALID_PUNCTUATION = "-x\u2010-\u2015\u2212\u30FC\uFF0D-\uFF0F " +
-      "\u00A0\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E";
+      "\u00A0\u00AD\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E";
 
   private static final String DIGITS = "\\p{Nd}";
   // We accept alpha characters in phone numbers, ASCII only, upper and lower case.
 
   /**
    * Checks to see if the string of characters could possibly be a phone number at all. At the
-   * moment, checks to see that the string begins with at least 3 digits, ignoring any punctuation
+   * moment, checks to see that the string begins with at least 2 digits, ignoring any punctuation
    * commonly found in phone numbers.
    * This method does not require the number to be normalized in advance - but does assume that
    * leading non-number symbols have been removed, such as by the method extractPossibleNumber.
     // If no digit is inserted/removed/modified as a result of our formatting, we return the
     // formatted phone number; otherwise we return the raw input the user entered.
     return (formattedNumber != null &&
-            normalizeDigitsOnly(formattedNumber).equals(normalizeDigitsOnly(rawInput)))
+            normalizeHelper(formattedNumber, DIALLABLE_CHAR_MAPPINGS, true /* remove non matches */)
+                .equals(normalizeHelper(
+                    rawInput, DIALLABLE_CHAR_MAPPINGS, true /* remove non matches */)))
         ? formattedNumber
         : rawInput;
   }
       phoneNumber.setCountryCodeSource(countryCodeSource);
     }
     if (countryCodeSource != CountryCodeSource.FROM_DEFAULT_COUNTRY) {
-      if (fullNumber.length() < MIN_LENGTH_FOR_NSN) {
+      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 "
                                        + "long enough to be a viable phone number.");
    * particular region is not performed. This can be done separately with {@link #isValidNumber}.
    *
    * @param numberToParse     number that we are attempting to parse. This can contain formatting
-   *                          such as +, ( and -, as well as a phone number extension.
+   *                          such as +, ( and -, as well as a phone number extension. It can also
+   *                          be provided in RFC3966 format.
    * @param defaultRegion     region that we are expecting the number to be from. This is only used
    *                          if the number being parsed is not written in international format.
    *                          The country_code for the number in this case would be stored as that
                                      "The string supplied was too long to parse.");
     }
 
-    int indexOfPhoneContext = numberToParse.indexOf(RFC3966_PHONE_CONTEXT);
     StringBuilder nationalNumber = new StringBuilder();
-    if (indexOfPhoneContext > 0) {
-      // Prefix the number with the phone context. The offset here is because the context we are
-      // expecting to match should start with a "+" sign, and we want to include this at the start
-      // of the number.
-      nationalNumber.append(numberToParse.substring(indexOfPhoneContext +
-                                                    RFC3966_PHONE_CONTEXT.length() - 1));
-      // Now append everything between the "tel:" prefix and the phone-context.
-      nationalNumber.append(numberToParse.substring(
-          numberToParse.indexOf(RFC3966_PREFIX) + RFC3966_PREFIX.length(), indexOfPhoneContext));
-      // Note that phone-contexts that are URLs will not be parsed - isViablePhoneNumber will throw
-      // an exception below.
-    } else {
-      // Extract a possible number from the string passed in (this strips leading characters that
-      // could not be the start of a phone number.)
-      nationalNumber.append(extractPossibleNumber(numberToParse));
-    }
+    buildNationalNumberForParsing(numberToParse, nationalNumber);
 
     if (!isViablePhoneNumber(nationalNumber.toString())) {
       throw new NumberParseException(NumberParseException.ErrorType.NOT_A_NUMBER,
   }
 
   /**
+   * Converts numberToParse to a form that we can parse and write it to nationalNumber if it is
+   * written in RFC3966; otherwise extract a possible number out of it and write to nationalNumber.
+   */
+  private void buildNationalNumberForParsing(String numberToParse, StringBuilder nationalNumber) {
+    int indexOfPhoneContext = numberToParse.indexOf(RFC3966_PHONE_CONTEXT);
+    if (indexOfPhoneContext > 0) {
+      int phoneContextStart = indexOfPhoneContext + RFC3966_PHONE_CONTEXT.length();
+      // If the phone context contains a phone number prefix, we need to capture it, whereas domains
+      // will be ignored.
+      if (numberToParse.charAt(phoneContextStart) == PLUS_SIGN) {
+        // Additional parameters might follow the phone context. If so, we will remove them here
+        // because the parameters after phone context are not important for parsing the
+        // phone number.
+        int phoneContextEnd = numberToParse.indexOf(';', phoneContextStart);
+        if (phoneContextEnd > 0) {
+          nationalNumber.append(numberToParse.substring(phoneContextStart, phoneContextEnd));
+        } else {
+          nationalNumber.append(numberToParse.substring(phoneContextStart));
+        }
+      }
+
+      // Now append everything between the "tel:" prefix and the phone-context. This should include
+      // the national number, an optional extension or isdn-subaddress component.
+      nationalNumber.append(numberToParse.substring(
+          numberToParse.indexOf(RFC3966_PREFIX) + RFC3966_PREFIX.length(), indexOfPhoneContext));
+    } else {
+      // Extract a possible number from the string passed in (this strips leading characters that
+      // could not be the start of a phone number.)
+      nationalNumber.append(extractPossibleNumber(numberToParse));
+    }
+
+    // Delete the isdn-subaddress and everything after it if it is present. Note extension won't
+    // appear at the same time with isdn-subaddress according to paragraph 5.3 of the RFC3966 spec,
+    int indexOfIsdn = nationalNumber.indexOf(RFC3966_ISDN_SUBADDRESS);
+    if (indexOfIsdn > 0) {
+      nationalNumber.delete(indexOfIsdn, nationalNumber.length());
+    }
+    // If both phone context and isdn-subaddress are absent but other parameters are present, the
+    // parameters are left in nationalNumber. This is because we are concerned about deleting
+    // content from a potential number string when there is no strong evidence that the number is
+    // actually written in RFC3966.
+  }
+
+  /**
    * Takes two phone numbers and compares them for equality.
    *
    * <p>Returns EXACT_MATCH if the country_code, NSN, presence of a leading zero for Italian numbers

File java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_882

Binary file added.

File java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF

Binary file modified.

File java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CZ

Binary file modified.

File java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ES

Binary file modified.

File java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW

Binary file modified.

File java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java

   // countries sharing a calling code, such as the NANPA countries, the one
   // indicated with "isMainCountryForCode" in the metadata should be first.
   static Map<Integer, List<String>> getCountryCodeToRegionCodeMap() {
-    // The capacity is set to 22 as there are 17 different country codes,
+    // The capacity is set to 24 as there are 18 different country codes,
     // and this offers a load factor of roughly 0.75.
     Map<Integer, List<String>> countryCodeToRegionCodeMap =
-        new HashMap<Integer, List<String>>(22);
+        new HashMap<Integer, List<String>>(24);
 
     ArrayList<String> listWithRegionCode;
 
     listWithRegionCode.add("001");
     countryCodeToRegionCodeMap.put(800, listWithRegionCode);
 
+    listWithRegionCode = new ArrayList<String>(1);
+    listWithRegionCode.add("001");
+    countryCodeToRegionCodeMap.put(979, listWithRegionCode);
+
     return countryCodeToRegionCodeMap;
   }
 }

File java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java

     assertEquals(0, wrongTypeCases.size());
   }
 
-  // TODO: Update this to use connectsToEmergencyNumber or similar once that is
-  // implemented.
   public void testEmergency() throws Exception {
+    ShortNumberUtil shortUtil = new ShortNumberUtil(phoneNumberUtil);
     int wrongTypeCounter = 0;
     for (String regionCode : phoneNumberUtil.getSupportedRegions()) {
       PhoneNumberDesc desc =
       if (desc.hasExampleNumber()) {
         String exampleNumber = desc.getExampleNumber();
         if (!exampleNumber.matches(desc.getPossibleNumberPattern()) ||
-            !exampleNumber.matches(desc.getNationalNumberPattern())) {
+            !shortUtil.isEmergencyNumber(exampleNumber, regionCode)) {
           wrongTypeCounter++;
           LOGGER.log(Level.SEVERE, "Emergency example number test failed for " + regionCode);
         }

File java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java

           .setRawInput("000-000-0000");
   private static final PhoneNumber INTERNATIONAL_TOLL_FREE =
       new PhoneNumber().setCountryCode(800).setNationalNumber(12345678L);
+  // We set this to be the same length as numbers for the other non-geographical country prefix that
+  // we have in our test metadata. However, this is not considered valid because they differ in
+  // their country calling code.
   private static final PhoneNumber INTERNATIONAL_TOLL_FREE_TOO_LONG =
-      new PhoneNumber().setCountryCode(800).setNationalNumber(1234567890L);
+      new PhoneNumber().setCountryCode(800).setNationalNumber(123456789L);
+  private static final PhoneNumber UNIVERSAL_PREMIUM_RATE =
+      new PhoneNumber().setCountryCode(979).setNationalNumber(123456789L);
 
   public void testGetSupportedRegions() {
     assertTrue(phoneUtil.getSupportedRegions().size() > 0);
 
   public void testGetExampleNumberForNonGeoEntity() {
     assertEquals(INTERNATIONAL_TOLL_FREE, phoneUtil.getExampleNumberForNonGeoEntity(800));
+    assertEquals(UNIVERSAL_PREMIUM_RATE, phoneUtil.getExampleNumberForNonGeoEntity(979));
   }
 
   public void testConvertAlphaCharactersInNumber() {
   }
 
   public void testNormaliseRemovePunctuation() {
-    String inputNumber = "034-56&+#234";
+    String inputNumber = "034-56&+#2\u00AD34";
     String expectedOutput = "03456234";
     assertEquals("Conversion did not correctly remove punctuation",
                  expectedOutput,
         phoneUtil.parseAndKeepRawInput("0011 16502530000", RegionCode.AU);
     assertEquals("0011 1 650 253 0000",
         phoneUtil.formatInOriginalFormat(outOfCountryNumberFromAU2, RegionCode.AU));
+
+    // Test the star sign is not removed from or added to the original input by this method.
+    PhoneNumber starNumber = phoneUtil.parseAndKeepRawInput("*1234", RegionCode.JP);
+    assertEquals("*1234", phoneUtil.formatInOriginalFormat(starNumber, RegionCode.JP));
+    PhoneNumber numberWithoutStar = phoneUtil.parseAndKeepRawInput("1234", RegionCode.JP);
+    assertEquals("1234", phoneUtil.formatInOriginalFormat(numberWithoutStar, RegionCode.JP));
   }
 
   public void testIsPremiumRate() {
     premiumRateNumber.setCountryCode(49).setNationalNumber(90091234567L);
     assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
                  phoneUtil.getNumberType(premiumRateNumber));
+
+    assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
+                 phoneUtil.getNumberType(UNIVERSAL_PREMIUM_RATE));
   }
 
   public void testIsTollFree() {
     assertTrue(phoneUtil.isValidNumber(IT_NUMBER));
     assertTrue(phoneUtil.isValidNumber(GB_MOBILE));
     assertTrue(phoneUtil.isValidNumber(INTERNATIONAL_TOLL_FREE));
+    assertTrue(phoneUtil.isValidNumber(UNIVERSAL_PREMIUM_RATE));
 
     PhoneNumber nzNumber = new PhoneNumber().setCountryCode(64).setNationalNumber(21387835L);
     assertTrue(phoneUtil.isValidNumber(nzNumber));
     assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForCountryCode(44));
     assertEquals(RegionCode.DE, phoneUtil.getRegionCodeForCountryCode(49));