Update libphonenumber to v6.1

Change-Id: I4a8cfbacf69da3840aa5286a756fb3f3bd8bc1b0
diff --git a/README.android b/README.android
index dd1dc5e..4eb0e38 100644
--- a/README.android
+++ b/README.android
@@ -1,5 +1,5 @@
 URL: http://code.google.com/p/libphonenumber/
-Version: 6.0 (r653)
+Version: 6.1 (r658)
 License: Apache 2
 Description: Google Phone Number Library.
 Local Modification:
diff --git a/java/release_notes.txt b/java/release_notes.txt
index a5a58ea..19c7388 100644
--- a/java/release_notes.txt
+++ b/java/release_notes.txt
@@ -1,3 +1,25 @@
+May 08, 2014: libphonenumber-6.1
+* Code changes:
+ - Adding MetadataLoader support to allow custom metadata loading from
+   alternative sources (should have no visible impact to users).
+ - Fixing bug where digits could be lost in as-you-type formatting and
+   formatting patterns incorrectly applied.
+
+* Metadata changes:
+ - Updated phone metadata for region code(s):
+   AR, BF, BR, BS, CL, CN, CO, CR, DE, DM, EC, EG, FR, GA, GD, GH, HU, ID, IL,
+   IN, JP, KH, KI, KN, LA, LC, LR, ML, MU, MX, MZ, NA, NE, PF, PL, RU, SM, TH,
+   TW, UZ, VA, VC
+ - Updated short number metadata for region code(s): BI, CR, PL, TH
+ - New geocoding data for country calling code(s): 32 (de), 1242 (en)
+ - Updated geocoding data for country calling code(s):
+   32 (en, nl), 55 (en), 56 (en, es), 86 (en, zh)
+ - New carrier data for country calling code(s):
+   1758 (en), 1784 (en), 1869 (en)
+ - Updated carrier data for country calling code(s):
+   66 (en), 86 (en), 227 (en), 231 (en), 233 (en), 258 (en), 1473 (en),
+   1767 (en)
+
 Feb 25, 2014: libphonenumber-6.0
 * Code changes:
  - Better support for detecting phone numbers in text that are beside each other
diff --git a/java/src/com/android/i18n/phonenumbers/AsYouTypeFormatter.java b/java/src/com/android/i18n/phonenumbers/AsYouTypeFormatter.java
index 4671671..790e66b 100644
--- a/java/src/com/android/i18n/phonenumbers/AsYouTypeFormatter.java
+++ b/java/src/com/android/i18n/phonenumbers/AsYouTypeFormatter.java
@@ -172,7 +172,7 @@
     return false;
   }
 
-  private void getAvailableFormats(String leadingThreeDigits) {
+  private void getAvailableFormats(String leadingDigits) {
     List<NumberFormat> formatList =
         (isCompleteNumber && currentMetadata.intlNumberFormatSize() > 0)
         ? currentMetadata.intlNumberFormats()
@@ -187,7 +187,7 @@
         }
       }
     }
-    narrowDownPossibleFormats(leadingThreeDigits);
+    narrowDownPossibleFormats(leadingDigits);
   }
 
   private boolean isFormatEligible(String format) {
@@ -199,16 +199,18 @@
     Iterator<NumberFormat> it = possibleFormats.iterator();
     while (it.hasNext()) {
       NumberFormat format = it.next();
-      if (format.leadingDigitsPatternSize() > indexOfLeadingDigitsPattern) {
-        Pattern leadingDigitsPattern =
-            regexCache.getPatternForRegex(
-                format.getLeadingDigitsPattern(indexOfLeadingDigitsPattern));
-        Matcher m = leadingDigitsPattern.matcher(leadingDigits);
-        if (!m.lookingAt()) {
-          it.remove();
-        }
-      } // else the particular format has no more specific leadingDigitsPattern, and it should be
-        // retained.
+      if (format.leadingDigitsPatternSize() == 0) {
+        // Keep everything that isn't restricted by leading digits.
+        continue;
+      }
+      int lastLeadingDigitsPattern =
+          Math.min(indexOfLeadingDigitsPattern, format.leadingDigitsPatternSize() - 1);
+      Pattern leadingDigitsPattern = regexCache.getPatternForRegex(
+          format.getLeadingDigitsPattern(lastLeadingDigitsPattern));
+      Matcher m = leadingDigitsPattern.matcher(leadingDigits);
+      if (!m.lookingAt()) {
+        it.remove();
+      }
     }
   }
 
@@ -362,7 +364,7 @@
           }
           return prefixBeforeNationalNumber + nationalNumber.toString();
         }
-        if (possibleFormats.size() > 0) {  // The formatting pattern is already chosen.
+        if (possibleFormats.size() > 0) {  // The formatting patterns are already chosen.
           String tempNationalNumber = inputDigitHelper(nextChar);
           // See if the accrued digits can be formatted properly already. If not, use the results
           // from inputDigitHelper, which does formatting based on the formatting pattern chosen.
@@ -481,7 +483,8 @@
     // We start to attempt to format only when at least MIN_LEADING_DIGITS_LENGTH digits of national
     // number (excluding national prefix) have been entered.
     if (nationalNumber.length() >= MIN_LEADING_DIGITS_LENGTH) {
-      getAvailableFormats(nationalNumber.substring(0, MIN_LEADING_DIGITS_LENGTH));
+
+      getAvailableFormats(nationalNumber.toString());
       // See if the accrued digits can be formatted properly already.
       String formattedNumber = attemptToFormatAccruedDigits();
       if (formattedNumber.length() > 0) {
diff --git a/java/src/com/android/i18n/phonenumbers/MetadataLoader.java b/java/src/com/android/i18n/phonenumbers/MetadataLoader.java
new file mode 100644
index 0000000..1937dc9
--- /dev/null
+++ b/java/src/com/android/i18n/phonenumbers/MetadataLoader.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Libphonenumber Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.i18n.phonenumbers;
+
+import java.io.InputStream;
+
+/**
+ * Interface for caller to specify a customized phone metadata loader.
+ */
+public interface MetadataLoader {
+  /**
+   * Returns an input stream corresponding to the metadata to load.
+   *
+   * @param metadataFileName File name (including path) of metadata to load. File path is an
+   *     absolute class path like /com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto.
+   * @return The input stream for the metadata file. The library will close this stream
+   *     after it is done. Return null in case the metadata file could not be found.
+   */
+  public InputStream loadMetadata(String metadataFileName);
+}
diff --git a/java/src/com/android/i18n/phonenumbers/PhoneNumberUtil.java b/java/src/com/android/i18n/phonenumbers/PhoneNumberUtil.java
index ebb9712..bd36708 100644
--- a/java/src/com/android/i18n/phonenumbers/PhoneNumberUtil.java
+++ b/java/src/com/android/i18n/phonenumbers/PhoneNumberUtil.java
@@ -56,6 +56,13 @@
  * @author Shaopeng Jia
  */
 public class PhoneNumberUtil {
+  // @VisibleForTesting
+  static final MetadataLoader DEFAULT_METADATA_LOADER = new MetadataLoader() {
+    public InputStream loadMetadata(String metadataFileName) {
+      return PhoneNumberUtil.class.getResourceAsStream(metadataFileName);
+    }
+  };
+
   private static final Logger logger = Logger.getLogger(PhoneNumberUtil.class.getName());
 
   /** Flags to use when compiling regular expressions for phone numbers. */
@@ -69,7 +76,8 @@
   // We don't allow input strings for parsing to be longer than 250 chars. This prevents malicious
   // input from overflowing the regular-expression engine.
   private static final int MAX_INPUT_STRING_LENGTH = 250;
-  static final String META_DATA_FILE_PREFIX =
+
+  private static final String META_DATA_FILE_PREFIX =
       "/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto";
 
   // Region-code for the unknown region.
@@ -565,13 +573,17 @@
 
   // The prefix of the metadata files from which region data is loaded.
   private final String currentFilePrefix;
+  // The metadata loader used to inject alternative metadata sources.
+  private final MetadataLoader metadataLoader;
 
   /**
    * This class implements a singleton, so the only constructor is private.
    */
-  private PhoneNumberUtil(String filePrefix,
+  // @VisibleForTesting
+  PhoneNumberUtil(String filePrefix, MetadataLoader metadataLoader,
       Map<Integer, List<String>> countryCallingCodeToRegionCodeMap) {
     this.currentFilePrefix = filePrefix;
+    this.metadataLoader = metadataLoader;
     this.countryCallingCodeToRegionCodeMap = countryCallingCodeToRegionCodeMap;
     for (Map.Entry<Integer, List<String>> entry : countryCallingCodeToRegionCodeMap.entrySet()) {
       List<String> regionCodes = entry.getValue();
@@ -596,11 +608,12 @@
   }
 
   // @VisibleForTesting
-  void loadMetadataFromFile(String filePrefix, String regionCode, int countryCallingCode) {
+  void loadMetadataFromFile(String filePrefix, String regionCode, int countryCallingCode,
+      MetadataLoader metadataLoader) {
     boolean isNonGeoRegion = REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode);
     String fileName = filePrefix + "_" +
         (isNonGeoRegion ? String.valueOf(countryCallingCode) : regionCode);
-    InputStream source = PhoneNumberUtil.class.getResourceAsStream(fileName);
+    InputStream source = metadataLoader.loadMetadata(fileName);
     if (source == null) {
       logger.log(Level.SEVERE, "missing metadata: " + fileName);
       throw new IllegalStateException("missing metadata: " + fileName);
@@ -637,7 +650,7 @@
    * @param source  the non-null stream from which metadata is to be read.
    * @return        the loaded metadata protocol buffer.
    */
-  private static PhoneMetadataCollection loadMetadataAndCloseInput(ObjectInput source) {
+  private static PhoneMetadataCollection loadMetadataAndCloseInput(ObjectInputStream source) {
     PhoneMetadataCollection metadataCollection = new PhoneMetadataCollection();
     try {
       metadataCollection.readExternal(source);
@@ -960,26 +973,12 @@
   }
 
   /**
-   * An unsafe version of getInstance() which must only be used for testing purposes.
+   * Sets or resets the PhoneNumberUtil singleton instance. If set to null, the next call to
+   * {@code getInstance()} will load (and return) the default instance.
    */
   // @VisibleForTesting
-  static synchronized PhoneNumberUtil getInstance(
-      String baseFileLocation,
-      Map<Integer, List<String>> countryCallingCodeToRegionCodeMap) {
-    if (instance != null) {
-      throw new IllegalStateException(
-          "PhoneNumberUtil instance is already set (you should call resetInstance() first)");
-    }
-    instance = new PhoneNumberUtil(baseFileLocation, countryCallingCodeToRegionCodeMap);
-    return instance;
-  }
-
-  /**
-   * Used for testing purposes only to reset the PhoneNumberUtil singleton to null.
-   */
-  // @VisibleForTesting
-  static synchronized void resetInstance() {
-    instance = null;
+  static synchronized void setInstance(PhoneNumberUtil util) {
+    instance = util;
   }
 
   /**
@@ -1009,13 +1008,33 @@
    */
   public static synchronized PhoneNumberUtil getInstance() {
     if (instance == null) {
-      return getInstance(META_DATA_FILE_PREFIX,
-          CountryCodeToRegionCodeMap.getCountryCodeToRegionCodeMap());
+      setInstance(createInstance(DEFAULT_METADATA_LOADER));
     }
     return instance;
   }
 
   /**
+   * Create a new {@link PhoneNumberUtil} instance to carry out international phone number
+   * formatting, parsing, or validation. The instance is loaded with all metadata by
+   * using the metadataLoader specified.
+   *
+   * This method should only be used in the rare case in which you want to manage your own
+   * metadata loading. Calling this method multiple times is very expensive, as each time
+   * a new instance is created from scratch. When in doubt, use {@link #getInstance}.
+   *
+   * @param metadataLoader Customized metadata loader. If null, default metadata loader will
+   *     be used. This should not be null.
+   * @return a PhoneNumberUtil instance
+   */
+  public static PhoneNumberUtil createInstance(MetadataLoader metadataLoader) {
+    if (metadataLoader == null) {
+      throw new IllegalArgumentException("metadataLoader could not be null.");
+    }
+    return new PhoneNumberUtil(META_DATA_FILE_PREFIX, metadataLoader,
+        CountryCodeToRegionCodeMap.getCountryCodeToRegionCodeMap());
+  }
+
+  /**
    * Helper function to check if the national prefix formatting rule has the first group only, i.e.,
    * does not start with the national prefix.
    */
@@ -2011,7 +2030,7 @@
       if (!regionToMetadataMap.containsKey(regionCode)) {
         // The regionCode here will be valid and won't be '001', so we don't need to worry about
         // what to pass in for the country calling code.
-        loadMetadataFromFile(currentFilePrefix, regionCode, 0);
+        loadMetadataFromFile(currentFilePrefix, regionCode, 0, metadataLoader);
       }
     }
     return regionToMetadataMap.get(regionCode);
@@ -2023,7 +2042,8 @@
         return null;
       }
       if (!countryCodeToNonGeographicalMetadataMap.containsKey(countryCallingCode)) {
-        loadMetadataFromFile(currentFilePrefix, REGION_CODE_FOR_NON_GEO_ENTITY, countryCallingCode);
+        loadMetadataFromFile(
+            currentFilePrefix, REGION_CODE_FOR_NON_GEO_ENTITY, countryCallingCode, metadataLoader);
       }
     }
     return countryCodeToNonGeographicalMetadataMap.get(countryCallingCode);
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR
index 9ffae28..223a753 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
index b9f463b..3bee242 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
index bbc8245..5f4ef06 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS
index fb08b89..fadbeae 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL
index f46c263..4a1a605 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN
index 899fe06..576f2ce 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO
index 66f255d..2a68fc3 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR
index ded0053..000c160 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE
index d249ad2..2d3a656 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM
index a380527..590614d 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC
index 6bdc388..7d1eecc 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG
index 28819f9..7511ce6 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR
index 4f8a5f2..4548f4b 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA
index ae00edd..ffaca37 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD
index f97545c..b1efd3e 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH
index 6a52b4f..cd8b59a 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU
index c1334ea..0da8402 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID
index fd96b0e..86f9385 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL
index a320227..f715319 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN
index 23aa980..3a375c7 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP
index 59628f4..ddfad7b 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH
index 6a38007..46dab59 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI
index 320f964..1be3aa8 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN
index ca4ffc2..4f224bd 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA
index 598afa0..17f888f 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC
index 8e74fdd..dd9f1ca 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR
index 26162f3..428ad11 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML
index ae62086..b14c8bb 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU
index f9eff07..63676ca 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX
index 655e2f7..7dd414a 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ
index 3350516..65b2f1f 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA
index d3657c7..f8d7049 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE
index 9ee87d7..8d0e16c 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF
index 54e741c..6ade89d 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL
index 1f4f529..491de26 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU
index 97177a1..c769356 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM
index 8a4093c..4294cf9 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH
index ad7eb15..b60fc07 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW
index 3a2e7d9..de246f5 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ
index 263c096..1711a97 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA
index 2599325..72c260f 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC
index a135a11..c1be6f7 100644
--- a/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC
+++ b/java/src/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_BI b/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_BI
index 86540b6..a0eacfd 100644
--- a/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_BI
+++ b/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_BI
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_CR b/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_CR
index 8b74ec9..cbc2628 100644
--- a/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_CR
+++ b/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_CR
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_PL b/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_PL
index ceb409e..ae1b620 100644
--- a/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_PL
+++ b/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_PL
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_TH b/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_TH
index 8834e85..60bd59b 100644
--- a/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_TH
+++ b/java/src/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto_TH
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/1242_en b/java/src/com/android/i18n/phonenumbers/geocoding/data/1242_en
new file mode 100644
index 0000000..cd7ef42
--- /dev/null
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/1242_en
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/32_de b/java/src/com/android/i18n/phonenumbers/geocoding/data/32_de
new file mode 100644
index 0000000..e483050
--- /dev/null
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/32_de
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/32_en b/java/src/com/android/i18n/phonenumbers/geocoding/data/32_en
index 0bd8b56..8b04552 100644
--- a/java/src/com/android/i18n/phonenumbers/geocoding/data/32_en
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/32_en
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/32_nl b/java/src/com/android/i18n/phonenumbers/geocoding/data/32_nl
index 74a5c6c..4f4f0d9 100644
--- a/java/src/com/android/i18n/phonenumbers/geocoding/data/32_nl
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/32_nl
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/55_en b/java/src/com/android/i18n/phonenumbers/geocoding/data/55_en
index 753576a..61697eb 100644
--- a/java/src/com/android/i18n/phonenumbers/geocoding/data/55_en
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/55_en
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/56_en b/java/src/com/android/i18n/phonenumbers/geocoding/data/56_en
index fa097e8..074b9d7 100644
--- a/java/src/com/android/i18n/phonenumbers/geocoding/data/56_en
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/56_en
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/56_es b/java/src/com/android/i18n/phonenumbers/geocoding/data/56_es
index c86ff79..f55b59f 100644
--- a/java/src/com/android/i18n/phonenumbers/geocoding/data/56_es
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/56_es
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/86_en b/java/src/com/android/i18n/phonenumbers/geocoding/data/86_en
index f012dc0..8fd663b 100644
--- a/java/src/com/android/i18n/phonenumbers/geocoding/data/86_en
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/86_en
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/86_zh b/java/src/com/android/i18n/phonenumbers/geocoding/data/86_zh
index 6ec9d0b..406d851 100644
--- a/java/src/com/android/i18n/phonenumbers/geocoding/data/86_zh
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/86_zh
Binary files differ
diff --git a/java/src/com/android/i18n/phonenumbers/geocoding/data/config b/java/src/com/android/i18n/phonenumbers/geocoding/data/config
index e6807dd..5cb01c1 100644
--- a/java/src/com/android/i18n/phonenumbers/geocoding/data/config
+++ b/java/src/com/android/i18n/phonenumbers/geocoding/data/config
Binary files differ
diff --git a/java/test/com/android/i18n/phonenumbers/AsYouTypeFormatterTest.java b/java/test/com/android/i18n/phonenumbers/AsYouTypeFormatterTest.java
index 478ca86..b743a9e 100644
--- a/java/test/com/android/i18n/phonenumbers/AsYouTypeFormatterTest.java
+++ b/java/test/com/android/i18n/phonenumbers/AsYouTypeFormatterTest.java
@@ -1149,4 +1149,25 @@
     assertEquals("007001234567890123456", formatter.inputDigit('6'));
     assertEquals("0070012345678901234567", formatter.inputDigit('7'));
   }
+
+  public void testAYTFNumberPatternsBecomingInvalidShouldNotResultInDigitLoss() {
+    AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.CN);
+
+    assertEquals("+", formatter.inputDigit('+'));
+    assertEquals("+8", formatter.inputDigit('8'));
+    assertEquals("+86 ", formatter.inputDigit('6'));
+    assertEquals("+86 9", formatter.inputDigit('9'));
+    assertEquals("+86 98", formatter.inputDigit('8'));
+    assertEquals("+86 988", formatter.inputDigit('8'));
+    assertEquals("+86 988 1", formatter.inputDigit('1'));
+    // Now the number pattern is no longer valid because there are multiple leading digit patterns;
+    // when we try again to extract a country code we should ensure we use the last leading digit
+    // pattern, rather than the first one such that it *thinks* it's found a valid formatting rule
+    // again.
+    // https://code.google.com/p/libphonenumber/issues/detail?id=437
+    assertEquals("+8698812", formatter.inputDigit('2'));
+    assertEquals("+86988123", formatter.inputDigit('3'));
+    assertEquals("+869881234", formatter.inputDigit('4'));
+    assertEquals("+8698812345", formatter.inputDigit('5'));
+  }
 }
diff --git a/java/test/com/android/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java b/java/test/com/android/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java
index 0a972cd..3b55b83 100644
--- a/java/test/com/android/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java
+++ b/java/test/com/android/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java
@@ -31,10 +31,10 @@
   // 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 29 as there are 22 different entries,
+    // The capacity is set to 30 as there are 23 different entries,
     // and this offers a load factor of roughly 0.75.
     Map<Integer, List<String>> countryCodeToRegionCodeMap =
-        new HashMap<Integer, List<String>>(29);
+        new HashMap<Integer, List<String>>(30);
 
     ArrayList<String> listWithRegionCode;
 
@@ -103,6 +103,10 @@
     countryCodeToRegionCodeMap.put(82, listWithRegionCode);
 
     listWithRegionCode = new ArrayList<String>(1);
+    listWithRegionCode.add("CN");
+    countryCodeToRegionCodeMap.put(86, listWithRegionCode);
+
+    listWithRegionCode = new ArrayList<String>(1);
     listWithRegionCode.add("AO");
     countryCodeToRegionCodeMap.put(244, listWithRegionCode);
 
diff --git a/java/test/com/android/i18n/phonenumbers/ExampleNumbersTest.java b/java/test/com/android/i18n/phonenumbers/ExampleNumbersTest.java
index c7ffbb9..46f37ab 100644
--- a/java/test/com/android/i18n/phonenumbers/ExampleNumbersTest.java
+++ b/java/test/com/android/i18n/phonenumbers/ExampleNumbersTest.java
@@ -35,29 +35,12 @@
  */
 public class ExampleNumbersTest extends TestCase {
   private static final Logger LOGGER = Logger.getLogger(ExampleNumbersTest.class.getName());
-  private PhoneNumberUtil phoneNumberUtil;
-  private ShortNumberInfo shortNumberInfo;
+  private PhoneNumberUtil phoneNumberUtil =
+      PhoneNumberUtil.createInstance(PhoneNumberUtil.DEFAULT_METADATA_LOADER);
+  private ShortNumberInfo shortNumberInfo = new ShortNumberInfo(phoneNumberUtil);
   private List<PhoneNumber> invalidCases = new ArrayList<PhoneNumber>();
   private List<PhoneNumber> wrongTypeCases = new ArrayList<PhoneNumber>();
 
-  public ExampleNumbersTest() {
-    PhoneNumberUtil.resetInstance();
-    phoneNumberUtil = PhoneNumberUtil.getInstance();
-    shortNumberInfo = new ShortNumberInfo(phoneNumberUtil);
-  }
-
-  @Override
-  protected void setUp() throws Exception {
-    super.setUp();
-    invalidCases.clear();
-    wrongTypeCases.clear();
-  }
-
-  @Override
-  protected void tearDown() throws Exception {
-    super.tearDown();
-  }
-
   /**
    * @param exampleNumberRequestedType  type we are requesting an example number for
    * @param possibleExpectedTypes       acceptable types that this number should match, such as
diff --git a/java/test/com/android/i18n/phonenumbers/PhoneNumberUtilTest.java b/java/test/com/android/i18n/phonenumbers/PhoneNumberUtilTest.java
index d8720cb..997430a 100644
--- a/java/test/com/android/i18n/phonenumbers/PhoneNumberUtilTest.java
+++ b/java/test/com/android/i18n/phonenumbers/PhoneNumberUtilTest.java
@@ -126,14 +126,15 @@
     // exist. However if the library is packaged incorrectly in the jar, this could happen and the
     // best we can do is make sure the exception has the file name in it.
     try {
-      phoneUtil.loadMetadataFromFile("no/such/file", "XX", -1);
+      phoneUtil.loadMetadataFromFile(
+          "no/such/file", "XX", -1, PhoneNumberUtil.DEFAULT_METADATA_LOADER);
       fail("expected exception");
     } catch (RuntimeException e) {
       assertTrue("Unexpected error: " + e, e.toString().contains("no/such/file_XX"));
     }
     try {
-      phoneUtil.loadMetadataFromFile(
-          "no/such/file", PhoneNumberUtil.REGION_CODE_FOR_NON_GEO_ENTITY, 123);
+      phoneUtil.loadMetadataFromFile("no/such/file", PhoneNumberUtil.REGION_CODE_FOR_NON_GEO_ENTITY,
+          123, PhoneNumberUtil.DEFAULT_METADATA_LOADER);
       fail("expected exception");
     } catch (RuntimeException e) {
       assertTrue("Unexpected error: " + e, e.getMessage().contains("no/such/file_123"));
diff --git a/java/test/com/android/i18n/phonenumbers/TestMetadataTestCase.java b/java/test/com/android/i18n/phonenumbers/TestMetadataTestCase.java
index 8075d9f..6e7ad7f 100644
--- a/java/test/com/android/i18n/phonenumbers/TestMetadataTestCase.java
+++ b/java/test/com/android/i18n/phonenumbers/TestMetadataTestCase.java
@@ -37,10 +37,10 @@
   }
 
   static PhoneNumberUtil initializePhoneUtilForTesting() {
-    PhoneNumberUtil.resetInstance();
-    PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(
-        TEST_META_DATA_FILE_PREFIX,
+    PhoneNumberUtil phoneUtil = new PhoneNumberUtil(
+        TEST_META_DATA_FILE_PREFIX, PhoneNumberUtil.DEFAULT_METADATA_LOADER,
         CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap());
+    PhoneNumberUtil.setInstance(phoneUtil);
     return phoneUtil;
   }
 }
diff --git a/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR b/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR
index e0b862f..7d7fb24 100644
--- a/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR
+++ b/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR
Binary files differ
diff --git a/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_CN b/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_CN
new file mode 100644
index 0000000..9741b32
--- /dev/null
+++ b/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_CN
Binary files differ
diff --git a/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX b/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX
index 6894906..ff509e7 100644
--- a/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX
+++ b/java/test/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX
Binary files differ