diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d9a10c0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,176 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..532bd0a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,76 @@
+# libPhoneNumber for iOS (ARC)
+
+* NBPhoneNumber, NBNumberFormat, NBPhoneNumberDesc, NBPhoneMetaData (Metadata classes) 
+
+* NBPhoneNumberUtil (from phonenumberutil.js)
+* NBAsYouTypeFormatter 
+
+## Install with CocoaPods
+### Use [CocoaPods](http://cocoapods.org/?q=libPhoneNumber-iOS)
+
+## Install without CocoaPods
+### Add source files to your projects from libPhoneNumber
+    - NBPhoneNumberUtil.h, .m
+    - NBAsYouTypeFormatter.h, .m
+    
+    - NBNumberFormat.h, .m
+    - NBPhoneNumber.h, .m
+    - NBPhoneNumberDesc.h, .m
+    - NBPhoneNumberDefines.h
+    
+    - NBPhoneNumberMetadata.h, .m
+    - NBPhoneNumberMetadataForTesting.h, .m
+    
+    - Add "NBPhoneNumberMetadata.plist" and "NBPhoneNumberMetadataForTesting.plist" to bundle resources
+    - Add "CoreTelephony.framework"
+
+    See sample test code from "libPhoneNumber-iOS / libPhoneNumberTests / libPhoneNumberTests.m"
+
+## Sample Usage
+    NBPhoneNumberUtil *phoneUtil = [NBPhoneNumberUtil sharedInstance];
+    
+    NSError *aError = nil;
+    NBPhoneNumber *myNumber = [phoneUtil parse:@"6766077303" defaultRegion:@"AT" error:&aError];
+    
+    if (aError == nil) {
+        // Should check error
+        NSLog(@"isValidPhoneNumber ? [%@]", [phoneUtil isValidNumber:myNumber] ? @"YES":@"NO");
+        NSLog(@"E164          : %@", [phoneUtil format:myNumber numberFormat:NBEPhoneNumberFormatE164 
+                                                 error:&aError]);
+        NSLog(@"INTERNATIONAL : %@", [phoneUtil format:myNumber numberFormat:NBEPhoneNumberFormatINTERNATIONAL 
+                                                 error:&aError]);
+        NSLog(@"NATIONAL      : %@", [phoneUtil format:myNumber numberFormat:NBEPhoneNumberFormatNATIONAL 
+                                                 error:&aError]);
+        NSLog(@"RFC3966       : %@", [phoneUtil format:myNumber numberFormat:NBEPhoneNumberFormatRFC3966 
+                                                 error:&aError]);
+    }
+    else {
+        NSLog(@"Error : %@", [aError localizedDescription]);
+    }
+    
+    NSLog (@"extractCountryCode [%ld]", [phoneUtil extractCountryCode:@"823213123123" 
+                                                       nationalNumber:nil]);
+    
+    NSString *res = nil;
+    UInt32 dRes = [phoneUtil extractCountryCode:@"823213123123" nationalNumber:&res];
+    
+    NSLog (@"extractCountryCode [%lu] [%@]", dRes, res);
+
+
+### Visit http://code.google.com/p/libphonenumber/ for more information
+#### or zen.isis@gmail.com
+
+## Metadata managing (updating metadata) 
+#### Step1. Fetch "metadata.js" and "metadatafortesting.js" from Repositories
+    svn checkout http://libphonenumber.googlecode.com/svn/trunk/ libphonenumber-read-only
+      
+#### Step2. Convert Javascript Object to JSON using PHP scripts 
+    Output - "PhoneNumberMetaData.json" and "PhoneNumberMetaDataForTesting.json"
+
+#### Step3. Generate binary file from NBPhoneMetaDataGenerator
+    Output - "NBPhoneNumberMetadata.plist" and "NBPhoneNumberMetadataForTesting.plist"
+
+#### Step4. Update exists "NBPhoneNumberMetadata.plist" and "NBPhoneNumberMetadataForTesting.plist" files
+
+## Porting Rules
+* **Remain** javascript libPhonenumber code logic (and comments etc) as possible for maintenance with *.js
diff --git a/libPhoneNumber/NBAsYouTypeFormatter.h b/libPhoneNumber/NBAsYouTypeFormatter.h
new file mode 100644
index 0000000..c994fd5
--- /dev/null
+++ b/libPhoneNumber/NBAsYouTypeFormatter.h
@@ -0,0 +1,21 @@
+//
+//  NBAsYouTypeFormatter.h
+//  libPhoneNumber
+//
+//  Created by ishtar on 13. 2. 25..
+//  Copyright (c) 2013년 NHN. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NBAsYouTypeFormatter : NSObject
+
+- (id)initWithRegionCode:(NSString*)regionCode;
+- (id)initWithRegionCodeForTest:(NSString*)regionCode;
+
+- (NSString*)inputDigit:(NSString*)nextChar;
+- (NSString*)inputDigitAndRememberPosition:(NSString*)nextChar;
+- (NSInteger)getRememberedPosition;
+- (void)clear;
+
+@end
diff --git a/libPhoneNumber/NBAsYouTypeFormatter.m b/libPhoneNumber/NBAsYouTypeFormatter.m
new file mode 100644
index 0000000..742199d
--- /dev/null
+++ b/libPhoneNumber/NBAsYouTypeFormatter.m
@@ -0,0 +1,1146 @@
+//
+//  NBAsYouTypeFormatter.m
+//  libPhoneNumber
+//
+//  Created by ishtar on 13. 2. 25..
+//  Copyright (c) 2013년 NHN. All rights reserved.
+//
+
+#import "NBAsYouTypeFormatter.h"
+
+#import "NBPhoneNumberUtil.h"
+#import "NBPhoneMetaData.h"
+#import "NBNumberFormat.h"
+
+
+@interface NBAsYouTypeFormatter ()
+
+@property (nonatomic, strong, readwrite) NSString *DIGIT_PLACEHOLDER_;
+@property (nonatomic, assign, readwrite) NSString *SEPARATOR_BEFORE_NATIONAL_NUMBER_;
+@property (nonatomic, strong, readwrite) NSString *currentOutput_, *currentFormattingPattern_;
+@property (nonatomic, strong, readwrite) NSString *defaultCountry_;
+@property (nonatomic, strong, readwrite) NSString *nationalPrefixExtracted_;
+@property (nonatomic, strong, readwrite) NSMutableString *formattingTemplate_, *accruedInput_, *prefixBeforeNationalNumber_, *accruedInputWithoutFormatting_, *nationalNumber_;
+@property (nonatomic, strong, readwrite) NSRegularExpression *DIGIT_PATTERN_, *NATIONAL_PREFIX_SEPARATORS_PATTERN_, *CHARACTER_CLASS_PATTERN_, *STANDALONE_DIGIT_PATTERN_;
+@property (nonatomic, strong, readwrite) NSRegularExpression *ELIGIBLE_FORMAT_PATTERN_;
+@property (nonatomic, assign, readwrite) BOOL ableToFormat_, inputHasFormatting_, isCompleteNumber_, isExpectingCountryCallingCode_, shouldAddSpaceAfterNationalPrefix_;
+@property (nonatomic, strong, readwrite) NBPhoneNumberUtil *phoneUtil_;
+@property (nonatomic, assign, readwrite) NSUInteger lastMatchPosition_, originalPosition_, positionToRemember_;
+@property (nonatomic, assign, readwrite) NSUInteger MIN_LEADING_DIGITS_LENGTH_;
+@property (nonatomic, strong, readwrite) NSMutableArray *possibleFormats_;
+@property (nonatomic, strong, readwrite) NBPhoneMetaData *currentMetaData_, *defaultMetaData_, *EMPTY_METADATA_;
+
+@end
+
+
+@implementation NBAsYouTypeFormatter
+
+- (id)init
+{
+    self = [super init];
+    
+    if (self) {
+        /**
+         * @type {i18n.phonenumbers.PhoneNumberUtil}
+         * @private
+         */
+        self.phoneUtil_ = [NBPhoneNumberUtil sharedInstance];
+        
+        /**
+         * The digits that have not been entered yet will be represented by a \u2008,
+         * the punctuation space.
+         * @const
+         * @type {string}
+         * @private
+         */
+        self.DIGIT_PLACEHOLDER_ = @"\u2008";
+        
+        /**
+         * Character used when appropriate to separate a prefix, such as a long NDD or a
+         * country calling code, from the national number.
+         * @const
+         * @type {string}
+         * @private
+         */
+        self.SEPARATOR_BEFORE_NATIONAL_NUMBER_ = @" ";
+        
+        /**
+         * This is the minimum length of national number accrued that is required to
+         * trigger the formatter. The first element of the leadingDigitsPattern of
+         * each numberFormat contains a regular expression that matches up to this
+         * number of digits.
+         * @const
+         * @type {number}
+         * @private
+         */
+        self.MIN_LEADING_DIGITS_LENGTH_ = 3;
+        
+        /**
+         * @type {string}
+         * @private
+         */
+        self.currentOutput_ = @"";
+        
+        /**
+         * @type {!goog.string.StringBuffer}
+         * @private
+         */
+        self.formattingTemplate_ = [NSMutableString stringWithString:@""];
+        
+        NSError *aError = nil;
+        
+        /**
+         * @type {RegExp}
+         * @private
+         */
+        self.DIGIT_PATTERN_ = [NSRegularExpression regularExpressionWithPattern:self.DIGIT_PLACEHOLDER_ options:0 error:&aError];
+        
+        /**
+         * A set of characters that, if found in a national prefix formatting rules, are
+         * an indicator to us that we should separate the national prefix from the
+         * number when formatting.
+         * @const
+         * @type {RegExp}
+         * @private
+         */
+        self.NATIONAL_PREFIX_SEPARATORS_PATTERN_ = [NSRegularExpression regularExpressionWithPattern:@"[- ]" options:0 error:&aError];
+        
+        /**
+         * A pattern that is used to match character classes in regular expressions.
+         * An example of a character class is [1-4].
+         * @const
+         * @type {RegExp}
+         * @private
+         */
+        self.CHARACTER_CLASS_PATTERN_ = [NSRegularExpression regularExpressionWithPattern:@"\\[([^\\[\\]])*\\]" options:0 error:&aError];
+        
+        /**
+         * Any digit in a regular expression that actually denotes a digit. For
+         * example, in the regular expression 80[0-2]\d{6,10}, the first 2 digits
+         * (8 and 0) are standalone digits, but the rest are not.
+         * Two look-aheads are needed because the number following \\d could be a
+         * two-digit number, since the phone number can be as long as 15 digits.
+         * @const
+         * @type {RegExp}
+         * @private
+         */
+        self.STANDALONE_DIGIT_PATTERN_ = [NSRegularExpression regularExpressionWithPattern:@"\\d(?=[^,}][^,}])" options:0 error:&aError];
+        
+        /**
+         * A pattern that is used to determine if a numberFormat under availableFormats
+         * is eligible to be used by the AYTF. It is eligible when the format element
+         * under numberFormat contains groups of the dollar sign followed by a single
+         * digit, separated by valid phone number punctuation. This prevents invalid
+         * punctuation (such as the star sign in Israeli star numbers) getting into the
+         * output of the AYTF.
+         * @const
+         * @type {RegExp}
+         * @private
+         */
+        NSString *eligible_format = @"^[-x‐-―−ー－-／ ­​⁠　()（）［］.\\[\\]/~⁓∼～]*(\\$\\d[-x‐-―−ー－-／ ­​⁠　()（）［］.\\[\\]/~⁓∼～]*)+$";
+        self.ELIGIBLE_FORMAT_PATTERN_ = [NSRegularExpression regularExpressionWithPattern:eligible_format options:0 error:&aError];
+        
+        /**
+         * The pattern from numberFormat that is currently used to create
+         * formattingTemplate.
+         * @type {string}
+         * @private
+         */
+        self.currentFormattingPattern_ = @"";
+        
+        /**
+         * @type {!goog.string.StringBuffer}
+         * @private
+         */
+        self.accruedInput_ = [NSMutableString stringWithString:@""];
+        
+        /**
+         * @type {!goog.string.StringBuffer}
+         * @private
+         */
+        self.accruedInputWithoutFormatting_ = [NSMutableString stringWithString:@""];
+        
+        /**
+         * This indicates whether AsYouTypeFormatter is currently doing the
+         * formatting.
+         * @type {BOOL}
+         * @private
+         */
+        self.ableToFormat_ = YES;
+        
+        /**
+         * Set to YES when users enter their own formatting. AsYouTypeFormatter will
+         * do no formatting at all when this is set to YES.
+         * @type {BOOL}
+         * @private
+         */
+        self.inputHasFormatting_ = NO;
+        
+        /**
+         * This is set to YES when we know the user is entering a full national
+         * significant number, since we have either detected a national prefix or an
+         * international dialing prefix. When this is YES, we will no longer use
+         * local number formatting patterns.
+         * @type {BOOL}
+         * @private
+         */
+        self.isCompleteNumber_ = NO;
+        
+        /**
+         * @type {BOOL}
+         * @private
+         */
+        self.isExpectingCountryCallingCode_ = NO;
+        
+        /**
+         * @type {number}
+         * @private
+         */
+        self.lastMatchPosition_ = 0;
+        
+        /**
+         * The position of a digit upon which inputDigitAndRememberPosition is most
+         * recently invoked, as found in the original sequence of characters the user
+         * entered.
+         * @type {number}
+         * @private
+         */
+        self.originalPosition_ = 0;
+        
+        /**
+         * The position of a digit upon which inputDigitAndRememberPosition is most
+         * recently invoked, as found in accruedInputWithoutFormatting.
+         * entered.
+         * @type {number}
+         * @private
+         */
+        self.positionToRemember_ = 0;
+        
+        /**
+         * This contains anything that has been entered so far preceding the national
+         * significant number, and it is formatted (e.g. with space inserted). For
+         * example, this can contain IDD, country code, and/or NDD, etc.
+         * @type {!goog.string.StringBuffer}
+         * @private
+         */
+        self.prefixBeforeNationalNumber_ = [NSMutableString stringWithString:@""];
+        
+        /**
+         * @type {BOOL}
+         * @private
+         */
+        self.shouldAddSpaceAfterNationalPrefix_ = NO;
+        
+        /**
+         * This contains the national prefix that has been extracted. It contains only
+         * digits without formatting.
+         * @type {string}
+         * @private
+         */
+        self.nationalPrefixExtracted_ = @"";
+        
+        /**
+         * @type {!goog.string.StringBuffer}
+         * @private
+         */
+        self.nationalNumber_ = [NSMutableString stringWithString:@""];
+        
+        /**
+         * @type {Array.<i18n.phonenumbers.NumberFormat>}
+         * @private
+         */
+        self.possibleFormats_ = [[NSMutableArray alloc] init];
+    }
+    
+    return self;
+}
+
+/**
+ * Constructs an AsYouTypeFormatter for the specific region.
+ *
+ * @param {string} regionCode the ISO 3166-1 two-letter region code that denotes
+ *     the region where the phone number is being entered.
+ * @constructor
+ */
+
+- (id)initWithRegionCode:(NSString*)regionCode
+{
+    self = [self init];
+    
+    if (self) {
+        /**
+         * @type {string}
+         * @private
+         */
+        self.defaultCountry_ = regionCode;
+        self.currentMetaData_ = [self getMetadataForRegion_:self.defaultCountry_];
+        /**
+         * @type {i18n.phonenumbers.PhoneMetadata}
+         * @private
+         */
+        self.defaultMetaData_ = self.currentMetaData_;
+        
+        /**
+         * @const
+         * @type {i18n.phonenumbers.PhoneMetadata}
+         * @private
+         */
+        self.EMPTY_METADATA_ = [[NBPhoneMetaData alloc] init];
+        [self.EMPTY_METADATA_ setInternationalPrefix:@"NA"];
+    }
+    
+    return self;
+}
+
+- (id)initWithRegionCodeForTest:(NSString*)regionCode
+{
+    self = [self init];
+    
+    if (self) {
+        self.phoneUtil_ = [NBPhoneNumberUtil sharedInstanceForTest];
+        
+        self.defaultCountry_ = regionCode;
+        self.currentMetaData_ = [self getMetadataForRegion_:self.defaultCountry_];
+        self.defaultMetaData_ = self.currentMetaData_;
+        self.EMPTY_METADATA_ = [[NBPhoneMetaData alloc] init];
+        [self.EMPTY_METADATA_ setInternationalPrefix:@"NA"];
+    }
+    
+    return self;
+}
+
+/**
+ * The metadata needed by this class is the same for all regions sharing the
+ * same country calling code. Therefore, we return the metadata for "main"
+ * region for this country calling code.
+ * @param {string} regionCode an ISO 3166-1 two-letter region code.
+ * @return {i18n.phonenumbers.PhoneMetadata} main metadata for this region.
+ * @private
+ */
+- (NBPhoneMetaData*)getMetadataForRegion_:(NSString*)regionCode
+{
+    
+    /** @type {number} */
+    NSNumber *countryCallingCode = [self.phoneUtil_ getCountryCodeForRegion:regionCode];
+    /** @type {string} */
+    NSString *mainCountry = [self.phoneUtil_ getRegionCodeForCountryCode:countryCallingCode];
+    /** @type {i18n.phonenumbers.PhoneMetadata} */
+    NBPhoneMetaData *metadata = [self.phoneUtil_ getMetadataForRegion:mainCountry];
+    if (metadata != nil) {
+        return metadata;
+    }
+    // Set to a default instance of the metadata. This allows us to function with
+    // an incorrect region code, even if formatting only works for numbers
+    // specified with '+'.
+    return self.EMPTY_METADATA_;
+};
+
+
+/**
+ * @return {BOOL} YES if a new template is created as opposed to reusing the
+ *     existing template.
+ * @private
+ */
+- (BOOL)maybeCreateNewTemplate_
+{
+    // When there are multiple available formats, the formatter uses the first
+    // format where a formatting template could be created.
+    /** @type {number} */
+    NSUInteger possibleFormatsLength = [self.possibleFormats_ count];
+    for (NSUInteger i = 0; i < possibleFormatsLength; ++i)
+    {
+        /** @type {i18n.phonenumbers.NumberFormat} */
+        NBNumberFormat *numberFormat = [self.possibleFormats_ safeObjectAtIndex:i];
+        /** @type {string} */
+        NSString *pattern = numberFormat.pattern;
+        
+        if ([self.currentFormattingPattern_ isEqualToString:pattern]) {
+            return NO;
+        }
+        
+        if ([self createFormattingTemplate_:numberFormat ])
+        {
+            self.currentFormattingPattern_ = pattern;
+            NSRange nationalPrefixRange = NSMakeRange(0, [numberFormat.nationalPrefixFormattingRule length]);
+            if (nationalPrefixRange.length > 0) {
+                NSTextCheckingResult *matchResult =
+                [self.NATIONAL_PREFIX_SEPARATORS_PATTERN_ firstMatchInString:numberFormat.nationalPrefixFormattingRule
+                                                                     options:0
+                                                                       range:nationalPrefixRange];
+                self.shouldAddSpaceAfterNationalPrefix_ = (matchResult != nil);
+            } else {
+                self.shouldAddSpaceAfterNationalPrefix_ = NO;
+            }
+            // With a new formatting template, the matched position using the old
+            // template needs to be reset.
+            self.lastMatchPosition_ = 0;
+            return YES;
+        }
+    }
+    self.ableToFormat_ = NO;
+    return NO;
+};
+
+
+/**
+ * @param {string} leadingThreeDigits first three digits of entered number.
+ * @private
+ */
+- (void)getAvailableFormats_:(NSString*)leadingThreeDigits
+{
+    /** @type {Array.<i18n.phonenumbers.NumberFormat>} */
+    BOOL isIntlNumberFormats = (self.isCompleteNumber_ && self.currentMetaData_.intlNumberFormats.count > 0);
+    NSMutableArray *formatList = isIntlNumberFormats ? self.currentMetaData_.intlNumberFormats : self.currentMetaData_.numberFormats;
+    
+    /** @type {number} */
+    NSUInteger formatListLength = formatList.count;
+    
+    for (NSUInteger i = 0; i < formatListLength; ++i)
+    {
+        /** @type {i18n.phonenumbers.NumberFormat} */
+        NBNumberFormat *format = [formatList safeObjectAtIndex:i];
+        /** @type {BOOL} */
+        BOOL nationalPrefixIsUsedByCountry = (self.currentMetaData_.nationalPrefix && self.currentMetaData_.nationalPrefix.length > 0);
+        
+        if (!nationalPrefixIsUsedByCountry || self.isCompleteNumber_ || format.nationalPrefixOptionalWhenFormatting ||
+            [self.phoneUtil_ formattingRuleHasFirstGroupOnly:format.nationalPrefixFormattingRule])
+        {
+            if ([self isFormatEligible_:format.format]) {
+                [self.possibleFormats_ addObject:format];
+            }
+        }
+    }
+    
+    [self narrowDownPossibleFormats_:leadingThreeDigits];
+};
+
+
+/**
+ * @param {string} format
+ * @return {BOOL}
+ * @private
+ */
+- (BOOL)isFormatEligible_:(NSString*)format
+{
+    NSTextCheckingResult *matchResult =
+        [self.ELIGIBLE_FORMAT_PATTERN_ firstMatchInString:format options:0 range:NSMakeRange(0, [format length])];
+    return (matchResult != nil);
+};
+
+
+/**
+ * @param {string} leadingDigits
+ * @private
+ */
+- (void)narrowDownPossibleFormats_:(NSString *)leadingDigits
+{
+    /** @type {Array.<i18n.phonenumbers.NumberFormat>} */
+    NSMutableArray *possibleFormats = [[NSMutableArray alloc] init];
+    /** @type {number} */
+    NSUInteger indexOfLeadingDigitsPattern = leadingDigits.length - self.MIN_LEADING_DIGITS_LENGTH_;
+    /** @type {number} */
+    NSUInteger possibleFormatsLength = self.possibleFormats_.count;
+    for (NSUInteger i = 0; i < possibleFormatsLength; ++i)
+    {
+        /** @type {i18n.phonenumbers.NumberFormat} */
+        NBNumberFormat *format = [self.possibleFormats_ safeObjectAtIndex:i];
+        if (format.leadingDigitsPatterns.count > indexOfLeadingDigitsPattern)
+        {
+            /** @type {string} */
+            NSString *leadingDigitsPattern = [format.leadingDigitsPatterns safeObjectAtIndex:indexOfLeadingDigitsPattern];
+            
+            if ([self.phoneUtil_ stringPositionByRegex:leadingDigits regex:leadingDigitsPattern] == 0)
+            {
+                [possibleFormats addObject:format];
+            }
+        } else {
+            // else the particular format has no more specific leadingDigitsPattern,
+            // and it should be retained.
+            [possibleFormats addObject:[self.possibleFormats_ safeObjectAtIndex:i]];
+        }
+    }
+    self.possibleFormats_ = possibleFormats;
+};
+
+
+/**
+ * @param {i18n.phonenumbers.NumberFormat} format
+ * @return {BOOL}
+ * @private
+ */
+- (BOOL)createFormattingTemplate_:(NBNumberFormat*)format
+{
+    /** @type {string} */
+    NSString *numberPattern = format.pattern;
+    
+    // The formatter doesn't format numbers when numberPattern contains '|', e.g.
+    // (20|3)\d{4}. In those cases we quickly return.
+    NSRange stringRange = [numberPattern rangeOfString:@"|"];
+    if (stringRange.location != NSNotFound) {
+        return NO;
+    }
+    
+    // Replace anything in the form of [..] with \d
+    numberPattern = [self.CHARACTER_CLASS_PATTERN_ stringByReplacingMatchesInString:numberPattern
+                                                                            options:0 range:NSMakeRange(0, [numberPattern length])
+                                                                       withTemplate:@"\\\\d"];
+    
+    // Replace any standalone digit (not the one in d{}) with \d
+    numberPattern = [self.STANDALONE_DIGIT_PATTERN_ stringByReplacingMatchesInString:numberPattern
+                                                                             options:0 range:NSMakeRange(0, [numberPattern length])
+                                                                        withTemplate:@"\\\\d"];
+    self.formattingTemplate_ = [NSMutableString stringWithString:@""];
+    
+    /** @type {string} */
+    NSString *tempTemplate = [self getFormattingTemplate_:numberPattern numberFormat:format.format];
+    if (tempTemplate.length > 0) {
+        [self.formattingTemplate_ appendString:tempTemplate];
+        return YES;
+    }
+    return NO;
+};
+
+
+/**
+ * Gets a formatting template which can be used to efficiently format a
+ * partial number where digits are added one by one.
+ *
+ * @param {string} numberPattern
+ * @param {string} numberFormat
+ * @return {string}
+ * @private
+ */
+- (NSString*)getFormattingTemplate_:(NSString*)numberPattern numberFormat:(NSString*)numberFormat
+{
+    // Creates a phone number consisting only of the digit 9 that matches the
+    // numberPattern by applying the pattern to the longestPhoneNumber string.
+    /** @type {string} */
+    NSString *longestPhoneNumber = @"999999999999999";
+    
+    /** @type {Array.<string>} */
+    NSArray *m = [self.phoneUtil_ matchedStringByRegex:longestPhoneNumber regex:numberPattern];
+    
+    // this match will always succeed
+    /** @type {string} */
+    NSString *aPhoneNumber = [m safeObjectAtIndex:0];
+    // No formatting template can be created if the number of digits entered so
+    // far is longer than the maximum the current formatting rule can accommodate.
+    if (aPhoneNumber.length < self.nationalNumber_.length) {
+        return @"";
+    }
+    // Formats the number according to numberFormat
+    /** @type {string} */
+    NSString *template = [self.phoneUtil_ replaceStringByRegex:aPhoneNumber regex:numberPattern withTemplate:numberFormat];
+    
+    // Replaces each digit with character DIGIT_PLACEHOLDER
+    template = [self.phoneUtil_ replaceStringByRegex:template regex:@"9" withTemplate:self.DIGIT_PLACEHOLDER_];
+    return template;
+};
+
+
+/**
+ * Clears the internal state of the formatter, so it can be reused.
+ */
+- (void)clear
+{
+    self.currentOutput_ = @"";
+    self.accruedInput_ = [NSMutableString stringWithString:@""];
+    self.accruedInputWithoutFormatting_ = [NSMutableString stringWithString:@""];
+    self.formattingTemplate_ = [NSMutableString stringWithString:@""];
+    self.lastMatchPosition_ = 0;
+    self.currentFormattingPattern_ = @"";
+    self.prefixBeforeNationalNumber_ = [NSMutableString stringWithString:@""];
+    self.nationalPrefixExtracted_ = @"";
+    self.nationalNumber_ = [NSMutableString stringWithString:@""];
+    self.ableToFormat_ = YES;
+    self.inputHasFormatting_ = NO;
+    self.positionToRemember_ = 0;
+    self.originalPosition_ = 0;
+    self.isCompleteNumber_ = NO;
+    self.isExpectingCountryCallingCode_ = NO;
+    [self.possibleFormats_ removeAllObjects];
+    self.shouldAddSpaceAfterNationalPrefix_ = NO;
+    
+    if (self.currentMetaData_ != self.defaultMetaData_) {
+        self.currentMetaData_ = [self getMetadataForRegion_:self.defaultCountry_];
+    }
+}
+
+
+/**
+ * Formats a phone number on-the-fly as each digit is entered.
+ *
+ * @param {string} nextChar the most recently entered digit of a phone number.
+ *     Formatting characters are allowed, but as soon as they are encountered
+ *     this method formats the number as entered and not 'as you type' anymore.
+ *     Full width digits and Arabic-indic digits are allowed, and will be shown
+ *     as they are.
+ * @return {string} the partially formatted phone number.
+ */
+- (NSString*)inputDigit:(NSString*)nextChar
+{
+    self.currentOutput_ = [self inputDigitWithOptionToRememberPosition_:nextChar rememberPosition:NO];
+    return self.currentOutput_;
+}
+
+
+/**
+ * Same as {@link #inputDigit}, but remembers the position where
+ * {@code nextChar} is inserted, so that it can be retrieved later by using
+ * {@link #getRememberedPosition}. The remembered position will be automatically
+ * adjusted if additional formatting characters are later inserted/removed in
+ * front of {@code nextChar}.
+ *
+ * @param {string} nextChar
+ * @return {string}
+ */
+- (NSString*)inputDigitAndRememberPosition:(NSString*)nextChar
+{
+    self.currentOutput_ = [self inputDigitWithOptionToRememberPosition_:nextChar rememberPosition:YES];
+    return self.currentOutput_;
+};
+
+
+/**
+ * @param {string} nextChar
+ * @param {BOOL} rememberPosition
+ * @return {string}
+ * @private
+ */
+- (NSString*)inputDigitWithOptionToRememberPosition_:(NSString*)nextChar rememberPosition:(BOOL)rememberPosition
+{
+    [self.accruedInput_ appendString:nextChar];
+    
+    if (rememberPosition) {
+        self.originalPosition_ = self.accruedInput_.length;
+    }
+    
+    // We do formatting on-the-fly only when each character entered is either a
+    // digit, or a plus sign (accepted at the start of the number only).
+    if (![self isDigitOrLeadingPlusSign_:nextChar])
+    {
+        self.ableToFormat_ = NO;
+        self.inputHasFormatting_ = YES;
+    } else {
+        nextChar = [self normalizeAndAccrueDigitsAndPlusSign_:nextChar rememberPosition:rememberPosition];
+    }
+    
+    if (!self.ableToFormat_) {
+        // When we are unable to format because of reasons other than that
+        // formatting chars have been entered, it can be due to really long IDDs or
+        // NDDs. If that is the case, we might be able to do formatting again after
+        // extracting them.
+        if (self.inputHasFormatting_) {
+            return [NSString stringWithString:self.accruedInput_];
+        }
+        else if ([self attemptToExtractIdd_]) {
+            if ([self attemptToExtractCountryCallingCode_]) {
+                return [self attemptToChoosePatternWithPrefixExtracted_];
+            }
+        }
+        else if ([self ableToExtractLongerNdd_]) {
+            // Add an additional space to separate long NDD and national significant
+            // number for readability. We don't set shouldAddSpaceAfterNationalPrefix_
+            // to YES, since we don't want this to change later when we choose
+            // formatting templates.
+            [self.prefixBeforeNationalNumber_ appendString:[NSString stringWithFormat: @"%@", self.SEPARATOR_BEFORE_NATIONAL_NUMBER_]];
+            return [self attemptToChoosePatternWithPrefixExtracted_];
+        }
+        return self.accruedInput_;
+    }
+    
+    // We start to attempt to format only when at least MIN_LEADING_DIGITS_LENGTH
+    // digits (the plus sign is counted as a digit as well for this purpose) have
+    // been entered.
+    switch (self.accruedInputWithoutFormatting_.length)
+    {
+        case 0:
+        case 1:
+        case 2:
+            return self.accruedInput_;
+        case 3:
+            if ([self attemptToExtractIdd_]) {
+                self.isExpectingCountryCallingCode_ = YES;
+            } else {
+                // No IDD or plus sign is found, might be entering in national format.
+                self.nationalPrefixExtracted_ = [self removeNationalPrefixFromNationalNumber_];
+                return [self attemptToChooseFormattingPattern_];
+            }
+        default:
+            if (self.isExpectingCountryCallingCode_) {
+                if ([self attemptToExtractCountryCallingCode_]) {
+                    self.isExpectingCountryCallingCode_ = NO;
+                }
+                return [NSString stringWithFormat:@"%@%@", self.prefixBeforeNationalNumber_, self.nationalNumber_];
+            }
+            
+            if (self.possibleFormats_.count > 0) {
+                // The formatting pattern is already chosen.
+                /** @type {string} */
+                NSString *tempNationalNumber = [self 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.
+                /** @type {string} */
+                NSString *formattedNumber = [self attemptToFormatAccruedDigits_];
+                if (formattedNumber.length > 0) {
+                    return formattedNumber;
+                }
+                
+                [self narrowDownPossibleFormats_:self.nationalNumber_];
+                
+                if ([self maybeCreateNewTemplate_]) {
+                    return [self inputAccruedNationalNumber_];
+                }
+                
+                return self.ableToFormat_ ? [self appendNationalNumber_:tempNationalNumber] : self.accruedInput_;
+            }
+            else {
+                return [self attemptToChooseFormattingPattern_];
+            }
+    }
+};
+
+
+/**
+ * @return {string}
+ * @private
+ */
+- (NSString*)attemptToChoosePatternWithPrefixExtracted_
+{
+    self.ableToFormat_ = YES;
+    self.isExpectingCountryCallingCode_ = NO;
+    [self.possibleFormats_ removeAllObjects];
+    return [self attemptToChooseFormattingPattern_];
+};
+
+
+/**
+ * Some national prefixes are a substring of others. If extracting the shorter
+ * NDD doesn't result in a number we can format, we try to see if we can extract
+ * a longer version here.
+ * @return {BOOL}
+ * @private
+ */
+- (BOOL)ableToExtractLongerNdd_
+{
+    if (self.nationalPrefixExtracted_.length > 0)
+    {
+        // Put the extracted NDD back to the national number before attempting to
+        // extract a new NDD.
+        /** @type {string} */
+        NSString *nationalNumberStr = [NSString stringWithString:self.nationalNumber_];
+        self.nationalNumber_ = [NSMutableString stringWithString:@""];
+        [self.nationalNumber_ appendString:self.nationalPrefixExtracted_];
+        [self.nationalNumber_ appendString:nationalNumberStr];
+        // Remove the previously extracted NDD from prefixBeforeNationalNumber. We
+        // cannot simply set it to empty string because people sometimes incorrectly
+        // enter national prefix after the country code, e.g. +44 (0)20-1234-5678.
+        /** @type {string} */
+        NSString *prefixBeforeNationalNumberStr = [NSString stringWithString:self.prefixBeforeNationalNumber_];
+        NSRange lastRange = [prefixBeforeNationalNumberStr rangeOfString:self.nationalPrefixExtracted_ options:NSBackwardsSearch];
+        /** @type {number} */
+        NSUInteger indexOfPreviousNdd = lastRange.location;
+        self.prefixBeforeNationalNumber_ = [NSMutableString stringWithString:@""];
+        [self.prefixBeforeNationalNumber_ appendString:[prefixBeforeNationalNumberStr substringWithRange:NSMakeRange(0, indexOfPreviousNdd)]];
+    }
+    
+    return self.nationalPrefixExtracted_ != [self removeNationalPrefixFromNationalNumber_];
+};
+
+
+/**
+ * @param {string} nextChar
+ * @return {BOOL}
+ * @private
+ */
+- (BOOL)isDigitOrLeadingPlusSign_:(NSString*)nextChar
+{
+    NSString *digitPattern = [NSString stringWithFormat:@"([%@])", [self.phoneUtil_ VALID_DIGITS_STRING]];
+    NSString *plusPattern = [NSString stringWithFormat:@"[%@]+", [self.phoneUtil_ PLUS_CHARS_]];
+    
+    BOOL isDigitPattern = [[self.phoneUtil_ matchesByRegex:nextChar regex:digitPattern] count] > 0;
+    BOOL isPlusPattern = [[self.phoneUtil_ matchesByRegex:nextChar regex:plusPattern] count] > 0;
+    
+    return isDigitPattern || (self.accruedInput_.length == 1 && isPlusPattern);
+};
+
+
+/**
+ * Check to see if there is an exact pattern match for these digits. If so, we
+ * should use this instead of any other formatting template whose
+ * leadingDigitsPattern also matches the input.
+ * @return {string}
+ * @private
+ */
+- (NSString*)attemptToFormatAccruedDigits_
+{
+    /** @type {string} */
+    NSString *nationalNumber = [NSString stringWithString:self.nationalNumber_];
+    
+    /** @type {number} */
+    NSUInteger possibleFormatsLength = self.possibleFormats_.count;
+    for (NSUInteger i = 0; i < possibleFormatsLength; ++i)
+    {
+        /** @type {i18n.phonenumbers.NumberFormat} */
+        NBNumberFormat *numberFormat = self.possibleFormats_[i];
+        /** @type {string} */
+        NSString * pattern = numberFormat.pattern;
+        /** @type {RegExp} */
+        NSString *patternRegExp = [NSString stringWithFormat:@"^(?:%@)$", pattern];
+        BOOL isPatternRegExp = [[self.phoneUtil_ matchesByRegex:nationalNumber regex:patternRegExp] count] > 0;
+        if (isPatternRegExp) {
+            if (numberFormat.nationalPrefixFormattingRule.length > 0) {
+                NSArray *matches = [self.NATIONAL_PREFIX_SEPARATORS_PATTERN_ matchesInString:numberFormat.nationalPrefixFormattingRule
+                                                                                     options:0
+                                                                                       range:NSMakeRange(0, numberFormat.nationalPrefixFormattingRule.length)];
+                self.shouldAddSpaceAfterNationalPrefix_ = [matches count] > 0;
+            } else {
+                self.shouldAddSpaceAfterNationalPrefix_ = NO;
+            }
+            
+            /** @type {string} */
+            NSString *formattedNumber = [self.phoneUtil_ replaceStringByRegex:nationalNumber
+                                                                        regex:pattern
+                                                                 withTemplate:numberFormat.format];
+            return [self appendNationalNumber_:formattedNumber];
+        }
+    }
+    return @"";
+};
+
+
+/**
+ * Combines the national number with any prefix (IDD/+ and country code or
+ * national prefix) that was collected. A space will be inserted between them if
+ * the current formatting template indicates this to be suitable.
+ * @param {string} nationalNumber The number to be appended.
+ * @return {string} The combined number.
+ * @private
+ */
+- (NSString*)appendNationalNumber_:(NSString*)nationalNumber
+{
+    /** @type {number} */
+    NSUInteger prefixBeforeNationalNumberLength = self.prefixBeforeNationalNumber_.length;
+    unichar blank_char = [self.SEPARATOR_BEFORE_NATIONAL_NUMBER_ characterAtIndex:0];
+    if (self.shouldAddSpaceAfterNationalPrefix_ && prefixBeforeNationalNumberLength > 0 &&
+        [self.prefixBeforeNationalNumber_ characterAtIndex:prefixBeforeNationalNumberLength - 1] != blank_char)
+    {
+        // We want to add a space after the national prefix if the national prefix
+        // formatting rule indicates that this would normally be done, with the
+        // exception of the case where we already appended a space because the NDD
+        // was surprisingly long.
+        
+        return [NSString stringWithFormat:@"%@%@%@", self.prefixBeforeNationalNumber_, self.SEPARATOR_BEFORE_NATIONAL_NUMBER_, nationalNumber];
+    } else {
+        return [NSString stringWithFormat:@"%@%@", self.prefixBeforeNationalNumber_, nationalNumber];
+    }
+};
+
+
+/**
+ * Returns the current position in the partially formatted phone number of the
+ * character which was previously passed in as the parameter of
+ * {@link #inputDigitAndRememberPosition}.
+ *
+ * @return {number}
+ */
+- (NSInteger)getRememberedPosition
+{
+    if (!self.ableToFormat_) {
+        return self.originalPosition_;
+    }
+    /** @type {number} */
+    NSUInteger accruedInputIndex = 0;
+    /** @type {number} */
+    NSUInteger currentOutputIndex = 0;
+    /** @type {string} */
+    NSString *accruedInputWithoutFormatting = self.accruedInputWithoutFormatting_;
+    /** @type {string} */
+    NSString *currentOutput = self.currentOutput_;
+    
+    while (accruedInputIndex < self.positionToRemember_ && currentOutputIndex < currentOutput.length)
+    {
+        if ([accruedInputWithoutFormatting characterAtIndex:accruedInputIndex] == [currentOutput characterAtIndex:currentOutputIndex])
+        {
+            accruedInputIndex++;
+        }
+        currentOutputIndex++;
+    }
+    return currentOutputIndex;
+};
+
+
+/**
+ * Attempts to set the formatting template and returns a string which contains
+ * the formatted version of the digits entered so far.
+ *
+ * @return {string}
+ * @private
+ */
+- (NSString*)attemptToChooseFormattingPattern_
+{
+    /** @type {string} */
+    NSString *nationalNumber = [self.nationalNumber_ copy];
+    // We start to attempt to format only when as least MIN_LEADING_DIGITS_LENGTH
+    // digits of national number (excluding national prefix) have been entered.
+    if (nationalNumber.length >= self.MIN_LEADING_DIGITS_LENGTH_) {
+        [self getAvailableFormats_:[nationalNumber substringWithRange:NSMakeRange(0, self.MIN_LEADING_DIGITS_LENGTH_)]];
+        return [self maybeCreateNewTemplate_] ? [self inputAccruedNationalNumber_] : self.accruedInput_;
+    } else {
+        return [self appendNationalNumber_:nationalNumber];
+    }
+}
+
+
+/**
+ * Invokes inputDigitHelper on each digit of the national number accrued, and
+ * returns a formatted string in the end.
+ *
+ * @return {string}
+ * @private
+ */
+- (NSString*)inputAccruedNationalNumber_
+{
+    /** @type {string} */
+    NSString *nationalNumber = [self.nationalNumber_ copy];
+    /** @type {number} */
+    NSUInteger lengthOfNationalNumber = nationalNumber.length;
+    if (lengthOfNationalNumber > 0) {
+        /** @type {string} */
+        NSString *tempNationalNumber = @"";
+        for (NSUInteger i = 0; i < lengthOfNationalNumber; i++)
+        {
+            tempNationalNumber = [self inputDigitHelper_:[NSString stringWithFormat: @"%C", [nationalNumber characterAtIndex:i]]];
+        }
+        return self.ableToFormat_ ? [self appendNationalNumber_:tempNationalNumber] : self.accruedInput_;
+    } else {
+        return self.prefixBeforeNationalNumber_;
+    }
+};
+
+
+/**
+ * @return {BOOL} YES if the current country is a NANPA country and the
+ *     national number begins with the national prefix.
+ * @private
+ */
+- (BOOL)isNanpaNumberWithNationalPrefix_
+{
+    // For NANPA numbers beginning with 1[2-9], treat the 1 as the national
+    // prefix. The reason is that national significant numbers in NANPA always
+    // start with [2-9] after the national prefix. Numbers beginning with 1[01]
+    // can only be short/emergency numbers, which don't need the national prefix.
+    if (![self.currentMetaData_.countryCode isEqualToNumber:@1]) {
+        return NO;
+    }
+    
+    /** @type {string} */
+    NSString *nationalNumber = [self.nationalNumber_ copy];
+    return ([nationalNumber characterAtIndex:0] == '1') && ([nationalNumber characterAtIndex:1] != '0') &&
+        ([nationalNumber characterAtIndex:1] != '1');
+};
+
+
+/**
+ * Returns the national prefix extracted, or an empty string if it is not
+ * present.
+ * @return {string}
+ * @private
+ */
+- (NSString*)removeNationalPrefixFromNationalNumber_
+{
+    /** @type {string} */
+    NSString *nationalNumber = [self.nationalNumber_ copy];
+    /** @type {number} */
+    NSUInteger startOfNationalNumber = 0;
+    
+    if ([self isNanpaNumberWithNationalPrefix_]) {
+        startOfNationalNumber = 1;
+        [self.prefixBeforeNationalNumber_ appendString:@"1"];
+        [self.prefixBeforeNationalNumber_ appendFormat:@"%@", self.SEPARATOR_BEFORE_NATIONAL_NUMBER_];
+        self.isCompleteNumber_ = YES;
+    }
+    else if (self.currentMetaData_.nationalPrefixForParsing != nil && self.currentMetaData_.nationalPrefixForParsing.length > 0)
+    {
+        /** @type {RegExp} */
+        NSString *nationalPrefixForParsing = [NSString stringWithFormat:@"^(?:%@)", self.currentMetaData_.nationalPrefixForParsing];
+        /** @type {Array.<string>} */
+        NSArray *m = [self.phoneUtil_ matchedStringByRegex:nationalNumber regex:nationalPrefixForParsing];
+        NSString *firstString = [m safeObjectAtIndex:0];
+        if (m != nil && firstString != nil && firstString.length > 0) {
+            // When the national prefix is detected, we use international formatting
+            // rules instead of national ones, because national formatting rules could
+            // contain local formatting rules for numbers entered without area code.
+            self.isCompleteNumber_ = YES;
+            startOfNationalNumber = firstString.length;
+            [self.prefixBeforeNationalNumber_ appendString:[nationalNumber substringWithRange:NSMakeRange(0, startOfNationalNumber)]];
+        }
+    }
+    
+    self.nationalNumber_ = [NSMutableString stringWithString:@""];
+    [self.nationalNumber_ appendString:[nationalNumber substringFromIndex:startOfNationalNumber]];
+    return [nationalNumber substringWithRange:NSMakeRange(0, startOfNationalNumber)];
+};
+
+
+/**
+ * Extracts IDD and plus sign to prefixBeforeNationalNumber when they are
+ * available, and places the remaining input into nationalNumber.
+ *
+ * @return {BOOL} YES when accruedInputWithoutFormatting begins with the
+ *     plus sign or valid IDD for defaultCountry.
+ * @private
+ */
+- (BOOL)attemptToExtractIdd_
+{
+    /** @type {string} */
+    NSString *accruedInputWithoutFormatting = [self.accruedInputWithoutFormatting_ copy];
+    /** @type {RegExp} */
+    NSString *internationalPrefix = [NSString stringWithFormat:@"^(?:\\+|%@)", self.currentMetaData_.internationalPrefix];
+    /** @type {Array.<string>} */
+    NSArray *m = [self.phoneUtil_ matchedStringByRegex:accruedInputWithoutFormatting regex:internationalPrefix];
+    
+    NSString *firstString = [m safeObjectAtIndex:0];
+    
+    if (m != nil && firstString != nil && firstString.length > 0) {
+        self.isCompleteNumber_ = YES;
+        /** @type {number} */
+        NSUInteger startOfCountryCallingCode = firstString.length;
+        self.nationalNumber_ = [NSMutableString stringWithString:@""];
+        [self.nationalNumber_ appendString:[accruedInputWithoutFormatting substringFromIndex:startOfCountryCallingCode]];
+        self.prefixBeforeNationalNumber_ = [NSMutableString stringWithString:@""];
+        [self.prefixBeforeNationalNumber_ appendString:[accruedInputWithoutFormatting substringWithRange:NSMakeRange(0, startOfCountryCallingCode)]];
+        
+        if ([accruedInputWithoutFormatting characterAtIndex:0] != '+')
+        {
+            [self.prefixBeforeNationalNumber_ appendString:[NSString stringWithFormat: @"%@", self.SEPARATOR_BEFORE_NATIONAL_NUMBER_]];
+        }
+        return YES;
+    }
+    return NO;
+};
+
+
+/**
+ * Extracts the country calling code from the beginning of nationalNumber to
+ * prefixBeforeNationalNumber when they are available, and places the remaining
+ * input into nationalNumber.
+ *
+ * @return {BOOL} YES when a valid country calling code can be found.
+ * @private
+ */
+- (BOOL)attemptToExtractCountryCallingCode_
+{
+    if (self.nationalNumber_.length == 0) {
+        return NO;
+    }
+    
+    /** @type {!goog.string.StringBuffer} */
+    NSString *numberWithoutCountryCallingCode = @"";
+    
+    /** @type {number} */
+    NSNumber *countryCode = [self.phoneUtil_ extractCountryCode:self.nationalNumber_ nationalNumber:&numberWithoutCountryCallingCode];
+    
+    if ([countryCode isEqualToNumber:@0]) {
+        return NO;
+    }
+    
+    self.nationalNumber_ = [NSMutableString stringWithString:@""];
+    [self.nationalNumber_ appendString:numberWithoutCountryCallingCode];
+    
+    /** @type {string} */
+    NSString *newRegionCode = [self.phoneUtil_ getRegionCodeForCountryCode:countryCode];
+    
+    if ([[self.phoneUtil_ REGION_CODE_FOR_NON_GEO_ENTITY] isEqualToString:newRegionCode]) {
+        self.currentMetaData_ = [self.phoneUtil_ getMetadataForNonGeographicalRegion:countryCode];
+    } else if (newRegionCode != self.defaultCountry_)
+    {
+        self.currentMetaData_ = [self getMetadataForRegion_:newRegionCode];
+    }
+    
+    /** @type {string} */
+    NSString *countryCodeString = [NSString stringWithFormat:@"%@", countryCode];
+    [self.prefixBeforeNationalNumber_ appendString:countryCodeString];
+    [self.prefixBeforeNationalNumber_ appendString:[NSString stringWithFormat: @"%@", self.SEPARATOR_BEFORE_NATIONAL_NUMBER_]];
+    return YES;
+};
+
+
+/**
+ * Accrues digits and the plus sign to accruedInputWithoutFormatting for later
+ * use. If nextChar contains a digit in non-ASCII format (e.g. the full-width
+ * version of digits), it is first normalized to the ASCII version. The return
+ * value is nextChar itself, or its normalized version, if nextChar is a digit
+ * in non-ASCII format. This method assumes its input is either a digit or the
+ * plus sign.
+ *
+ * @param {string} nextChar
+ * @param {BOOL} rememberPosition
+ * @return {string}
+ * @private
+ */
+- (NSString*)normalizeAndAccrueDigitsAndPlusSign_:(NSString *)nextChar rememberPosition:(BOOL)rememberPosition
+{
+    /** @type {string} */
+    NSString *normalizedChar;
+    
+    if ([nextChar isEqualToString:@"+"]) {
+        normalizedChar = nextChar;
+        [self.accruedInputWithoutFormatting_ appendString:nextChar];
+    } else {
+        normalizedChar = [[self.phoneUtil_ DIGIT_MAPPINGS] objectForKey:nextChar];
+        [self.accruedInputWithoutFormatting_ appendString:normalizedChar];
+        [self.nationalNumber_ appendString:normalizedChar];
+    }
+    
+    if (rememberPosition) {
+        self.positionToRemember_ = self.accruedInputWithoutFormatting_.length;
+    }
+    
+    return normalizedChar;
+};
+
+
+/**
+ * @param {string} nextChar
+ * @return {string}
+ * @private
+ */
+- (NSString*)inputDigitHelper_:(NSString *)nextChar
+{
+    /** @type {string} */
+    NSString *formattingTemplate = [self.formattingTemplate_ copy];
+    NSString *subedString = @"";
+    
+    if (formattingTemplate.length > self.lastMatchPosition_) {
+        subedString = [formattingTemplate substringFromIndex:self.lastMatchPosition_];
+    }
+    
+    if ([self.phoneUtil_ stringPositionByRegex:subedString regex:self.DIGIT_PLACEHOLDER_] >= 0) {
+        /** @type {number} */
+        NSUInteger digitPatternStart = [self.phoneUtil_ stringPositionByRegex:formattingTemplate regex:self.DIGIT_PLACEHOLDER_];
+        
+        /** @type {string} */
+        NSRange tempRange = [formattingTemplate rangeOfString:self.DIGIT_PLACEHOLDER_];
+        NSString *tempTemplate = [formattingTemplate stringByReplacingOccurrencesOfString:self.DIGIT_PLACEHOLDER_
+                                                                               withString:nextChar
+                                                                                  options:NSLiteralSearch
+                                                                                    range:tempRange];
+        self.formattingTemplate_ = [NSMutableString stringWithString:@""];
+        [self.formattingTemplate_ appendString:tempTemplate];
+        self.lastMatchPosition_ = digitPatternStart;
+        return [tempTemplate substringWithRange:NSMakeRange(0, self.lastMatchPosition_ + 1)];
+    } else {
+        if (self.possibleFormats_.count == 1)
+        {
+            // More digits are entered than we could handle, and there are no other
+            // valid patterns to try.
+            self.ableToFormat_ = NO;
+        }  // else, we just reset the formatting pattern.
+        self.currentFormattingPattern_ = @"";
+        return self.accruedInput_;
+    }
+};
+
+@end
diff --git a/libPhoneNumber/NBNumberFormat.h b/libPhoneNumber/NBNumberFormat.h
new file mode 100644
index 0000000..d2e8749
--- /dev/null
+++ b/libPhoneNumber/NBNumberFormat.h
@@ -0,0 +1,22 @@
+//
+//  NBPhoneNumberFormat.h
+//  libPhoneNumber
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NBNumberFormat : NSObject
+
+// from phonemetadata.pb.js
+/* 1 */ @property (nonatomic, strong, readwrite) NSString *pattern;
+/* 2 */ @property (nonatomic, strong, readwrite) NSString *format;
+/* 3 */ @property (nonatomic, strong, readwrite) NSMutableArray *leadingDigitsPatterns;
+/* 4 */ @property (nonatomic, strong, readwrite) NSString *nationalPrefixFormattingRule;
+/* 6 */ @property (nonatomic, assign, readwrite) BOOL nationalPrefixOptionalWhenFormatting;
+/* 5 */ @property (nonatomic, strong, readwrite) NSString *domesticCarrierCodeFormattingRule;
+
+- (id)initWithData:(id)data;
+
+@end
diff --git a/libPhoneNumber/NBNumberFormat.m b/libPhoneNumber/NBNumberFormat.m
new file mode 100644
index 0000000..5f261a7
--- /dev/null
+++ b/libPhoneNumber/NBNumberFormat.m
@@ -0,0 +1,139 @@
+//
+//  NBPhoneNumberFormat.m
+//  libPhoneNumber
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import "NBNumberFormat.h"
+#import "NBPhoneNumberDefines.h"
+
+@implementation NBNumberFormat
+
+@synthesize pattern, format, leadingDigitsPatterns, nationalPrefixFormattingRule, nationalPrefixOptionalWhenFormatting, domesticCarrierCodeFormattingRule;
+
+
+- (id)initWithData:(id)data
+{
+    self = [self init];
+    
+    if (self && data != nil && [data isKindOfClass:[NSArray class]])
+    {
+        /* 1 */ self.pattern = [data safeObjectAtIndex:1];
+        /* 2 */ self.format = [data safeObjectAtIndex:2];
+        /* 3 */ self.leadingDigitsPatterns = [self stringArrayFromData:[data safeObjectAtIndex:3]]; // NSString array
+        /* 4 */ self.nationalPrefixFormattingRule = [data safeObjectAtIndex:4];
+        /* 6 */ self.nationalPrefixOptionalWhenFormatting = [[data safeObjectAtIndex:6] boolValue];
+        /* 5 */ self.domesticCarrierCodeFormattingRule = [data safeObjectAtIndex:5];
+    }
+    
+    return self;
+}
+
+
+- (id)init
+{
+    self = [super init];
+    
+    if (self)
+    {
+        self.nationalPrefixOptionalWhenFormatting = NO;
+        self.leadingDigitsPatterns = [[NSMutableArray alloc] init];
+    }
+    
+    return self;
+}
+
+
+- (NSMutableArray*)stringArrayFromData:(id)data
+{
+    NSMutableArray *resArray = [[NSMutableArray alloc] init];
+    if (data != nil && [data isKindOfClass:[NSArray class]])
+    {
+        for (id numFormat in data)
+        {
+            if ([numFormat isKindOfClass:[NSString class]])
+            {
+                [resArray addObject:numFormat];
+            }
+            else
+            {
+                [resArray addObject:[numFormat stringValue]];
+            }
+        }
+    }
+    
+    return resArray;
+}
+
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"[pattern:%@, format:%@, leadingDigitsPattern:%@, nationalPrefixFormattingRule:%@, nationalPrefixOptionalWhenFormatting:%@, domesticCarrierCodeFormattingRule:%@]",
+            self.pattern, self.format, self.leadingDigitsPatterns, self.nationalPrefixFormattingRule, self.nationalPrefixOptionalWhenFormatting?@"Y":@"N", self.domesticCarrierCodeFormattingRule];
+}
+
+
+- (id)copyWithZone:(NSZone *)zone
+{
+	NBNumberFormat *phoneFormatCopy = [[NBNumberFormat allocWithZone:zone] init];
+    
+    /*
+     1 @property (nonatomic, strong, readwrite) NSString *pattern;
+     2 @property (nonatomic, strong, readwrite) NSString *format;
+     3 @property (nonatomic, strong, readwrite) NSString *leadingDigitsPattern;
+     4 @property (nonatomic, strong, readwrite) NSString *nationalPrefixFormattingRule;
+     6 @property (nonatomic, assign, readwrite) BOOL nationalPrefixOptionalWhenFormatting;
+     5 @property (nonatomic, strong, readwrite) NSString *domesticCarrierCodeFormattingRule;
+    */
+    
+    phoneFormatCopy.pattern = [self.pattern copy];
+    phoneFormatCopy.format = [self.format copy];
+    phoneFormatCopy.leadingDigitsPatterns = [self.leadingDigitsPatterns copy];
+    phoneFormatCopy.nationalPrefixFormattingRule = [self.nationalPrefixFormattingRule copy];
+    phoneFormatCopy.nationalPrefixOptionalWhenFormatting = self.nationalPrefixOptionalWhenFormatting;
+    phoneFormatCopy.domesticCarrierCodeFormattingRule = [self.domesticCarrierCodeFormattingRule copy];
+    
+	return phoneFormatCopy;
+}
+
+
+- (id)initWithCoder:(NSCoder*)coder
+{
+    if (self = [super init])
+    {
+        self.pattern = [coder decodeObjectForKey:@"pattern"];
+        self.format = [coder decodeObjectForKey:@"format"];
+        self.leadingDigitsPatterns = [coder decodeObjectForKey:@"leadingDigitsPatterns"];
+        self.nationalPrefixFormattingRule = [coder decodeObjectForKey:@"nationalPrefixFormattingRule"];
+        self.nationalPrefixOptionalWhenFormatting = [[coder decodeObjectForKey:@"nationalPrefixOptionalWhenFormatting"] boolValue];
+        self.domesticCarrierCodeFormattingRule = [coder decodeObjectForKey:@"domesticCarrierCodeFormattingRule"];
+    }
+    return self;
+}
+
+
+- (void)encodeWithCoder:(NSCoder*)coder
+{
+    [coder encodeObject:self.pattern forKey:@"pattern"];
+    [coder encodeObject:self.format forKey:@"format"];
+    [coder encodeObject:self.leadingDigitsPatterns forKey:@"leadingDigitsPatterns"];
+    [coder encodeObject:self.nationalPrefixFormattingRule forKey:@"nationalPrefixFormattingRule"];
+    [coder encodeObject:[NSNumber numberWithBool:self.nationalPrefixOptionalWhenFormatting] forKey:@"nationalPrefixOptionalWhenFormatting"];
+    [coder encodeObject:self.domesticCarrierCodeFormattingRule forKey:@"domesticCarrierCodeFormattingRule"];
+}
+
+
+- (void)setData:(id)data
+{
+    if ([data isKindOfClass:[NSArray class]] || [data isKindOfClass:[NSMutableArray class]])
+    {
+        
+    }
+    else if ([data isKindOfClass:[NSDictionary class]] || [data isKindOfClass:[NSMutableDictionary class]])
+    {
+        
+    }
+}
+
+@end
diff --git a/libPhoneNumber/NBPhoneMetaData.h b/libPhoneNumber/NBPhoneMetaData.h
new file mode 100644
index 0000000..6767492
--- /dev/null
+++ b/libPhoneNumber/NBPhoneMetaData.h
@@ -0,0 +1,45 @@
+//
+//  M2PhoneMetaData.h
+//  libPhoneNumber
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import <Foundation/Foundation.h>
+
+@class NBPhoneNumberDesc, NBNumberFormat;
+
+@interface NBPhoneMetaData : NSObject
+
+// from phonemetadata.pb.js
+/*  1 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *generalDesc;
+/*  2 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *fixedLine;
+/*  3 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *mobile;
+/*  4 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *tollFree;
+/*  5 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *premiumRate;
+/*  6 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *sharedCost;
+/*  7 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *personalNumber;
+/*  8 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *voip;
+/* 21 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *pager;
+/* 25 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *uan;
+/* 27 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *emergency;
+/* 28 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *voicemail;
+/* 24 */ @property (nonatomic, strong, readwrite) NBPhoneNumberDesc *noInternationalDialling;
+/*  9 */ @property (nonatomic, strong, readwrite) NSString *codeID;
+/* 10 */ @property (nonatomic, strong, readwrite) NSNumber *countryCode;
+/* 11 */ @property (nonatomic, strong, readwrite) NSString *internationalPrefix;
+/* 17 */ @property (nonatomic, strong, readwrite) NSString *preferredInternationalPrefix;
+/* 12 */ @property (nonatomic, strong, readwrite) NSString *nationalPrefix;
+/* 13 */ @property (nonatomic, strong, readwrite) NSString *preferredExtnPrefix;
+/* 15 */ @property (nonatomic, strong, readwrite) NSString *nationalPrefixForParsing;
+/* 16 */ @property (nonatomic, strong, readwrite) NSString *nationalPrefixTransformRule;
+/* 18 */ @property (nonatomic, assign, readwrite) BOOL sameMobileAndFixedLinePattern;
+/* 19 */ @property (nonatomic, strong, readwrite) NSMutableArray *numberFormats;
+/* 20 */ @property (nonatomic, strong, readwrite) NSMutableArray *intlNumberFormats;
+/* 22 */ @property (nonatomic, assign, readwrite) BOOL mainCountryForCode;
+/* 23 */ @property (nonatomic, strong, readwrite) NSString *leadingDigits;
+/* 26 */ @property (nonatomic, assign, readwrite) BOOL leadingZeroPossible;
+
+- (void)buildData:(id)data;
+
+@end
diff --git a/libPhoneNumber/NBPhoneMetaData.m b/libPhoneNumber/NBPhoneMetaData.m
new file mode 100644
index 0000000..8aa30d8
--- /dev/null
+++ b/libPhoneNumber/NBPhoneMetaData.m
@@ -0,0 +1,458 @@
+//
+//  NBPhoneMetaData.m
+//  libPhoneNumber
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import "NBPhoneMetaData.h"
+#import "NBPhoneNumberDesc.h"
+#import "NBNumberFormat.h"
+#import "NBPhoneNumberDefines.h"
+
+@implementation NBPhoneMetaData
+
+@synthesize generalDesc, fixedLine, mobile, tollFree, premiumRate, sharedCost, personalNumber, voip, pager, uan, emergency, voicemail, noInternationalDialling;
+@synthesize codeID, countryCode;
+@synthesize internationalPrefix, preferredInternationalPrefix, nationalPrefix, preferredExtnPrefix, nationalPrefixForParsing, nationalPrefixTransformRule, sameMobileAndFixedLinePattern, numberFormats, intlNumberFormats, mainCountryForCode, leadingDigits, leadingZeroPossible;
+
+- (id)init
+{
+    self = [super init];
+    
+    if (self)
+    {
+        [self setNumberFormats:[[NSMutableArray alloc] init]];
+        [self setIntlNumberFormats:[[NSMutableArray alloc] init]];
+
+        self.leadingZeroPossible = NO;
+        self.mainCountryForCode = NO;
+    }
+    
+    return self;
+}
+
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"* codeID[%@] countryCode[%@] generalDesc[%@] fixedLine[%@] mobile[%@] tollFree[%@] premiumRate[%@] sharedCost[%@] personalNumber[%@] voip[%@] pager[%@] uan[%@] emergency[%@] voicemail[%@] noInternationalDialling[%@] internationalPrefix[%@] preferredInternationalPrefix[%@] nationalPrefix[%@] preferredExtnPrefix[%@] nationalPrefixForParsing[%@] nationalPrefixTransformRule[%@] sameMobileAndFixedLinePattern[%@] numberFormats[%@] intlNumberFormats[%@] mainCountryForCode[%@] leadingDigits[%@] leadingZeroPossible[%@]",
+             self.codeID, self.countryCode, self.generalDesc, self.fixedLine, self.mobile, self.tollFree, self.premiumRate, self.sharedCost, self.personalNumber, self.voip, self.pager, self.uan, self.emergency, self.voicemail, self.noInternationalDialling, self.internationalPrefix, self.preferredInternationalPrefix, self.nationalPrefix, self.preferredExtnPrefix, self.nationalPrefixForParsing, self.nationalPrefixTransformRule, self.sameMobileAndFixedLinePattern?@"Y":@"N", self.numberFormats, self.intlNumberFormats, self.mainCountryForCode?@"Y":@"N", self.leadingDigits, self.leadingZeroPossible?@"Y":@"N"];
+}
+
+
+- (void)buildData:(id)data
+{
+    if (data != nil && [data isKindOfClass:[NSArray class]] )
+    {
+        /*  1 */ self.generalDesc = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:1]];
+        /*  2 */ self.fixedLine = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:2]];
+        /*  3 */ self.mobile = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:3]];
+        /*  4 */ self.tollFree = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:4]];
+        /*  5 */ self.premiumRate = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:5]];
+        /*  6 */ self.sharedCost = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:6]];
+        /*  7 */ self.personalNumber = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:7]];
+        /*  8 */ self.voip = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:8]];
+        /* 21 */ self.pager = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:21]];
+        /* 25 */ self.uan = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:25]];
+        /* 27 */ self.emergency = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:27]];
+        /* 28 */ self.voicemail = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:28]];
+        /* 24 */ self.noInternationalDialling = [[NBPhoneNumberDesc alloc] initWithData:[data safeObjectAtIndex:24]];
+        /*  9 */ self.codeID = [data safeObjectAtIndex:9];
+        /* 10 */ self.countryCode = [data safeObjectAtIndex:10];
+        /* 11 */ self.internationalPrefix = [data safeObjectAtIndex:11];
+        /* 17 */ self.preferredInternationalPrefix = [data safeObjectAtIndex:17];
+        /* 12 */ self.nationalPrefix = [data safeObjectAtIndex:12];
+        /* 13 */ self.preferredExtnPrefix = [data safeObjectAtIndex:13];
+        /* 15 */ self.nationalPrefixForParsing = [data safeObjectAtIndex:15];
+        /* 16 */ self.nationalPrefixTransformRule = [data safeObjectAtIndex:16];
+        /* 18 */ self.sameMobileAndFixedLinePattern = [[data safeObjectAtIndex:18] boolValue];
+        /* 19 */ self.numberFormats = [self numberFormatArrayFromData:[data safeObjectAtIndex:19]];     // NBNumberFormat array
+        /* 20 */ self.intlNumberFormats = [self numberFormatArrayFromData:[data safeObjectAtIndex:20]]; // NBNumberFormat array
+        /* 22 */ self.mainCountryForCode = [[data safeObjectAtIndex:22] boolValue];
+        /* 23 */ self.leadingDigits = [data safeObjectAtIndex:23];
+        /* 26 */ self.leadingZeroPossible = [[data safeObjectAtIndex:26] boolValue];
+    }
+    else
+    {
+        NSLog(@"nil data or wrong data type");
+    }
+}
+
+
+- (id)initWithCoder:(NSCoder*)coder
+{
+    if (self = [super init])
+    {
+        self.generalDesc = [coder decodeObjectForKey:@"generalDesc"];
+        self.fixedLine = [coder decodeObjectForKey:@"fixedLine"];
+        self.mobile = [coder decodeObjectForKey:@"mobile"];
+        self.tollFree = [coder decodeObjectForKey:@"tollFree"];
+        self.premiumRate = [coder decodeObjectForKey:@"premiumRate"];
+        self.sharedCost = [coder decodeObjectForKey:@"sharedCost"];
+        self.personalNumber = [coder decodeObjectForKey:@"personalNumber"];
+        self.voip = [coder decodeObjectForKey:@"voip"];
+        self.pager = [coder decodeObjectForKey:@"pager"];
+        self.uan = [coder decodeObjectForKey:@"uan"];
+        self.emergency = [coder decodeObjectForKey:@"emergency"];
+        self.voicemail = [coder decodeObjectForKey:@"voicemail"];
+        self.noInternationalDialling = [coder decodeObjectForKey:@"noInternationalDialling"];
+        self.codeID = [coder decodeObjectForKey:@"codeID"];
+        self.countryCode = [coder decodeObjectForKey:@"countryCode"];
+        self.internationalPrefix = [coder decodeObjectForKey:@"internationalPrefix"];
+        self.preferredInternationalPrefix = [coder decodeObjectForKey:@"preferredInternationalPrefix"];
+        self.nationalPrefix = [coder decodeObjectForKey:@"nationalPrefix"];
+        self.preferredExtnPrefix = [coder decodeObjectForKey:@"preferredExtnPrefix"];
+        self.nationalPrefixForParsing = [coder decodeObjectForKey:@"nationalPrefixForParsing"];
+        self.nationalPrefixTransformRule = [coder decodeObjectForKey:@"nationalPrefixTransformRule"];
+        self.sameMobileAndFixedLinePattern = [[coder decodeObjectForKey:@"sameMobileAndFixedLinePattern"] boolValue];
+        self.numberFormats = [coder decodeObjectForKey:@"numberFormats"];
+        self.intlNumberFormats = [coder decodeObjectForKey:@"intlNumberFormats"];
+        self.mainCountryForCode = [[coder decodeObjectForKey:@"mainCountryForCode"] boolValue];
+        self.leadingDigits = [coder decodeObjectForKey:@"leadingDigits"];
+        self.leadingZeroPossible = [[coder decodeObjectForKey:@"leadingZeroPossible"] boolValue];
+    }
+    return self;
+}
+
+
+- (void)encodeWithCoder:(NSCoder*)coder
+{
+    [coder encodeObject:self.generalDesc forKey:@"generalDesc"];
+    [coder encodeObject:self.fixedLine forKey:@"fixedLine"];
+    [coder encodeObject:self.mobile forKey:@"mobile"];
+    [coder encodeObject:self.tollFree forKey:@"tollFree"];
+    [coder encodeObject:self.premiumRate forKey:@"premiumRate"];
+    [coder encodeObject:self.sharedCost forKey:@"sharedCost"];
+    [coder encodeObject:self.personalNumber forKey:@"personalNumber"];
+    [coder encodeObject:self.voip forKey:@"voip"];
+    [coder encodeObject:self.pager forKey:@"pager"];
+    [coder encodeObject:self.uan forKey:@"uan"];
+    [coder encodeObject:self.emergency forKey:@"emergency"];
+    [coder encodeObject:self.voicemail forKey:@"voicemail"];
+    [coder encodeObject:self.noInternationalDialling forKey:@"noInternationalDialling"];
+    [coder encodeObject:self.codeID forKey:@"codeID"];
+    [coder encodeObject:self.countryCode forKey:@"countryCode"];
+    [coder encodeObject:self.internationalPrefix forKey:@"internationalPrefix"];
+    [coder encodeObject:self.preferredInternationalPrefix forKey:@"preferredInternationalPrefix"];
+    [coder encodeObject:self.nationalPrefix forKey:@"nationalPrefix"];
+    [coder encodeObject:self.preferredExtnPrefix forKey:@"preferredExtnPrefix"];
+    [coder encodeObject:self.nationalPrefixForParsing forKey:@"nationalPrefixForParsing"];
+    [coder encodeObject:self.nationalPrefixTransformRule forKey:@"nationalPrefixTransformRule"];
+    [coder encodeObject:[NSNumber numberWithBool:self.sameMobileAndFixedLinePattern] forKey:@"sameMobileAndFixedLinePattern"];
+    [coder encodeObject:self.numberFormats forKey:@"numberFormats"];
+    [coder encodeObject:self.intlNumberFormats forKey:@"intlNumberFormats"];
+    [coder encodeObject:[NSNumber numberWithBool:self.mainCountryForCode] forKey:@"mainCountryForCode"];
+    [coder encodeObject:self.leadingDigits forKey:@"leadingDigits"];
+    [coder encodeObject:[NSNumber numberWithBool:self.leadingZeroPossible] forKey:@"leadingZeroPossible"];
+}
+
+
+- (NSMutableArray*)numberFormatArrayFromData:(id)data
+{
+    NSMutableArray *resArray = [[NSMutableArray alloc] init];
+    if (data != nil && [data isKindOfClass:[NSArray class]])
+    {
+        for (id numFormat in data)
+        {
+            NBNumberFormat *newNumberFormat = [[NBNumberFormat alloc] initWithData:numFormat];
+            [resArray addObject:newNumberFormat];
+        }
+    }
+    
+    return resArray;
+}
+
+/*
+- (NSString*)getNormalizedNationalPrefixFormattingRule
+{
+    NSString *replacedFormattingRule = [self.nationalPrefixFormattingRule stringByReplacingOccurrencesOfString:@"$NP" withString:self.nationalPrefix];
+    return replacedFormattingRule;
+}
+
+
+- (BOOL)sameMobileAndFixedLinePattern
+{
+    if ([self.mobile isEqual:self.fixedLine]) return YES;
+    return NO;
+}
+
+
+- (NBPhoneNumberDesc*)inheriteValues:(NBPhoneNumberDesc*)targetDesc
+{
+    if (targetDesc == nil)
+    {
+        targetDesc = [[NBPhoneNumberDesc alloc] init];
+    }
+    
+    if (self.generalDesc != nil)
+    {
+        if (targetDesc.nationalNumberPattern == nil)
+        {
+            if (self.generalDesc.nationalNumberPattern != nil)
+                targetDesc.nationalNumberPattern = [self.generalDesc.nationalNumberPattern copy];
+        }
+        
+        if (targetDesc.possibleNumberPattern == nil)
+        {
+            if (self.generalDesc.possibleNumberPattern != nil)
+                targetDesc.possibleNumberPattern = [self.generalDesc.possibleNumberPattern copy];
+        }
+        
+        if (targetDesc.exampleNumber == nil)
+        {
+            if (self.generalDesc.exampleNumber != nil)
+                targetDesc.exampleNumber = [self.generalDesc.exampleNumber copy];
+        }
+    }
+    
+    return targetDesc;
+}
+
+
+- (void)updateDescriptions
+{
+    self.fixedLine = [[self inheriteValues:self.fixedLine] copy];
+    self.mobile = [[self inheriteValues:self.mobile] copy];
+    self.tollFree = [[self inheriteValues:self.tollFree] copy];
+    self.premiumRate = [[self inheriteValues:self.premiumRate] copy];
+    self.sharedCost = [[self inheriteValues:self.sharedCost] copy];
+    self.personalNumber = [[self inheriteValues:self.personalNumber] copy];
+    self.voip = [[self inheriteValues:self.voip] copy];
+    self.pager = [[self inheriteValues:self.pager] copy];
+    self.uan = [[self inheriteValues:self.uan] copy];
+    self.emergency = [[self inheriteValues:self.emergency] copy];
+    self.voicemail = [[self inheriteValues:self.voicemail] copy];
+    self.noInternationalDialling = [[self inheriteValues:self.noInternationalDialling] copy];
+}
+
+
+- (void)setAttributes:(NSDictionary*)data
+{
+    NSString *attributeName = [data valueForKey:@"attributeName"];
+    id attributeContent = [data valueForKey:@"nodeContent"];
+    
+    if ([attributeContent isKindOfClass:[NSString class]] && [attributeContent length] > 0)
+        attributeContent = [NBPhoneNumberManager stringByTrimming:attributeContent];
+    
+    if (attributeName && [attributeName isKindOfClass:[NSString class]] && [attributeName length]  > 0 && [attributeName isEqualToString:@"id"] &&
+        attributeContent && [attributeContent isKindOfClass:[NSString class]] && [attributeContent length] > 0)
+    {
+        [self setCodeID:attributeContent];
+    }
+    else if (attributeName && [attributeName isKindOfClass:[NSString class]] && [attributeName length]  > 0 && attributeContent && [attributeContent isKindOfClass:[NSString class]] && [attributeContent length] > 0)
+    {
+        @try {
+            if ([[attributeContent lowercaseString] isEqualToString:@"true"])
+            {
+                [self setValue:[NSNumber numberWithBool:YES] forKey:attributeName];
+            }
+            else if ([[attributeContent lowercaseString] isEqualToString:@"false"])
+            {
+                [self setValue:[NSNumber numberWithBool:NO] forKey:attributeName];
+            }
+            else
+            {
+                [self setValue:attributeContent forKey:attributeName];
+            }
+        }
+        @catch (NSException *ex) {
+            NSLog(@"setAttributes setValue:%@ forKey:%@ error [%@]", attributeContent, attributeName, [attributeContent class]);
+        }
+    }
+}
+
+
+- (BOOL)setChilds:(id)data
+{
+    if (data && [data isKindOfClass:[NSDictionary class]])
+    {
+        NSString *nodeName = [data valueForKey:@"nodeName"];
+        id nodeContent = [data valueForKey:@"nodeContent"];
+        
+        if ([nodeContent isKindOfClass:[NSString class]] && [nodeContent length] > 0)
+            nodeContent = [NBPhoneNumberManager stringByTrimming:nodeContent];
+        
+        // [TYPE] PhoneNumberDesc
+        if ([nodeName isEqualToString:@"generalDesc"] || [nodeName isEqualToString:@"fixedLine"] || [nodeName isEqualToString:@"mobile"] || [nodeName isEqualToString:@"shortCode"] || [nodeName isEqualToString:@"emergency"] || [nodeName isEqualToString:@"voip"] || [nodeName isEqualToString:@"voicemail"] || [nodeName isEqualToString:@"uan"] || [nodeName isEqualToString:@"premiumRate"] || [nodeName isEqualToString:@"nationalNumberPattern"] || [nodeName isEqualToString:@"sharedCost"] || [nodeName isEqualToString:@"tollFree"] || [nodeName isEqualToString:@"noInternationalDialling"] || [nodeName isEqualToString:@"personalNumber"] || [nodeName isEqualToString:@"pager"] || [nodeName isEqualToString:@"areaCodeOptional"])
+        {
+            [self setNumberDescData:data];
+            return YES;
+        }
+        else if ([nodeName isEqualToString:@"availableFormats"])
+        {
+            [self setNumberFormatsData:data];
+            return YES;
+        }
+        else if ([nodeName isEqualToString:@"comment"] == NO && [nodeContent isKindOfClass:[NSString class]])
+        {
+            [self setValue:nodeContent forKey:nodeName];
+            return YES;
+        }
+        else if ([nodeName isEqualToString:@"comment"])
+        {
+            return YES;
+        }
+    }
+    
+    return NO;
+}
+
+
+- (void)setNumberFormatsData:(id)data
+{
+    NSArray *nodeChildArray = [data valueForKey:@"nodeChildArray"];
+    
+    for (id childNumberFormat in nodeChildArray)
+    {
+        NSArray *nodeChildAttributeNumberFormatArray = [childNumberFormat valueForKey:@"nodeAttributeArray"];
+        NSArray *nodeChildNodeNumberFormatArray = [childNumberFormat valueForKey:@"nodeChildArray"];
+        
+        NSString *nodeName = [childNumberFormat valueForKey:@"nodeName"];
+        
+        if ([nodeName isEqualToString:@"numberFormat"])
+        {
+            NBNumberFormat *newNumberFormat = [[NBNumberFormat alloc] init];
+            
+            for (id childAttribute in nodeChildAttributeNumberFormatArray)
+            {
+                NSString *childNodeName = [childAttribute valueForKey:@"attributeName"];
+                NSString *childNodeContent = nil;
+                
+                if ([childNodeName isEqualToString:@"comment"])
+                {
+                    continue;
+                }
+                
+                childNodeContent = [NBPhoneNumberManager stringByTrimming:[childAttribute valueForKey:@"nodeContent"]];
+                
+                @try {
+                    [newNumberFormat setValue:childNodeContent forKey:childNodeName];
+                }
+                @catch (NSException *ex) {
+                    NSLog(@"nodeChildAttributeArray setValue:%@ forKey:%@ error [%@] %@", childNodeContent, childNodeName, [childNodeContent class], childAttribute);
+                }
+            }
+            
+            for (id childNode in nodeChildNodeNumberFormatArray)
+            {
+                NSString *childNodeName = [childNode valueForKey:@"nodeName"];
+                NSString *childNodeContent = nil;
+                
+                if ([childNodeName isEqualToString:@"comment"])
+                {
+                    continue;
+                }
+                
+                childNodeContent = [NBPhoneNumberManager stringByTrimming:[childNode valueForKey:@"nodeContent"]];
+                
+                @try {
+                    if ([childNodeName isEqualToString:@"leadingDigits"])
+                    {
+                        [newNumberFormat.leadingDigitsPattern addObject:childNodeContent];
+                    }
+                    else
+                    {
+                        if ([[childNodeContent lowercaseString] isEqualToString:@"true"])
+                        {
+                            [newNumberFormat setValue:[NSNumber numberWithBool:YES] forKey:childNodeName];
+                        }
+                        else if ([[childNodeContent lowercaseString] isEqualToString:@"false"])
+                        {
+                            [newNumberFormat setValue:[NSNumber numberWithBool:NO] forKey:childNodeName];
+                        }
+                        else
+                        {
+                            [newNumberFormat setValue:childNodeContent forKey:childNodeName];
+                        }
+                    }
+                }
+                @catch (NSException *ex) {
+                    NSLog(@"nodeChildArray setValue:%@ forKey:%@ error [%@] %@", childNodeContent, childNodeName, [childNodeContent class], childNode);
+                }
+            }
+            [self.numberFormats addObject:newNumberFormat];
+        }
+        else if ([nodeName isEqualToString:@"comment"] == NO)
+        {
+            NSLog(@"process ========== %@", childNumberFormat);
+        }
+    }
+}
+
+
+- (void)setNumberDescData:(id)data
+{
+    NSString *nodeName = [data valueForKey:@"nodeName"];
+    NSArray *nodeChildArray = [data valueForKey:@"nodeChildArray"];
+    
+    NBPhoneNumberDesc *newNumberDesc = [[NBPhoneNumberDesc alloc] init];
+    
+    for (id childNode in nodeChildArray)
+    {
+        NSString *childNodeName = [childNode valueForKey:@"nodeName"];
+        NSString *childNodeContent = [NBPhoneNumberManager stringByTrimming:[childNode valueForKey:@"nodeContent"]];
+        
+        if ([childNodeName isEqualToString:@"comment"])
+        {
+            continue;
+        }
+        
+        @try {
+            if (childNodeContent && childNodeContent.length > 0)
+            {
+                [newNumberDesc setValue:childNodeContent forKey:childNodeName];
+            }
+        }
+        @catch (NSException *ex) {
+            NSLog(@"setNumberDesc setValue:%@ forKey:%@ error [%@]", childNodeContent, childNodeName, [childNodeContent class]);
+        }
+    }
+    
+    nodeName = [nodeName lowercaseString];
+    
+    if ([nodeName isEqualToString:[@"generalDesc" lowercaseString]])
+        self.generalDesc = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"fixedLine" lowercaseString]])
+        self.fixedLine = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"mobile" lowercaseString]])
+        self.mobile = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"tollFree" lowercaseString]]) {
+        [self setTollFree:newNumberDesc];
+    }
+    
+    if ([nodeName isEqualToString:[@"premiumRate" lowercaseString]])
+        self.premiumRate = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"sharedCost" lowercaseString]]) {
+        self.sharedCost = newNumberDesc;
+    }
+    
+    if ([nodeName isEqualToString:[@"personalNumber" lowercaseString]])
+        self.personalNumber = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"voip" lowercaseString]])
+        self.voip = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"pager" lowercaseString]])
+        self.pager = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"uan" lowercaseString]])
+        self.uan = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"emergency" lowercaseString]])
+        self.emergency = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"voicemail" lowercaseString]])
+        self.voicemail = newNumberDesc;
+    
+    if ([nodeName isEqualToString:[@"noInternationalDialling" lowercaseString]])
+        self.noInternationalDialling = newNumberDesc;
+    
+    [self updateDescriptions];
+}
+*/
+
+@end
\ No newline at end of file
diff --git a/libPhoneNumber/NBPhoneNumber.h b/libPhoneNumber/NBPhoneNumber.h
new file mode 100644
index 0000000..dfa3b17
--- /dev/null
+++ b/libPhoneNumber/NBPhoneNumber.h
@@ -0,0 +1,25 @@
+//
+//  NBPhoneNumber.h
+//  libPhoneNumber
+//  
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import <Foundation/Foundation.h>
+#import "NBPhoneNumberDefines.h"
+
+@interface NBPhoneNumber : NSObject <NSCopying>
+
+// from phonemetadata.pb.js
+/* 1 */ @property (nonatomic, strong, readwrite) NSNumber *countryCode;
+/* 2 */ @property (nonatomic, strong, readwrite) NSNumber *nationalNumber;
+/* 3 */ @property (nonatomic, strong, readwrite) NSString *extension;
+/* 4 */ @property (nonatomic, assign, readwrite) BOOL italianLeadingZero;
+/* 5 */ @property (nonatomic, strong, readwrite) NSString *rawInput;
+/* 6 */ @property (nonatomic, strong, readwrite) NSNumber *countryCodeSource;
+/* 7 */ @property (nonatomic, strong, readwrite) NSString *preferredDomesticCarrierCode;
+
+- (void)clearCountryCodeSource;
+- (NBECountryCodeSource)getCountryCodeSourceOrDefault;
+
+@end
\ No newline at end of file
diff --git a/libPhoneNumber/NBPhoneNumber.m b/libPhoneNumber/NBPhoneNumber.m
new file mode 100644
index 0000000..cd79761
--- /dev/null
+++ b/libPhoneNumber/NBPhoneNumber.m
@@ -0,0 +1,121 @@
+//
+//  NBPhoneNumber.m
+//  libPhoneNumber
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import "NBPhoneNumber.h"
+#import "NBPhoneNumberDefines.h"
+
+@implementation NBPhoneNumber
+
+@synthesize countryCode, nationalNumber, extension, italianLeadingZero, rawInput, countryCodeSource, preferredDomesticCarrierCode;
+
+- (id)init
+{
+    self = [super init];
+    
+    if (self)
+    {
+        self.countryCodeSource = nil;
+        self.italianLeadingZero = NO;
+        self.nationalNumber = @-1;
+        self.countryCode = @-1;
+    }
+    
+    return self;
+}
+
+
+- (void)clearCountryCodeSource
+{
+    [self setCountryCodeSource:nil];
+}
+
+
+- (NBECountryCodeSource)getCountryCodeSourceOrDefault
+{
+    if (self.countryCodeSource == nil)
+        return NBECountryCodeSourceFROM_NUMBER_WITH_PLUS_SIGN;
+    
+    return [self.countryCodeSource intValue];
+}
+
+
+- (BOOL)isEqualToObject:(NBPhoneNumber*)otherObj
+{
+    return [self isEqual:otherObj];
+}
+
+
+- (NSUInteger)hash
+{
+    NSData *selfObject = [NSKeyedArchiver archivedDataWithRootObject:self];
+    return [selfObject hash];
+}
+
+
+- (BOOL)isEqual:(id)object
+{
+    if ([object isKindOfClass:[NBPhoneNumber class]] == NO)
+        return NO;
+    
+    NBPhoneNumber *other = object;
+    return ([self.countryCode isEqualToNumber: other.countryCode]) && ([self.nationalNumber isEqualToNumber: other.nationalNumber]) &&
+        (self.italianLeadingZero == other.italianLeadingZero) &&
+        ((self.extension == nil && other.extension == nil) || [self.extension isEqualToString:other.extension]);
+}
+
+
+- (id)copyWithZone:(NSZone *)zone
+{
+	NBPhoneNumber *phoneNumberCopy = [[NBPhoneNumber allocWithZone:zone] init];
+    
+	phoneNumberCopy.countryCode = [self.countryCode copy];
+    phoneNumberCopy.nationalNumber = [self.nationalNumber copy];
+    phoneNumberCopy.extension = [self.extension copy];
+    phoneNumberCopy.italianLeadingZero = self.italianLeadingZero;
+    phoneNumberCopy.rawInput = [self.rawInput copy];
+    phoneNumberCopy.countryCodeSource = [self.countryCodeSource copy];
+    phoneNumberCopy.preferredDomesticCarrierCode = [self.preferredDomesticCarrierCode copy];
+    
+	return phoneNumberCopy;
+}
+
+
+- (id)initWithCoder:(NSCoder*)coder
+{
+    if (self = [super init])
+    {
+        self.countryCode = [coder decodeObjectForKey:@"countryCode"];
+        self.nationalNumber = [coder decodeObjectForKey:@"nationalNumber"];
+        self.extension = [coder decodeObjectForKey:@"extension"];
+        self.italianLeadingZero = [[coder decodeObjectForKey:@"italianLeadingZero"] boolValue];
+        self.rawInput = [coder decodeObjectForKey:@"rawInput"];
+        self.countryCodeSource = [coder decodeObjectForKey:@"countryCodeSource"];
+        self.preferredDomesticCarrierCode = [coder decodeObjectForKey:@"preferredDomesticCarrierCode"];
+    }
+    return self;
+}
+
+
+- (void)encodeWithCoder:(NSCoder*)coder
+{
+    [coder encodeObject:self.countryCode forKey:@"countryCode"];
+    [coder encodeObject:self.nationalNumber forKey:@"nationalNumber"];
+    [coder encodeObject:self.extension forKey:@"extension"];
+    [coder encodeObject:[NSNumber numberWithBool:self.italianLeadingZero] forKey:@"italianLeadingZero"];
+    [coder encodeObject:self.rawInput forKey:@"rawInput"];
+    [coder encodeObject:self.countryCodeSource forKey:@"countryCodeSource"];
+    [coder encodeObject:self.preferredDomesticCarrierCode forKey:@"preferredDomesticCarrierCode"];
+}
+
+
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@" - countryCode[%@], nationalNumber[%@], extension[%@], italianLeadingZero[%@], rawInput[%@] countryCodeSource[%d] preferredDomesticCarrierCode[%@]", self.countryCode, self.nationalNumber, self.extension, self.italianLeadingZero?@"Y":@"N", self.rawInput, [self.countryCodeSource intValue], self.preferredDomesticCarrierCode];
+}
+
+@end
diff --git a/libPhoneNumber/NBPhoneNumberDefines.h b/libPhoneNumber/NBPhoneNumberDefines.h
new file mode 100644
index 0000000..f7c9bf8
--- /dev/null
+++ b/libPhoneNumber/NBPhoneNumberDefines.h
@@ -0,0 +1,107 @@
+//
+//  NBPhoneNumberDefines.h
+//  libPhoneNumber
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#ifndef libPhoneNumber_NBPhoneNumberDefines_h
+#define libPhoneNumber_NBPhoneNumberDefines_h
+
+#define NB_YES [NSNumber numberWithBool:YES]
+#define NB_NO [NSNumber numberWithBool:NO]
+
+#pragma mark - Enum -
+
+typedef enum {
+    NBEPhoneNumberFormatE164 = 0,
+    NBEPhoneNumberFormatINTERNATIONAL = 1,
+    NBEPhoneNumberFormatNATIONAL = 2,
+    NBEPhoneNumberFormatRFC3966 = 3
+} NBEPhoneNumberFormat;
+
+
+typedef enum {
+    NBEPhoneNumberTypeFIXED_LINE = 0,
+    NBEPhoneNumberTypeMOBILE = 1,
+    // In some regions (e.g. the USA), it is impossible to distinguish between
+    // fixed-line and mobile numbers by looking at the phone number itself.
+    NBEPhoneNumberTypeFIXED_LINE_OR_MOBILE = 2,
+    // Freephone lines
+    NBEPhoneNumberTypeTOLL_FREE = 3,
+    NBEPhoneNumberTypePREMIUM_RATE = 4,
+    // The cost of this call is shared between the caller and the recipient, and
+    // is hence typically less than PREMIUM_RATE calls. See
+    // http://en.wikipedia.org/wiki/Shared_Cost_Service for more information.
+    NBEPhoneNumberTypeSHARED_COST = 5,
+    // Voice over IP numbers. This includes TSoIP (Telephony Service over IP).
+    NBEPhoneNumberTypeVOIP = 6,
+    // A personal number is associated with a particular person, and may be routed
+    // to either a MOBILE or FIXED_LINE number. Some more information can be found
+    // here = http://en.wikipedia.org/wiki/Personal_Numbers
+    NBEPhoneNumberTypePERSONAL_NUMBER = 7,
+    NBEPhoneNumberTypePAGER = 8,
+    // Used for 'Universal Access Numbers' or 'Company Numbers'. They may be
+    // further routed to specific offices, but allow one number to be used for a
+    // company.
+    NBEPhoneNumberTypeUAN = 9,
+    // Used for 'Voice Mail Access Numbers'.
+    NBEPhoneNumberTypeVOICEMAIL = 10,
+    // A phone number is of type UNKNOWN when it does not fit any of the known
+    // patterns for a specific region.
+    NBEPhoneNumberTypeUNKNOWN = -1
+} NBEPhoneNumberType;
+
+
+typedef enum {
+    NBEMatchTypeNOT_A_NUMBER = 0,
+    NBEMatchTypeNO_MATCH = 1,
+    NBEMatchTypeSHORT_NSN_MATCH = 2,
+    NBEMatchTypeNSN_MATCH = 3,
+    NBEMatchTypeEXACT_MATCH = 4
+} NBEMatchType;
+
+
+typedef enum {
+    NBEValidationResultIS_POSSIBLE = 0,
+    NBEValidationResultINVALID_COUNTRY_CODE = 1,
+    NBEValidationResultTOO_SHORT = 2,
+    NBEValidationResultTOO_LONG = 3
+} NBEValidationResult;
+
+
+typedef enum {
+    NBECountryCodeSourceFROM_NUMBER_WITH_PLUS_SIGN = 1,
+    NBECountryCodeSourceFROM_NUMBER_WITH_IDD = 5,
+    NBECountryCodeSourceFROM_NUMBER_WITHOUT_PLUS_SIGN = 10,
+    NBECountryCodeSourceFROM_DEFAULT_COUNTRY = 20
+} NBECountryCodeSource;
+
+
+@interface NSArray (NBAdditions)
+
+- (id)safeObjectAtIndex:(NSUInteger)index;
+
+@end
+
+
+@implementation NSArray (NBAdditions)
+
+- (id)safeObjectAtIndex:(NSUInteger)index
+{
+    @synchronized(self)
+    {
+        if(index >= [self count]) return nil;
+        
+        id res = [self objectAtIndex:index];
+        
+        if (res == nil || (NSNull*)res == [NSNull null])
+            return nil;
+        
+        return res;
+    }
+}
+
+@end
+
+#endif
diff --git a/libPhoneNumber/NBPhoneNumberDesc.h b/libPhoneNumber/NBPhoneNumberDesc.h
new file mode 100644
index 0000000..288727c
--- /dev/null
+++ b/libPhoneNumber/NBPhoneNumberDesc.h
@@ -0,0 +1,19 @@
+//
+//  NBPhoneNumberDesc.h
+//  libPhoneNumber
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NBPhoneNumberDesc : NSObject
+
+// from phonemetadata.pb.js
+/* 2 */ @property (nonatomic, strong, readwrite) NSString *nationalNumberPattern;
+/* 3 */ @property (nonatomic, strong, readwrite) NSString *possibleNumberPattern;
+/* 6 */ @property (nonatomic, strong, readwrite) NSString *exampleNumber;
+
+- (id)initWithData:(id)data;
+
+@end
diff --git a/libPhoneNumber/NBPhoneNumberDesc.m b/libPhoneNumber/NBPhoneNumberDesc.m
new file mode 100644
index 0000000..f698103
--- /dev/null
+++ b/libPhoneNumber/NBPhoneNumberDesc.m
@@ -0,0 +1,90 @@
+//
+//  NBPhoneNumberDesc.m
+//  libPhoneNumber
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import "NBPhoneNumberDesc.h"
+#import "NBPhoneNumberDefines.h"
+
+@implementation NBPhoneNumberDesc
+
+@synthesize nationalNumberPattern, possibleNumberPattern, exampleNumber;
+
+
+- (id)initWithData:(id)data
+{
+    self = [self init];
+    
+    if (self && data != nil && [data isKindOfClass:[NSArray class]])
+    {
+        /* 2 */ self.nationalNumberPattern = [data safeObjectAtIndex:2];
+        /* 3 */ self.possibleNumberPattern = [data safeObjectAtIndex:3];
+        /* 6 */ self.exampleNumber = [data safeObjectAtIndex:6];
+    }
+    
+    return self;
+}
+
+
+- (id)init
+{
+    self = [super init];
+    
+    if (self)
+    {
+    }
+    
+    return self;
+}
+
+
+- (id)initWithCoder:(NSCoder*)coder
+{
+    if (self = [super init])
+    {
+        self.nationalNumberPattern = [coder decodeObjectForKey:@"nationalNumberPattern"];
+        self.possibleNumberPattern = [coder decodeObjectForKey:@"possibleNumberPattern"];
+        self.exampleNumber = [coder decodeObjectForKey:@"exampleNumber"];
+    }
+    return self;
+}
+
+
+- (void)encodeWithCoder:(NSCoder*)coder
+{
+    [coder encodeObject:self.nationalNumberPattern forKey:@"nationalNumberPattern"];
+    [coder encodeObject:self.possibleNumberPattern forKey:@"possibleNumberPattern"];
+    [coder encodeObject:self.exampleNumber forKey:@"exampleNumber"];
+}
+
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"nationalNumberPattern[%@] possibleNumberPattern[%@] exampleNumber[%@]", self.nationalNumberPattern, self.possibleNumberPattern, self.exampleNumber];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+	NBPhoneNumberDesc *phoneDescCopy = [[NBPhoneNumberDesc allocWithZone:zone] init];
+    
+    phoneDescCopy.nationalNumberPattern = [self.nationalNumberPattern copy];
+    phoneDescCopy.possibleNumberPattern = [self.possibleNumberPattern copy];
+    phoneDescCopy.exampleNumber = [self.exampleNumber copy];
+    
+	return phoneDescCopy;
+}
+
+- (BOOL)isEqual:(id)object
+{
+    if ([object isKindOfClass:[NBPhoneNumberDesc class]] == NO)
+        return NO;
+    
+    NBPhoneNumberDesc *other = object;
+    return [self.nationalNumberPattern isEqual:other.nationalNumberPattern] &&
+        [self.possibleNumberPattern isEqual:other.possibleNumberPattern] &&
+        [self.exampleNumber isEqual:other.exampleNumber];
+}
+
+@end
diff --git a/libPhoneNumber/NBPhoneNumberMetadata.plist b/libPhoneNumber/NBPhoneNumberMetadata.plist
new file mode 100644
index 0000000..8cd2d03
--- /dev/null
+++ b/libPhoneNumber/NBPhoneNumberMetadata.plist
Binary files differ
diff --git a/libPhoneNumber/NBPhoneNumberUtil.h b/libPhoneNumber/NBPhoneNumberUtil.h
new file mode 100644
index 0000000..e9e13ec
--- /dev/null
+++ b/libPhoneNumber/NBPhoneNumberUtil.h
@@ -0,0 +1,108 @@
+//
+//  NBPhoneNumberUtil.h
+//  Band
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import <Foundation/Foundation.h>
+#import "NBPhoneNumberDefines.h"
+
+@class NBPhoneMetaData, NBPhoneNumber;
+
+@interface NBPhoneNumberUtil : NSObject
+
++ (NBPhoneNumberUtil*)sharedInstance;
++ (NBPhoneNumberUtil*)sharedInstanceForTest;
+
+// regular expressions
+- (NSArray*)matchesByRegex:(NSString*)sourceString regex:(NSString*)pattern;
+- (NSArray*)matchedStringByRegex:(NSString*)sourceString regex:(NSString*)pattern;
+- (NSString*)replaceStringByRegex:(NSString*)sourceString regex:(NSString*)pattern withTemplate:(NSString*)templateString;
+- (NSInteger)stringPositionByRegex:(NSString*)sourceString regex:(NSString*)pattern;
+
+
++ (NSString*)stringByTrimming:(NSString*)aString;
+
+//- (NSString*)numbersOnly:(NSString*)phoneNumber;
+- (NSArray*)regionCodeFromCountryCode:(NSNumber *)countryCodeNumber;
+- (NSString*)countryCodeFromRegionCode:(NSString*)regionCode;
+
+
+// libPhoneNumber Util functions
+- (NSString*)convertAlphaCharactersInNumber:(NSString*)number;
+
+- (NSString*)normalizePhoneNumber:(NSString*)phoneNumber;
+- (NSString*)normalizeDigitsOnly:(NSString*)number;
+
+- (BOOL)isNumberGeographical:(NBPhoneNumber*)phoneNumber;
+
+- (NSString*)extractPossibleNumber:(NSString*)phoneNumber;
+- (NSNumber*)extractCountryCode:(NSString*)fullNumber nationalNumber:(NSString**)nationalNumber;
+
+- (NSString*)getNddPrefixForRegion:(NSString*)regionCode stripNonDigits:(BOOL)stripNonDigits;
+- (NSString*)getNationalSignificantNumber:(NBPhoneNumber*)phoneNumber;
+
+- (NBEPhoneNumberType)getNumberType:(NBPhoneNumber*)phoneNumber;
+
+- (NSNumber*)getCountryCodeForRegion:(NSString*)regionCode;
+
+- (NSString*)getRegionCodeForCountryCode:(NSNumber*)countryCallingCode;
+- (NSArray*)getRegionCodesForCountryCode:(NSNumber*)countryCallingCode;
+- (NSString*)getRegionCodeForNumber:(NBPhoneNumber*)phoneNumber;
+
+- (NBPhoneNumber*)getExampleNumber:(NSString*)regionCode error:(NSError**)error;
+- (NBPhoneNumber*)getExampleNumberForType:(NSString*)regionCode type:(NBEPhoneNumberType)type error:(NSError**)error;
+- (NBPhoneNumber*)getExampleNumberForNonGeoEntity:(NSNumber*)countryCallingCode error:(NSError**)error;
+
+- (NBPhoneMetaData*)getMetadataForNonGeographicalRegion:(NSNumber*)countryCallingCode;
+- (NBPhoneMetaData*)getMetadataForRegion:(NSString*)regionCode;
+
+- (BOOL)canBeInternationallyDialled:(NBPhoneNumber*)number error:(NSError**)error;
+
+- (BOOL)truncateTooLongNumber:(NBPhoneNumber*)number error:(NSError**)error;
+
+- (BOOL)isValidNumber:(NBPhoneNumber*)number;
+- (BOOL)isViablePhoneNumber:(NSString*)phoneNumber;
+- (BOOL)isAlphaNumber:(NSString*)number;
+- (BOOL)isValidNumberForRegion:(NBPhoneNumber*)number regionCode:(NSString*)regionCode;
+- (BOOL)isNANPACountry:(NSString*)regionCode;
+- (BOOL)isLeadingZeroPossible:(NSNumber*)countryCallingCode;
+
+- (NBEValidationResult)isPossibleNumberWithReason:(NBPhoneNumber*)number error:(NSError**)error;
+
+- (BOOL)isPossibleNumber:(NBPhoneNumber*)number error:(NSError**)error;
+- (BOOL)isPossibleNumberString:(NSString*)number regionDialingFrom:(NSString*)regionDialingFrom error:(NSError**)error;
+
+- (NBEMatchType)isNumberMatch:(id)firstNumberIn second:(id)secondNumberIn error:(NSError**)error;
+
+- (NSUInteger)getLengthOfGeographicalAreaCode:(NBPhoneNumber*)phoneNumber error:(NSError**)error;
+- (NSUInteger)getLengthOfNationalDestinationCode:(NBPhoneNumber*)phoneNumber error:(NSError**)error;
+
+- (BOOL)maybeStripNationalPrefixAndCarrierCode:(NSString**)numberStr metadata:(NBPhoneMetaData*)metadata carrierCode:(NSString**)carrierCode error:(NSError**)error;
+- (NBECountryCodeSource)maybeStripInternationalPrefixAndNormalize:(NSString**)numberStr possibleIddPrefix:(NSString*)possibleIddPrefix error:(NSError**)error;
+- (NSNumber*)maybeExtractCountryCode:(NSString*)number metadata:(NBPhoneMetaData*)defaultRegionMetadata
+                   nationalNumber:(NSString**)nationalNumber keepRawInput:(BOOL)keepRawInput phoneNumber:(NBPhoneNumber**)phoneNumber error:(NSError**)error;
+
+- (NBPhoneNumber*)parse:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion error:(NSError**)error;
+- (NBPhoneNumber*)parseAndKeepRawInput:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion error:(NSError**)error;
+- (NBPhoneNumber*)parseWithPhoneCarrierRegion:(NSString*)numberToParse error:(NSError**)error;
+
+- (NSString*)format:(NBPhoneNumber*)phoneNumber numberFormat:(NBEPhoneNumberFormat)numberFormat error:(NSError**)error;
+- (NSString*)formatByPattern:(NBPhoneNumber*)number numberFormat:(NBEPhoneNumberFormat)numberFormat userDefinedFormats:(NSArray*)userDefinedFormats error:(NSError**)error;
+- (NSString*)formatNumberForMobileDialing:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom withFormatting:(BOOL)withFormatting error:(NSError**)error;
+- (NSString*)formatOutOfCountryCallingNumber:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom error:(NSError**)error;
+- (NSString*)formatOutOfCountryKeepingAlphaChars:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom error:(NSError**)error;
+- (NSString*)formatNationalNumberWithCarrierCode:(NBPhoneNumber*)number carrierCode:(NSString*)carrierCode error:(NSError**)error;
+- (NSString*)formatInOriginalFormat:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom error:(NSError**)error;
+- (NSString*)formatNationalNumberWithPreferredCarrierCode:(NBPhoneNumber*)number fallbackCarrierCode:(NSString*)fallbackCarrierCode error:(NSError**)error;
+
+- (BOOL)formattingRuleHasFirstGroupOnly:(NSString*)nationalPrefixFormattingRule;
+
+@property (nonatomic, readonly) NSString *VALID_PUNCTUATION;
+@property (nonatomic, readonly) NSString *VALID_DIGITS_STRING;
+@property (nonatomic, readonly) NSString *PLUS_CHARS_;
+@property (nonatomic, readonly) NSString *REGION_CODE_FOR_NON_GEO_ENTITY;
+@property (nonatomic, readonly) NSDictionary *DIGIT_MAPPINGS;
+
+@end
diff --git a/libPhoneNumber/NBPhoneNumberUtil.m b/libPhoneNumber/NBPhoneNumberUtil.m
new file mode 100644
index 0000000..bfb95c9
--- /dev/null
+++ b/libPhoneNumber/NBPhoneNumberUtil.m
@@ -0,0 +1,4305 @@
+//
+//  NBPhoneNumberUtil.m
+//  Band
+//
+//  Created by NHN Corp. Last Edited by BAND dev team (band_dev@nhn.com)
+//
+
+#import "NBPhoneNumberUtil.h"
+#import "NBPhoneNumber.h"
+#import "NBNumberFormat.h"
+#import "NBPhoneNumberDesc.h"
+#import "NBPhoneMetaData.h"
+#import "math.h"
+
+#import <CoreTelephony/CTTelephonyNetworkInfo.h>
+#import <CoreTelephony/CTCarrier.h>
+
+
+#pragma mark - Static Int variables -
+const static NSUInteger NANPA_COUNTRY_CODE_ = 1;
+const static NSUInteger MIN_LENGTH_FOR_NSN_ = 2;
+const static NSUInteger MAX_LENGTH_FOR_NSN_ = 16;
+const static NSUInteger MAX_LENGTH_COUNTRY_CODE_ = 3;
+const static NSUInteger MAX_INPUT_STRING_LENGTH_ = 250;
+
+
+#pragma mark - Static String variables -
+NSString *INVALID_COUNTRY_CODE_STR = @"Invalid country calling code";
+NSString *NOT_A_NUMBER_STR = @"The string supplied did not seem to be a phone number";
+NSString *TOO_SHORT_AFTER_IDD_STR = @"Phone number too short after IDD";
+NSString *TOO_SHORT_NSN_STR = @"The string supplied is too short to be a phone number";
+NSString *TOO_LONG_STR = @"The string supplied is too long to be a phone number";
+
+NSString *UNKNOWN_REGION_ = @"ZZ";
+NSString *COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX_ = @"3";
+NSString *PLUS_SIGN = @"+";
+NSString *STAR_SIGN_ = @"*";
+NSString *RFC3966_EXTN_PREFIX_ = @";ext=";
+NSString *RFC3966_PREFIX_ = @"tel:";
+NSString *RFC3966_PHONE_CONTEXT_ = @";phone-context=";
+NSString *RFC3966_ISDN_SUBADDRESS_ = @";isub=";
+NSString *DEFAULT_EXTN_PREFIX_ = @" ext. ";
+NSString *VALID_ALPHA_ = @"A-Za-z";
+
+#pragma mark - Static regular expression strings -
+NSString *NON_DIGITS_PATTERN_ = @"\\D+";
+NSString *CC_PATTERN_ = @"\\$CC";
+NSString *FIRST_GROUP_PATTERN_ = @"(\\$\\d)";
+NSString *FIRST_GROUP_ONLY_PREFIX_PATTERN_ = @"^\\(?\\$1\\)?";
+NSString *NP_PATTERN_ = @"\\$NP";
+NSString *FG_PATTERN_ = @"\\$FG";
+NSString *VALID_ALPHA_PHONE_PATTERN_STRING = @"(?:.*?[A-Za-z]){3}.*";
+NSString *UNIQUE_INTERNATIONAL_PREFIX_ = @"[\\d]+(?:[~\\u2053\\u223C\\uFF5E][\\d]+)?";
+
+
+#pragma mark - NBPhoneNumberUtil interface -
+@interface NBPhoneNumberUtil ()
+
+/*
+ Terminologies
+ - Country Number (CN)  = Country code for i18n calling
+ - Country Code   (CC) : ISO country codes (2 chars)
+ Ref. site (countrycode.org)
+ */
+@property (nonatomic, readonly) NSDictionary *coreMetaData;
+@property (nonatomic, readonly) NSRegularExpression *PLUS_CHARS_PATTERN, *CAPTURING_DIGIT_PATTERN, *VALID_ALPHA_PHONE_PATTERN_;
+@property (nonatomic, readonly) NSString *LEADING_PLUS_CHARS_PATTERN_, *EXTN_PATTERN_, *SEPARATOR_PATTERN_, *VALID_PHONE_NUMBER_PATTERN_, *VALID_START_CHAR_PATTERN_, *UNWANTED_END_CHAR_PATTERN_, *SECOND_NUMBER_START_PATTERN_;
+
+@property (nonatomic, readonly) NSDictionary *ALPHA_MAPPINGS_, *ALL_NORMALIZATION_MAPPINGS_, *DIALLABLE_CHAR_MAPPINGS_, *ALL_PLUS_NUMBER_GROUPING_SYMBOLS_;
+
+@property (nonatomic, strong, readwrite) NSMutableDictionary *mapCCode2CN;
+@property (nonatomic, strong, readwrite) NSMutableDictionary *mapCN2CCode;
+
+@property (nonatomic, strong, readwrite) NSMutableDictionary *i18nNumberFormat;
+@property (nonatomic, strong, readwrite) NSMutableDictionary *i18nPhoneNumberDesc;
+@property (nonatomic, strong, readwrite) NSMutableDictionary *i18nPhoneMetadata;
+
+@end
+
+
+@implementation NBPhoneNumberUtil
+
++ (NBPhoneNumberUtil*)sharedInstance
+{
+    static NBPhoneNumberUtil *sharedOnceInstance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{ sharedOnceInstance = [[self alloc] init]; });
+    return sharedOnceInstance;
+}
+
+
++ (NBPhoneNumberUtil*)sharedInstanceForTest
+{
+    static NBPhoneNumberUtil *sharedOnceInstanceForTest = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{ sharedOnceInstanceForTest = [[self alloc] initForTest]; });
+    return sharedOnceInstanceForTest;
+}
+
+
++ (NSString*)stringByTrimming:(NSString*)aString
+{
+    NSString *aRes = @"";
+    NSArray *newlines = [aString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
+    for (NSString *line in newlines)
+    {
+        NSString *performedString = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+        
+        if (performedString.length > 0)
+            aRes = [aRes stringByAppendingString:performedString];
+    }
+    
+    if (newlines.count <= 0)
+        return aString;
+    
+    return aRes;
+}
+
+
+#pragma mark - Regular expression Utilities -
+- (BOOL)hasValue:(NSString*)string
+{
+    if (string == nil || [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length <= 0)
+    {
+        return NO;
+    }
+    
+    return YES;
+}
+
+
+- (NSMutableArray*)componentsSeparatedByRegex:(NSString*)sourceString regex:(NSString*)pattern
+{
+    NSString *replacedString = [self replaceStringByRegex:sourceString regex:pattern withTemplate:@"<SEP>"];
+    NSMutableArray *resArray = [[replacedString componentsSeparatedByString:@"<SEP>"] mutableCopy];
+    [resArray removeObject:@""];
+    return resArray;
+}
+
+
+- (NSInteger)stringPositionByRegex:(NSString*)sourceString regex:(NSString*)pattern
+{
+    if (sourceString == nil || sourceString.length <= 0 || pattern == nil || pattern.length <= 0) {
+        return -1;
+    }
+    
+    NSError *error = nil;
+    NSRegularExpression *currentPattern = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
+    NSArray *matches = [currentPattern matchesInString:sourceString options:0 range:NSMakeRange(0, sourceString.length)];
+    
+    NSInteger foundPosition = -1;
+    
+    if (matches.count > 0)
+    {
+        NSTextCheckingResult *match = [matches objectAtIndex:0];
+        return match.range.location;
+    }
+    
+    return foundPosition;
+}
+
+
+- (NSInteger)indexOfStringByString:(NSString*)sourceString target:(NSString*)targetString
+{
+    NSRange finded = [sourceString rangeOfString:targetString];
+    if (finded.location != NSNotFound)
+    {
+        return finded.location;
+    }
+    
+    return -1;
+}
+
+
+- (NSString*)replaceFirstStringByRegex:(NSString*)sourceString regex:(NSString*)pattern withTemplate:(NSString*)templateString
+{
+    NSString *replacementResult = [sourceString copy];
+    NSError *error = nil;
+    
+    NSRegularExpression *currentPattern = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
+    NSRange replaceRange = [currentPattern rangeOfFirstMatchInString:sourceString options:0 range:NSMakeRange(0, sourceString.length)];
+    
+    if (replaceRange.location != NSNotFound)
+    {
+        replacementResult = [currentPattern stringByReplacingMatchesInString:[sourceString mutableCopy] options:0
+                                                                       range:replaceRange
+                                                                withTemplate:templateString];
+    }
+    
+    return replacementResult;
+}
+
+
+- (NSString*)replaceStringByRegex:(NSString*)sourceString regex:(NSString*)pattern withTemplate:(NSString*)templateString
+{
+    NSString *replacementResult = [sourceString copy];
+    NSError *error = nil;
+    
+    NSRegularExpression *currentPattern = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
+    NSArray *matches = [currentPattern matchesInString:sourceString options:0 range:NSMakeRange(0, sourceString.length)];
+    
+    if ([matches count] == 1)
+    {
+        NSRange replaceRange = [currentPattern rangeOfFirstMatchInString:sourceString options:0 range:NSMakeRange(0, sourceString.length)];
+        
+        if (replaceRange.location != NSNotFound)
+        {
+            replacementResult = [currentPattern stringByReplacingMatchesInString:[sourceString mutableCopy] options:0
+                                                                           range:replaceRange
+                                                                    withTemplate:templateString];
+        }
+        return replacementResult;
+    }
+    
+    if ([matches count] > 1)
+    {
+        replacementResult = [currentPattern stringByReplacingMatchesInString:[replacementResult mutableCopy] options:0
+                                                                       range:NSMakeRange(0, sourceString.length) withTemplate:templateString];
+        return replacementResult;
+    }
+    
+    return replacementResult;
+}
+
+
+- (NSTextCheckingResult*)matcheFirstByRegex:(NSString*)sourceString regex:(NSString*)pattern
+{
+    NSError *error = nil;
+    NSRegularExpression *currentPattern = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
+    NSArray *matches = [currentPattern matchesInString:sourceString options:0 range:NSMakeRange(0, sourceString.length)];
+    if ([matches count] > 0)
+        return [matches objectAtIndex:0];
+    return nil;
+}
+
+
+- (NSArray*)matchesByRegex:(NSString*)sourceString regex:(NSString*)pattern
+{
+    NSError *error = nil;
+    NSRegularExpression *currentPattern = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
+    NSArray *matches = [currentPattern matchesInString:sourceString options:0 range:NSMakeRange(0, sourceString.length)];
+    return matches;
+}
+
+
+- (NSArray*)matchedStringByRegex:(NSString*)sourceString regex:(NSString*)pattern
+{
+    NSArray *matches = [self matchesByRegex:sourceString regex:pattern];
+    NSMutableArray *matchString = [[NSMutableArray alloc] init];
+    
+    for (NSTextCheckingResult *match in matches)
+    {
+        NSString *curString = [sourceString substringWithRange:match.range];
+        [matchString addObject:curString];
+    }
+    
+    return matchString;
+}
+
+
+- (BOOL)isStartingStringByRegex:(NSString*)sourceString regex:(NSString*)pattern
+{
+    NSError *error = nil;
+    NSRegularExpression *currentPattern = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
+    NSArray *matches = [currentPattern matchesInString:sourceString options:0 range:NSMakeRange(0, sourceString.length)];
+    
+    for (NSTextCheckingResult *match in matches)
+    {
+        if (match.range.location == 0)
+        {
+            return YES;
+        }
+    }
+    
+    return NO;
+}
+
+
+- (NSString*)stringByReplacingOccurrencesString:(NSString *)sourceString withMap:(NSDictionary *)dicMap removeNonMatches:(BOOL)bRemove
+{
+    NSMutableString *targetString = [[NSMutableString alloc] initWithString:@""];
+    
+    for(NSUInteger i=0; i<sourceString.length; i++)
+    {
+        unichar oneChar = [sourceString characterAtIndex:i];
+        NSString *keyString = [NSString stringWithCharacters:&oneChar length:1];
+        NSString *mappedValue = [dicMap objectForKey:keyString];
+        if (mappedValue != nil)
+        {
+            [targetString appendString:mappedValue];
+        }
+        else
+        {
+            if (bRemove == NO)
+            {
+                [targetString appendString:keyString];
+            }
+        }
+    }
+    
+    return targetString;
+}
+
+
+- (BOOL)isNaN:(NSString*)sourceString
+{
+    NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet];
+    NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:sourceString];
+    BOOL hasNumberOnly = [alphaNums isSupersetOfSet:inStringSet];
+    
+    return !hasNumberOnly;
+}
+
+/*
+ - (NSString*)numbersOnly:(NSString*)phoneNumber
+ {
+ NSMutableString *strippedString = [NSMutableString stringWithCapacity:phoneNumber.length];
+ 
+ NSScanner *scanner = [NSScanner scannerWithString:phoneNumber];
+ NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
+ 
+ while ([scanner isAtEnd] == NO) {
+ NSString *buffer;
+ if ([scanner scanCharactersFromSet:numbers intoString:&buffer]) {
+ [strippedString appendString:buffer];
+ 
+ } else {
+ [scanner setScanLocation:([scanner scanLocation] + 1)];
+ }
+ }
+ 
+ return strippedString;
+ }
+ */
+
+
+- (NSString*)getNationalSignificantNumber:(NBPhoneNumber*)phoneNumber
+{
+    if (phoneNumber.italianLeadingZero)
+    {
+        return [NSString stringWithFormat:@"0%@", phoneNumber.nationalNumber];
+    }
+    
+    return [NSString stringWithFormat:@"%@", phoneNumber.nationalNumber];
+}
+
+
+- (NSArray*)regionCodeFromCountryCode:(NSNumber *)countryCodeNumber
+{
+    if (self.mapCN2CCode == nil || [self.mapCN2CCode count] <= 0)
+    {
+        return nil;
+    }
+    
+    id res = [self.mapCN2CCode objectForKey:[NSString stringWithFormat:@"%@", countryCodeNumber]];
+    
+    if (res && [res isKindOfClass:[NSArray class]] && [((NSArray*)res) count] > 0)
+    {
+        return res;
+    }
+    
+    return nil;
+}
+
+
+- (NSString*)countryCodeFromRegionCode:(NSString*)regionCode
+{
+    if (self.mapCCode2CN == nil || [self.mapCCode2CN count] <= 0)
+    {
+        return nil;
+    }
+    
+    id res = [self.mapCCode2CN objectForKey:regionCode];
+    
+    if (res)
+    {
+        return res;
+    }
+    
+    return nil;
+}
+
+
+#pragma mark - Initializations -
+- (id)init
+{
+    self = [super init];
+    if (self)
+    {
+        [self initRegularExpressionSet];
+        [self initNormalizationMappings];
+        
+        NSDictionary *resData = [self loadMetadata:@"NBPhoneNumberMetadata"];
+        _coreMetaData = [resData objectForKey:@"countryToMetadata"];
+        _mapCN2CCode = [resData objectForKey:@"countryCodeToRegionCodeMap"];
+        
+        [self initCC2CN];
+    }
+    
+    return self;
+}
+
+
+- (id)initForTest
+{
+    self = [super init];
+    if (self)
+    {
+        [self initRegularExpressionSet];
+        [self initNormalizationMappings];
+        
+        NSDictionary *resData = [self loadMetadata:@"NBPhoneNumberMetadataForTesting"];
+        _coreMetaData = [resData objectForKey:@"countryToMetadata"];
+        _mapCN2CCode = [resData objectForKey:@"countryCodeToRegionCodeMap"];
+        
+        [self initCC2CN];
+    }
+    
+    return self;
+}
+
+
+- (NSDictionary*)loadMetadata:(NSString*)name
+{
+    NSDictionary *unarchiveData = nil;
+    
+    @try {
+        NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:@"plist"];
+        NSData *fileData = [NSData dataWithContentsOfFile:filePath];
+        unarchiveData = [NSKeyedUnarchiver unarchiveObjectWithData:fileData];
+    }
+    @catch (NSException *exception) {
+        return unarchiveData;
+    }
+    
+    return unarchiveData;
+}
+
+/*
+ - (NSDictionary*)generateMetadata:(id)metaClass
+ {
+ NSMutableDictionary *resMedata = [[NSMutableDictionary alloc] init];
+ NSDictionary *srcMedata = nil;
+ 
+ if ([metaClass isKindOfClass:[NBPhoneNumberMetadataForTesting class]])
+ {
+ srcMedata = ((NBPhoneNumberMetadataForTesting*)metaClass).metadata;
+ }
+ else if ([metaClass isKindOfClass:[NBPhoneNumberMetadata class]])
+ {
+ srcMedata = ((NBPhoneNumberMetadata*)metaClass).metadata;
+ }
+ else
+ {
+ return resMedata;
+ }
+ 
+ NSDictionary *countryCodeToRegionCodeMap = [srcMedata objectForKey:@"countryCodeToRegionCodeMap"];
+ NSDictionary *countryToMetadata = [srcMedata objectForKey:@"countryToMetadata"];
+ NSLog(@"- countryCodeToRegionCodeMap count [%d]", [countryCodeToRegionCodeMap count]);
+ NSLog(@"- countryToMetadata          count [%d]", [countryToMetadata count]);
+ 
+ NSMutableDictionary *genetatedMetaData = [[NSMutableDictionary alloc] init];
+ 
+ for (id key in [countryToMetadata allKeys])
+ {
+ id metaData = [countryToMetadata objectForKey:key];
+ 
+ NBPhoneMetaData *newMetaData = [[NBPhoneMetaData alloc] init];
+ [newMetaData buildData:metaData];
+ 
+ [genetatedMetaData setObject:newMetaData forKey:key];
+ }
+ 
+ [resMedata setObject:countryCodeToRegionCodeMap forKey:@"countryCodeToRegionCodeMap"];
+ [resMedata setObject:genetatedMetaData forKey:@"countryToMetadata"];
+ 
+ return resMedata;
+ }
+ */
+
+
+- (void)initRegularExpressionSet
+{
+    _VALID_PUNCTUATION = @"-x‐-―−ー－-／ ­​⁠　()（）［］.\\[\\]/~⁓∼～";
+    _VALID_DIGITS_STRING = @"0-9０-９٠-٩۰-۹";
+    _PLUS_CHARS_ = @"+＋";
+    _REGION_CODE_FOR_NON_GEO_ENTITY = @"001";
+    
+    NSString *EXTN_PATTERNS_FOR_PARSING_ = @"(?:;ext=([0-9０-９٠-٩۰-۹]{1,7})|[  \\t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|ｅ?ｘｔｎ?|[,xｘX#＃~～]|int|anexo|ｉｎｔ)[:\\.．]?[  \\t,-]*([0-9０-９٠-٩۰-۹]{1,7})#?|[- ]+([0-9０-９٠-٩۰-۹]{1,5})#)$";
+    
+    NSError *error = nil;
+    
+    _PLUS_CHARS_PATTERN =
+    [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"[%@]+", _PLUS_CHARS_] options:0 error:&error];
+    
+    _LEADING_PLUS_CHARS_PATTERN_ = [NSString stringWithFormat:@"^[%@]+", _PLUS_CHARS_];
+    
+    _CAPTURING_DIGIT_PATTERN =
+    [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"([%@])", _VALID_DIGITS_STRING] options:0 error:&error];
+    
+    _VALID_START_CHAR_PATTERN_ = [NSString stringWithFormat:@"[%@%@]", _PLUS_CHARS_, _VALID_DIGITS_STRING];
+    
+    _SECOND_NUMBER_START_PATTERN_ = @"[\\\\\\/] *x";
+    
+    _VALID_ALPHA_PHONE_PATTERN_ = [NSRegularExpression regularExpressionWithPattern:VALID_ALPHA_PHONE_PATTERN_STRING options:0 error:&error];
+    
+    _UNWANTED_END_CHAR_PATTERN_ = [NSString stringWithFormat:@"[^%@%@#]+$", _VALID_DIGITS_STRING, VALID_ALPHA_];
+    
+    _EXTN_PATTERN_ = [NSString stringWithFormat:@"(?:%@)$", EXTN_PATTERNS_FOR_PARSING_];
+    
+    
+    _SEPARATOR_PATTERN_ = [NSString stringWithFormat:@"[%@]+", _VALID_PUNCTUATION];
+    
+    _VALID_PHONE_NUMBER_PATTERN_ = @"^[0-9０-９٠-٩۰-۹]{2}$|^[+＋]*(?:[-x‐-―−ー－-／  ­​⁠　()（）［］.\\[\\]/~⁓∼～*]*[0-9０-９٠-٩۰-۹]){3,}[-x‐-―−ー－-／  ­​⁠　()（）［］.\\[\\]/~⁓∼～*A-Za-z0-9０-９٠-٩۰-۹]*(?:;ext=([0-9０-９٠-٩۰-۹]{1,7})|[  \\t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|ｅ?ｘｔｎ?|[,xｘ#＃~～]|int|anexo|ｉｎｔ)[:\\.．]?[  \\t,-]*([0-9０-９٠-٩۰-۹]{1,7})#?|[- ]+([0-9０-９٠-٩۰-۹]{1,5})#)?$";
+}
+
+
+- (void)dealloc
+{
+    [self clearCC2CN];
+    [self clearCN2CC];
+}
+
+
+- (void)clearCC2CN
+{
+    if (self.mapCCode2CN != nil)
+    {
+        [self.mapCCode2CN removeAllObjects];
+        self.mapCCode2CN = nil;
+    }
+}
+
+
+- (void)clearCN2CC
+{
+    if (self.mapCN2CCode != nil)
+    {
+        [self.mapCN2CCode removeAllObjects];
+        self.mapCN2CCode = nil;
+    }
+}
+
+
+- (void)initNormalizationMappings
+{
+    _DIGIT_MAPPINGS = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                       @"0", @"0", @"1", @"1", @"2", @"2", @"3", @"3", @"4", @"4", @"5", @"5", @"6", @"6", @"7", @"7", @"8", @"8", @"9", @"9",
+                       // Fullwidth digit 0 to 9
+                       @"0", @"\uFF10", @"1", @"\uFF11", @"2", @"\uFF12", @"3", @"\uFF13", @"4", @"\uFF14", @"5", @"\uFF15", @"6", @"\uFF16", @"7", @"\uFF17", @"8", @"\uFF18", @"9", @"\uFF19",
+                       // Arabic-indic digit 0 to 9
+                       @"0", @"\u0660", @"1", @"\u0661", @"2", @"\u0662", @"3", @"\u0663", @"4", @"\u0664", @"5", @"\u0665", @"6", @"\u0666", @"7", @"\u0667", @"8", @"\u0668", @"9", @"\u0669",
+                       // Eastern-Arabic digit 0 to 9
+                       @"0", @"\u06F0", @"1", @"\u06F1",  @"2", @"\u06F2", @"3", @"\u06F3", @"4", @"\u06F4", @"5", @"\u06F5", @"6", @"\u06F6", @"7", @"\u06F7", @"8", @"\u06F8", @"9", @"\u06F9", nil];
+    
+    _DIALLABLE_CHAR_MAPPINGS_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                 @"0", @"0", @"1", @"1", @"2", @"2", @"3", @"3", @"4", @"4", @"5", @"5", @"6", @"6", @"7", @"7", @"8", @"8", @"9", @"9",
+                                 @"+", @"+", @"*", @"*", nil];
+    
+    _ALPHA_MAPPINGS_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                        @"2", @"A", @"2", @"B", @"2", @"C", @"3", @"D", @"3", @"E", @"3", @"F", @"4", @"G", @"4", @"H", @"4", @"I", @"5", @"J",
+                        @"5", @"K", @"5", @"L", @"6", @"M", @"6", @"N", @"6", @"O", @"7", @"P", @"7", @"Q", @"7", @"R", @"7", @"S", @"8", @"T",
+                        @"8", @"U", @"8", @"V", @"9", @"W", @"9", @"X", @"9", @"Y", @"9", @"Z", nil];
+    
+    _ALL_NORMALIZATION_MAPPINGS_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                    @"0", @"0", @"1", @"1", @"2", @"2", @"3", @"3", @"4", @"4", @"5", @"5", @"6", @"6", @"7", @"7", @"8", @"8", @"9", @"9",
+                                    // Fullwidth digit 0 to 9
+                                    @"0", @"\uFF10", @"1", @"\uFF11", @"2", @"\uFF12", @"3", @"\uFF13", @"4", @"\uFF14", @"5", @"\uFF15", @"6", @"\uFF16", @"7", @"\uFF17", @"8", @"\uFF18", @"9", @"\uFF19",
+                                    // Arabic-indic digit 0 to 9
+                                    @"0", @"\u0660", @"1", @"\u0661", @"2", @"\u0662", @"3", @"\u0663", @"4", @"\u0664", @"5", @"\u0665", @"6", @"\u0666", @"7", @"\u0667", @"8", @"\u0668", @"9", @"\u0669",
+                                    // Eastern-Arabic digit 0 to 9
+                                    @"0", @"\u06F0", @"1", @"\u06F1",  @"2", @"\u06F2", @"3", @"\u06F3", @"4", @"\u06F4", @"5", @"\u06F5", @"6", @"\u06F6", @"7", @"\u06F7", @"8", @"\u06F8", @"9", @"\u06F9",
+                                    @"2", @"A", @"2", @"B", @"2", @"C", @"3", @"D", @"3", @"E", @"3", @"F", @"4", @"G", @"4", @"H", @"4", @"I", @"5", @"J",
+                                    @"5", @"K", @"5", @"L", @"6", @"M", @"6", @"N", @"6", @"O", @"7", @"P", @"7", @"Q", @"7", @"R", @"7", @"S", @"8", @"T",
+                                    @"8", @"U", @"8", @"V", @"9", @"W", @"9", @"X", @"9", @"Y", @"9", @"Z", nil];
+    
+    _ALL_PLUS_NUMBER_GROUPING_SYMBOLS_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                          @"0", @"0", @"1", @"1", @"2", @"2", @"3", @"3", @"4", @"4", @"5", @"5", @"6", @"6", @"7", @"7", @"8", @"8", @"9", @"9",
+                                          @"A", @"A", @"B", @"B", @"C", @"C", @"D", @"D", @"E", @"E", @"F", @"F", @"G", @"G", @"H", @"H", @"I", @"I", @"J", @"J",
+                                          @"K", @"K", @"L", @"L", @"M", @"M", @"N", @"N", @"O", @"O", @"P", @"P", @"Q", @"Q", @"R", @"R", @"S", @"S", @"T", @"T",
+                                          @"U", @"U", @"V", @"V", @"W", @"W", @"X", @"X", @"Y", @"Y", @"Z", @"Z", @"A", @"a", @"B", @"b", @"C", @"c", @"D", @"d",
+                                          @"E", @"e", @"F", @"f", @"G", @"g", @"H", @"h", @"I", @"i", @"J", @"j", @"K", @"k", @"L", @"l", @"M", @"m", @"N", @"n",
+                                          @"O", @"o", @"P", @"p", @"Q", @"q", @"R", @"r", @"S", @"s", @"T", @"t", @"U", @"u", @"V", @"v", @"W", @"w", @"X", @"x",
+                                          @"Y", @"y", @"Z", @"z", @"-", @"-", @"-", @"\uFF0D", @"-", @"\u2010", @"-", @"\u2011", @"-", @"\u2012", @"-", @"\u2013", @"-", @"\u2014", @"-", @"\u2015",
+                                          @"-", @"\u2212", @"/", @"/", @"/", @"\uFF0F", @" ", @" ", @" ", @"\u3000", @" ", @"\u2060", @".", @".", @".", @"\uFF0E", nil];
+    
+}
+
+
+- (void)initCC2CN
+{
+    [self clearCC2CN];
+    _mapCCode2CN = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                    @"1", @"US", @"1", @"AG", @"1", @"AI", @"1", @"AS", @"1", @"BB", @"1", @"BM", @"1", @"BS", @"1", @"CA", @"1", @"DM", @"1", @"DO",
+                    @"1", @"GD", @"1", @"GU", @"1", @"JM", @"1", @"KN", @"1", @"KY", @"1", @"LC", @"1", @"MP", @"1", @"MS", @"1", @"PR", @"1", @"SX",
+                    @"1", @"TC", @"1", @"TT", @"1", @"VC", @"1", @"VG", @"1", @"VI", @"7", @"RU", @"7", @"KZ",
+                    @"20", @"EG", @"27", @"ZA",
+                    @"30", @"GR", @"31", @"NL", @"32", @"BE", @"33", @"FR", @"34", @"ES", @"36", @"HU", @"39", @"IT",
+                    @"40", @"RO", @"41", @"CH", @"43", @"AT", @"44", @"GB", @"44", @"GG", @"44", @"IM", @"44", @"JE", @"45", @"DK", @"46", @"SE", @"47", @"NO", @"47", @"SJ", @"48", @"PL", @"49", @"DE",
+                    @"51", @"PE", @"52", @"MX", @"53", @"CU", @"54", @"AR", @"55", @"BR", @"56", @"CL", @"57", @"CO", @"58", @"VE",
+                    @"60", @"MY", @"61", @"AU", @"61", @"CC", @"61", @"CX", @"62", @"ID", @"63", @"PH", @"64", @"NZ", @"65", @"SG", @"66", @"TH",
+                    @"81", @"JP", @"82", @"KR", @"84", @"VN", @"86", @"CN",
+                    @"90", @"TR", @"91", @"IN", @"92", @"PK", @"93", @"AF", @"94", @"LK", @"95", @"MM", @"98", @"IR",
+                    @"211", @"SS", @"212", @"MA", @"212", @"EH", @"213", @"DZ", @"216", @"TN", @"218", @"LY",
+                    @"220", @"GM", @"221", @"SN", @"222", @"MR", @"223", @"ML", @"224", @"GN", @"225", @"CI", @"226", @"BF", @"227", @"NE", @"228", @"TG", @"229", @"BJ",
+                    @"230", @"MU", @"231", @"LR", @"232", @"SL", @"233", @"GH", @"234", @"NG", @"235", @"TD", @"236", @"CF", @"237", @"CM", @"238", @"CV", @"239", @"ST",
+                    @"240", @"GQ", @"241", @"GA", @"242", @"CG", @"243", @"CD", @"244", @"AO", @"245", @"GW", @"246", @"IO", @"247", @"AC", @"248", @"SC", @"249", @"SD",
+                    @"250", @"RW", @"251", @"ET", @"252", @"SO", @"253", @"DJ", @"254", @"KE", @"255", @"TZ", @"256", @"UG", @"257", @"BI", @"258", @"MZ",
+                    @"260", @"ZM", @"261", @"MG", @"262", @"RE", @"262", @"YT", @"263", @"ZW", @"264", @"NA", @"265", @"MW", @"266", @"LS", @"267", @"BW", @"268", @"SZ", @"269", @"KM",
+                    @"290", @"SH", @"291", @"ER", @"297", @"AW", @"298", @"FO", @"299", @"GL",
+                    @"350", @"GI", @"351", @"PT", @"352", @"LU", @"353", @"IE", @"354", @"IS", @"355", @"AL", @"356", @"MT", @"357", @"CY", @"358", @"FI",@"358", @"AX", @"359", @"BG",
+                    @"370", @"LT", @"371", @"LV", @"372", @"EE", @"373", @"MD", @"374", @"AM", @"375", @"BY", @"376", @"AD", @"377", @"MC", @"378", @"SM", @"379", @"VA",
+                    @"380", @"UA", @"381", @"RS", @"382", @"ME", @"385", @"HR", @"386", @"SI", @"387", @"BA", @"389", @"MK",
+                    @"420", @"CZ", @"421", @"SK", @"423", @"LI",
+                    @"500", @"FK", @"501", @"BZ", @"502", @"GT", @"503", @"SV", @"504", @"HN", @"505", @"NI", @"506", @"CR", @"507", @"PA", @"508", @"PM", @"509", @"HT",
+                    @"590", @"GP", @"590", @"BL", @"590", @"MF", @"591", @"BO", @"592", @"GY", @"593", @"EC", @"594", @"GF", @"595", @"PY", @"596", @"MQ", @"597", @"SR", @"598", @"UY", @"599", @"CW", @"599", @"BQ",
+                    @"670", @"TL", @"672", @"NF", @"673", @"BN", @"674", @"NR", @"675", @"PG", @"676", @"TO", @"677", @"SB", @"678", @"VU", @"679", @"FJ",
+                    @"680", @"PW", @"681", @"WF", @"682", @"CK", @"683", @"NU", @"685", @"WS", @"686", @"KI", @"687", @"NC", @"688", @"TV", @"689", @"PF",
+                    @"690", @"TK", @"691", @"FM", @"692", @"MH",
+                    @"800", @"001", @"808", @"001",
+                    @"850", @"KP", @"852", @"HK", @"853", @"MO", @"855", @"KH", @"856", @"LA",
+                    @"870", @"001", @"878", @"001",
+                    @"880", @"BD", @"881", @"001", @"882", @"001", @"883", @"001", @"886", @"TW", @"888", @"001",
+                    @"960", @"MV", @"961", @"LB", @"962", @"JO", @"963", @"SY", @"964", @"IQ", @"965", @"KW", @"966", @"SA", @"967", @"YE", @"968", @"OM",
+                    @"970", @"PS", @"971", @"AE", @"972", @"IL", @"973", @"BH", @"974", @"QA", @"975", @"BT", @"976", @"MN", @"977", @"NP", @"979", @"001",
+                    @"992", @"TJ", @"993", @"TM", @"994", @"AZ", @"995", @"GE", @"996", @"KG", @"998", @"UZ",
+                    nil];
+}
+
+/*
+ - (void)initCN2CC
+ {
+ [self clearCN2CC];
+ _mapCN2CCode = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ @[@"US", @"AG", @"AI", @"AS", @"BB", @"BM", @"BS", @"CA", @"DM", @"DO", @"GD", @"GU", @"JM", @"KN", @"KY", @"LC", @"MP", @"MS", @"PR", @"SX", @"TC", @"TT", @"VC", @"VG", @"VI"], @"1", @[@"RU", @"KZ"], @"7",
+ @[@"EG"], @"20", @[@"ZA"], @"27",
+ @[@"GR"], @"30", @[@"NL"], @"31", @[@"BE"], @"32", @[@"FR"], @"33", @[@"ES"], @"34", @[@"HU"], @"36", @[@"IT"], @"39",
+ @[@"RO"], @"40", @[@"CH"], @"41", @[@"AT"], @"43", @[@"GB", @"GG", @"IM", @"JE"], @"44", @[@"DK"], @"45", @[@"SE"], @"46", @[@"NO", @"SJ"], @"47", @[@"PL"], @"48", @[@"DE"], @"49",
+ @[@"PE"], @"51", @[@"MX"], @"52", @[@"CU"], @"53", @[@"AR"], @"54", @[@"BR"], @"55", @[@"CL"], @"56", @[@"CO"], @"57", @[@"VE"], @"58",
+ @[@"MY"], @"60", @[@"AU", @"CC", @"CX"], @"61", @[@"ID"], @"62", @[@"PH"], @"63", @[@"NZ"], @"64", @[@"SG"], @"65", @[@"TH"], @"66",
+ @[@"JP"], @"81", @[@"KR"], @"82", @[@"VN"], @"84", @[@"CN"], @"86",
+ @[@"TR"], @"90", @[@"IN"], @"91", @[@"PK"], @"92", @[@"AF"], @"93", @[@"LK"], @"94", @[@"MM"], @"95", @[@"IR"], @"98",
+ @[@"SS"], @"211", @[@"MA", @"EH"], @"212", @[@"DZ"], @"213", @[@"TN"], @"216", @[@"LY"], @"218",
+ @[@"GM"], @"220", @[@"SN"], @"221", @[@"MR"], @"222", @[@"ML"], @"223", @[@"GN"], @"224", @[@"CI"], @"225", @[@"BF"], @"226", @[@"NE"], @"227", @[@"TG"], @"228", @[@"BJ"], @"229",
+ @[@"MU"], @"230", @[@"LR"], @"231", @[@"SL"], @"232", @[@"GH"], @"233", @[@"NG"], @"234", @[@"TD"], @"235", @[@"CF"], @"236", @[@"CM"], @"237", @[@"CV"], @"238", @[@"ST"], @"239",
+ @[@"GQ"], @"240", @[@"GA"], @"241", @[@"CG"], @"242", @[@"CD"], @"243", @[@"AO"], @"244", @[@"GW"], @"245", @[@"IO"], @"246", @[@"AC"], @"247", @[@"SC"], @"248", @[@"SD"], @"249",
+ @[@"RW"], @"250", @[@"ET"], @"251", @[@"SO"], @"252", @[@"DJ"], @"253", @[@"KE"], @"254", @[@"TZ"], @"255", @[@"UG"], @"256", @[@"BI"], @"257", @[@"MZ"], @"258",
+ @[@"ZM"], @"260", @[@"MG"], @"261", @[@"RE", @"YT"], @"262", @[@"ZW"], @"263", @[@"NA"], @"264", @[@"MW"], @"265", @[@"LS"], @"266", @[@"BW"], @"267", @[@"SZ"], @"268", @[@"KM"], @"269",
+ @[@"SH"], @"290", @[@"ER"], @"291", @[@"AW"], @"297", @[@"FO"], @"298", @[@"GL"], @"299",
+ @[@"GI"], @"350", @[@"PT"], @"351", @[@"LU"], @"352", @[@"IE"], @"353", @[@"IS"], @"354", @[@"AL"], @"355", @[@"MT"], @"356", @[@"CY"], @"357", @[@"FI", @"AX"], @"358", @[@"BG"], @"359",
+ @[@"LT"], @"370", @[@"LV"], @"371", @[@"EE"], @"372", @[@"MD"], @"373", @[@"AM"], @"374", @[@"BY"], @"375", @[@"AD"], @"376", @[@"MC"], @"377", @[@"SM"], @"378", @[@"VA"], @"379",
+ @[@"UA"], @"380", @[@"RS"], @"381", @[@"ME"], @"382", @[@"HR"], @"385", @[@"SI"], @"386", @[@"BA"], @"387", @[@"MK"], @"389",
+ @[@"CZ"], @"420", @[@"SK"], @"421", @[@"LI"], @"423",
+ @[@"FK"], @"500", @[@"BZ"], @"501", @[@"GT"], @"502", @[@"SV"], @"503", @[@"HN"], @"504", @[@"NI"], @"505", @[@"CR"], @"506", @[@"PA"], @"507", @[@"PM"], @"508", @[@"HT"], @"509",
+ @[@"GP", @"BL", @"MF"], @"590", @[@"BO"], @"591", @[@"GY"], @"592", @[@"EC"], @"593", @[@"GF"], @"594", @[@"PY"], @"595", @[@"MQ"], @"596", @[@"SR"], @"597", @[@"UY"], @"598", @[@"CW", @"BQ"], @"599",
+ @[@"TL"], @"670", @[@"NF"], @"672", @[@"BN"], @"673", @[@"NR"], @"674", @[@"PG"], @"675", @[@"TO"], @"676", @[@"SB"], @"677", @[@"VU"], @"678", @[@"FJ"], @"679",
+ @[@"PW"], @"680", @[@"WF"], @"681", @[@"CK"], @"682", @[@"NU"], @"683", @[@"WS"], @"685", @[@"KI"], @"686", @[@"NC"], @"687", @[@"TV"], @"688", @[@"PF"], @"689",
+ @[@"TK"], @"690", @[@"FM"], @"691", @[@"MH"], @"692",
+ @[@"001"], @"800", @[@"001"], @"808",
+ @[@"KP"], @"850", @[@"HK"], @"852", @[@"MO"], @"853", @[@"KH"], @"855", @[@"LA"], @"856",
+ @[@"001"], @"870", @[@"001"], @"878",
+ @[@"BD"], @"880", @[@"001"], @"881", @[@"001"], @"882", @[@"001"], @"883", @[@"TW"], @"886", @[@"001"], @"888",
+ @[@"MV"], @"960", @[@"LB"], @"961", @[@"JO"], @"962", @[@"SY"], @"963", @[@"IQ"], @"964", @[@"KW"], @"965", @[@"SA"], @"966", @[@"YE"], @"967", @[@"OM"], @"968",
+ @[@"PS"], @"970", @[@"AE"], @"971", @[@"IL"], @"972", @[@"BH"], @"973", @[@"QA"], @"974", @[@"BT"], @"975", @[@"MN"], @"976", @[@"NP"], @"977", @[@"001"], @"979",
+ @[@"TJ"], @"992", @[@"TM"], @"993", @[@"AZ"], @"994", @[@"GE"], @"995", @[@"KG"], @"996", @[@"UZ"], @"998", nil];
+ }
+ */
+
+
+#pragma mark - Metadata manager (phonenumberutil.js) functions -
+/**
+ * Attempts to extract a possible number from the string passed in. This
+ * currently strips all leading characters that cannot be used to start a phone
+ * number. Characters that can be used to start a phone number are defined in
+ * the VALID_START_CHAR_PATTERN. If none of these characters are found in the
+ * number passed in, an empty string is returned. This function also attempts to
+ * strip off any alternative extensions or endings if two or more are present,
+ * such as in the case of: (530) 583-6985 x302/x2303. The second extension here
+ * makes this actually two phone numbers, (530) 583-6985 x302 and (530) 583-6985
+ * x2303. We remove the second extension so that the first number is parsed
+ * correctly.
+ *
+ * @param {string} number the string that might contain a phone number.
+ * @return {string} the number, stripped of any non-phone-number prefix (such as
+ *     'Tel:') or an empty string if no character used to start phone numbers
+ *     (such as + or any digit) is found in the number.
+ */
+- (NSString*)extractPossibleNumber:(NSString*)number
+{
+    NSString *possibleNumber = @"";
+    NSInteger start = [self stringPositionByRegex:number regex:self.VALID_START_CHAR_PATTERN_];
+    
+    if (start >= 0)
+    {
+        possibleNumber = [number substringFromIndex:start];
+        // Remove trailing non-alpha non-numerical characters.
+        possibleNumber = [self replaceStringByRegex:possibleNumber regex:self.UNWANTED_END_CHAR_PATTERN_ withTemplate:@""];
+        
+        // Check for extra numbers at the end.
+        NSInteger secondNumberStart = [self stringPositionByRegex:number regex:self.SECOND_NUMBER_START_PATTERN_];
+        if (secondNumberStart >= 0)
+        {
+            possibleNumber = [possibleNumber substringWithRange:NSMakeRange(0, secondNumberStart - 1)];
+        }
+    }
+    else
+    {
+        possibleNumber = @"";
+    }
+    
+    return possibleNumber;
+    
+    /*
+     NSString *possibleNumber = @"";
+     NSRegularExpression *currentPattern = self.VALID_START_CHAR_PATTERN_;
+     int sourceLength = phoneNumber.length;
+     
+     NSArray *matches = [currentPattern matchesInString:phoneNumber options:0 range:NSMakeRange(0, sourceLength)];
+     if (matches && [matches count] > 0)
+     {
+     NSRange rangeOfFirstMatch = ((NSTextCheckingResult*)[matches objectAtIndex:0]).range;
+     possibleNumber = [phoneNumber substringFromIndex:rangeOfFirstMatch.location];
+     
+     // Remove trailing non-alpha non-numerical characters.
+     currentPattern = self.UNWANTED_END_CHAR_PATTERN_;
+     possibleNumber = [currentPattern stringByReplacingMatchesInString:possibleNumber options:0
+     range:NSMakeRange(0, [possibleNumber length]) withTemplate:@""];
+     // Check for extra numbers at the end.
+     currentPattern = self.SECOND_NUMBER_START_PATTERN_;
+     matches = [currentPattern matchesInString:possibleNumber options:0
+     range:NSMakeRange(0, [possibleNumber length])];
+     if (matches && [matches count] > 0)
+     {
+     NSRange rangeOfSecondMatch = ((NSTextCheckingResult*)[matches objectAtIndex:0]).range;
+     possibleNumber = [possibleNumber substringWithRange:NSMakeRange(0, rangeOfSecondMatch.location)];
+     }
+     }
+     
+     return possibleNumber;
+     */
+}
+
+
+/**
+ * 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 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.
+ *
+ * @param {string} number string to be checked for viability as a phone number.
+ * @return {boolean} NO if the number could be a phone number of some sort,
+ *     otherwise NO.
+ */
+- (BOOL)isViablePhoneNumber:(NSString*)phoneNumber
+{
+    if (phoneNumber.length < MIN_LENGTH_FOR_NSN_)
+    {
+        return NO;
+    }
+    
+    return [self matchesEntirely:self.VALID_PHONE_NUMBER_PATTERN_ string:phoneNumber];
+}
+
+
+/**
+ * Normalizes a string of characters representing a phone number. This performs
+ * the following conversions:
+ *   Punctuation is stripped.
+ *   For ALPHA/VANITY numbers:
+ *   Letters are converted to their numeric representation on a telephone
+ *       keypad. The keypad used here is the one defined in ITU Recommendation
+ *       E.161. This is only done if there are 3 or more letters in the number,
+ *       to lessen the risk that such letters are typos.
+ *   For other numbers:
+ *   Wide-ascii digits are converted to normal ASCII (European) digits.
+ *   Arabic-Indic numerals are converted to European numerals.
+ *   Spurious alpha characters are stripped.
+ *
+ * @param {string} number a string of characters representing a phone number.
+ * @return {string} the normalized string version of the phone number.
+ */
+- (NSString*)normalizePhoneNumber:(NSString*)number
+{
+    if ([self matchesEntirely:VALID_ALPHA_PHONE_PATTERN_STRING string:number])
+    {
+        return [self normalizeHelper:number normalizationReplacements:self.ALL_NORMALIZATION_MAPPINGS_ removeNonMatches:true];
+    }
+    else
+    {
+        return [self normalizeDigitsOnly:number];
+    }
+    
+    return nil;
+}
+
+
+/**
+ * Normalizes a string of characters representing a phone number. This is a
+ * wrapper for normalize(String number) but does in-place normalization of the
+ * StringBuffer provided.
+ *
+ * @param {!goog.string.StringBuffer} number a StringBuffer of characters
+ *     representing a phone number that will be normalized in place.
+ * @private
+ */
+
+- (void)normalizeSB:(NSString**)number
+{
+    if (number == NULL)
+    {
+        return;
+    }
+    
+    (*number) = [self normalizePhoneNumber:(*number)];
+}
+
+
+/**
+ * Normalizes a string of characters representing a phone number. This converts
+ * wide-ascii and arabic-indic numerals to European numerals, and strips
+ * punctuation and alpha characters.
+ *
+ * @param {string} number a string of characters representing a phone number.
+ * @return {string} the normalized string version of the phone number.
+ */
+- (NSString*)normalizeDigitsOnly:(NSString*)number
+{
+    return [self stringByReplacingOccurrencesString:number
+                                            withMap:self.DIGIT_MAPPINGS removeNonMatches:YES];
+}
+
+
+/**
+ * Converts all alpha characters in a number to their respective digits on a
+ * keypad, but retains existing formatting. Also converts wide-ascii digits to
+ * normal ascii digits, and converts Arabic-Indic numerals to European numerals.
+ *
+ * @param {string} number a string of characters representing a phone number.
+ * @return {string} the normalized string version of the phone number.
+ */
+- (NSString*)convertAlphaCharactersInNumber:(NSString*)number
+{
+    return [self stringByReplacingOccurrencesString:number
+                                            withMap:self.ALL_NORMALIZATION_MAPPINGS_ removeNonMatches:NO];
+}
+
+
+/**
+ * Gets the length of the geographical area code from the
+ * {@code national_number} field of the PhoneNumber object passed in, so that
+ * clients could use it to split a national significant number into geographical
+ * area code and subscriber number. It works in such a way that the resultant
+ * subscriber number should be diallable, at least on some devices. An example
+ * of how this could be used:
+ *
+ * <pre>
+ * var phoneUtil = getInstance();
+ * var number = phoneUtil.parse('16502530000', 'US');
+ * var nationalSignificantNumber =
+ *     phoneUtil.getNationalSignificantNumber(number);
+ * var areaCode;
+ * var subscriberNumber;
+ *
+ * var areaCodeLength = phoneUtil.getLengthOfGeographicalAreaCode(number);
+ * if (areaCodeLength > 0) {
+ *   areaCode = nationalSignificantNumber.substring(0, areaCodeLength);
+ *   subscriberNumber = nationalSignificantNumber.substring(areaCodeLength);
+ * } else {
+ *   areaCode = '';
+ *   subscriberNumber = nationalSignificantNumber;
+ * }
+ * </pre>
+ *
+ * N.B.: area code is a very ambiguous concept, so the I18N team generally
+ * recommends against using it for most purposes, but recommends using the more
+ * general {@code national_number} instead. Read the following carefully before
+ * deciding to use this method:
+ * <ul>
+ *  <li> geographical area codes change over time, and this method honors those
+ *    changes; therefore, it doesn't guarantee the stability of the result it
+ *    produces.
+ *  <li> subscriber numbers may not be diallable from all devices (notably
+ *    mobile devices, which typically requires the full national_number to be
+ *    dialled in most regions).
+ *  <li> most non-geographical numbers have no area codes, including numbers
+ *    from non-geographical entities.
+ *  <li> some geographical numbers have no area codes.
+ * </ul>
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the PhoneNumber object for
+ *     which clients want to know the length of the area code.
+ * @return {number} the length of area code of the PhoneNumber object passed in.
+ */
+- (NSUInteger)getLengthOfGeographicalAreaCode:(NBPhoneNumber*)phoneNumber error:(NSError **)error
+{
+    NSUInteger res = 0;
+    @try {
+        res = [self getLengthOfGeographicalAreaCode:phoneNumber];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+        {
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+        }
+    }
+    return res;
+}
+
+
+- (NSUInteger)getLengthOfGeographicalAreaCode:(NBPhoneNumber*)phoneNumber
+{
+    NSString *regionCode = [self getRegionCodeForNumber:phoneNumber];
+    NBPhoneMetaData *metadata = [self getMetadataForRegion:regionCode];
+    
+    if (metadata == nil)
+    {
+        return 0;
+    }
+    // If a country doesn't use a national prefix, and this number doesn't have
+    // an Italian leading zero, we assume it is a closed dialling plan with no
+    // area codes.
+    if (metadata.nationalPrefix == nil && phoneNumber.italianLeadingZero == NO)
+    {
+        return 0;
+    }
+    
+    if ([self isNumberGeographical:phoneNumber] == NO)
+    {
+        return 0;
+    }
+    
+    return [self getLengthOfNationalDestinationCode:phoneNumber];
+}
+
+
+/**
+ * Gets the length of the national destination code (NDC) from the PhoneNumber
+ * object passed in, so that clients could use it to split a national
+ * significant number into NDC and subscriber number. The NDC of a phone number
+ * is normally the first group of digit(s) right after the country calling code
+ * when the number is formatted in the international format, if there is a
+ * subscriber number part that follows. An example of how this could be used:
+ *
+ * <pre>
+ * var phoneUtil = getInstance();
+ * var number = phoneUtil.parse('18002530000', 'US');
+ * var nationalSignificantNumber =
+ *     phoneUtil.getNationalSignificantNumber(number);
+ * var nationalDestinationCode;
+ * var subscriberNumber;
+ *
+ * var nationalDestinationCodeLength =
+ *     phoneUtil.getLengthOfNationalDestinationCode(number);
+ * if (nationalDestinationCodeLength > 0) {
+ *   nationalDestinationCode =
+ *       nationalSignificantNumber.substring(0, nationalDestinationCodeLength);
+ *   subscriberNumber =
+ *       nationalSignificantNumber.substring(nationalDestinationCodeLength);
+ * } else {
+ *   nationalDestinationCode = '';
+ *   subscriberNumber = nationalSignificantNumber;
+ * }
+ * </pre>
+ *
+ * Refer to the unittests to see the difference between this function and
+ * {@link #getLengthOfGeographicalAreaCode}.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the PhoneNumber object for
+ *     which clients want to know the length of the NDC.
+ * @return {number} the length of NDC of the PhoneNumber object passed in.
+ */
+- (NSUInteger)getLengthOfNationalDestinationCode:(NBPhoneNumber*)phoneNumber error:(NSError **)error
+{
+    NSUInteger res = 0;
+    
+    @try {
+        res = [self getLengthOfNationalDestinationCode:phoneNumber];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+        {
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+        }
+    }
+    
+    return res;
+}
+
+
+- (NSUInteger)getLengthOfNationalDestinationCode:(NBPhoneNumber*)phoneNumber
+{
+    NBPhoneNumber *copiedProto = nil;
+    if ([self hasValue:phoneNumber.extension])
+    {
+        copiedProto = [phoneNumber copy];
+        copiedProto.extension = nil;
+    }
+    else
+    {
+        copiedProto = phoneNumber;
+    }
+    
+    NSString *nationalSignificantNumber = [self format:copiedProto numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
+    NSMutableArray *numberGroups = [[self componentsSeparatedByRegex:nationalSignificantNumber regex:NON_DIGITS_PATTERN_] mutableCopy];
+    
+    // The pattern will start with '+COUNTRY_CODE ' so the first group will always
+    // be the empty string (before the + symbol) and the second group will be the
+    // country calling code. The third group will be area code if it is not the
+    // last group.
+    // NOTE: On IE the first group that is supposed to be the empty string does
+    // not appear in the array of number groups... so make the result on non-IE
+    // browsers to be that of IE.
+    if ([numberGroups count] > 0 && ((NSString*)[numberGroups objectAtIndex:0]).length <= 0)
+    {
+        [numberGroups removeObjectAtIndex:0];
+    }
+    
+    if ([numberGroups count] <= 2)
+    {
+        return 0;
+    }
+    
+    NSArray *regionCodes = [self regionCodeFromCountryCode:phoneNumber.countryCode];
+    BOOL isExists = NO;
+    
+    for (NSString *regCode in regionCodes)
+    {
+        if ([regCode isEqualToString:@"AR"])
+        {
+            isExists = YES;
+            break;
+        }
+    }
+    
+    if (isExists && [self getNumberType:phoneNumber] == NBEPhoneNumberTypeMOBILE)
+    {
+        // Argentinian mobile numbers, when formatted in the international format,
+        // are in the form of +54 9 NDC XXXX.... As a result, we take the length of
+        // the third group (NDC) and add 1 for the digit 9, which also forms part of
+        // the national significant number.
+        //
+        // TODO: Investigate the possibility of better modeling the metadata to make
+        // it easier to obtain the NDC.
+        return ((NSString*)[numberGroups objectAtIndex:2]).length + 1;
+    }
+    
+    return ((NSString*)[numberGroups objectAtIndex:1]).length;
+}
+
+
+/**
+ * Normalizes a string of characters representing a phone number by replacing
+ * all characters found in the accompanying map with the values therein, and
+ * stripping all other characters if removeNonMatches is NO.
+ *
+ * @param {string} number a string of characters representing a phone number.
+ * @param {!Object.<string, string>} normalizationReplacements a mapping of
+ *     characters to what they should be replaced by in the normalized version
+ *     of the phone number.
+ * @param {boolean} removeNonMatches indicates whether characters that are not
+ *     able to be replaced should be stripped from the number. If this is NO,
+ *     they will be left unchanged in the number.
+ * @return {string} the normalized string version of the phone number.
+ * @private
+ */
+- (NSString*)normalizeHelper:(NSString*)sourceString normalizationReplacements:(NSDictionary*)normalizationReplacements
+            removeNonMatches:(BOOL)removeNonMatches
+{
+    NSMutableString *normalizedNumber = [[NSMutableString alloc] init];
+    unichar character = 0;
+    NSString *newDigit = @"";
+    NSUInteger numberLength = sourceString.length;
+    
+    for (NSUInteger i = 0; i<numberLength; ++i)
+    {
+        character = [sourceString characterAtIndex:i];
+        newDigit = [normalizationReplacements objectForKey:[[NSString stringWithFormat: @"%C", character] uppercaseString]];
+        if (newDigit != nil)
+        {
+            [normalizedNumber appendString:newDigit];
+        }
+        else if (removeNonMatches == NO)
+        {
+            [normalizedNumber appendString:[NSString stringWithFormat: @"%C", character]];
+        }
+        // If neither of the above are NO, we remove this character.
+        
+        //NSLog(@"[%@]", normalizedNumber);
+    }
+    
+    return normalizedNumber;
+}
+
+
+/**
+ * Helper function to check if the national prefix formatting rule has the first
+ * group only, i.e., does not start with the national prefix.
+ *
+ * @param {string} nationalPrefixFormattingRule The formatting rule for the
+ *     national prefix.
+ * @return {boolean} NO if the national prefix formatting rule has the first
+ *     group only.
+ */
+- (BOOL)formattingRuleHasFirstGroupOnly:(NSString*)nationalPrefixFormattingRule
+{
+    BOOL hasFound = NO;
+    if ([self stringPositionByRegex:nationalPrefixFormattingRule regex:FIRST_GROUP_ONLY_PREFIX_PATTERN_] >= 0)
+    {
+        hasFound = YES;
+    }
+    
+    return (([nationalPrefixFormattingRule length] == 0) || hasFound);
+}
+
+
+/**
+ * Tests whether a phone number has a geographical association. It checks if
+ * the number is associated to a certain region in the country where it belongs
+ * to. Note that this doesn't verify if the number is actually in use.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} phoneNumber The phone number to test.
+ * @return {boolean} NO if the phone number has a geographical association.
+ * @private
+ */
+- (BOOL)isNumberGeographical:(NBPhoneNumber*)phoneNumber
+{
+    NBEPhoneNumberType numberType = [self getNumberType:phoneNumber];
+    // TODO: Include mobile phone numbers from countries like Indonesia, which
+    // has some mobile numbers that are geographical.
+    return numberType == NBEPhoneNumberTypeFIXED_LINE || numberType == NBEPhoneNumberTypeFIXED_LINE_OR_MOBILE;
+}
+
+
+/**
+ * Helper function to check region code is not unknown or nil.
+ *
+ * @param {?string} regionCode the ISO 3166-1 two-letter region code.
+ * @return {boolean} NO if region code is valid.
+ * @private
+ */
+- (BOOL)isValidRegionCode:(NSString*)regionCode
+{
+    // In Java we check whether the regionCode is contained in supportedRegions
+    // that is built out of all the values of countryCallingCodeToRegionCodeMap
+    // (countryCodeToRegionCodeMap in JS) minus REGION_CODE_FOR_NON_GEO_ENTITY.
+    // In JS we check whether the regionCode is contained in the keys of
+    // countryToMetadata but since for non-geographical country calling codes
+    // (e.g. +800) we use the country calling codes instead of the region code as
+    // key in the map we have to make sure regionCode is not a number to prevent
+    // returning NO for non-geographical country calling codes.
+    return [self hasValue:regionCode] && [self isNaN:regionCode] && [self getMetadataForRegion:regionCode.uppercaseString] != nil;
+}
+
+
+/**
+ * Helper function to check the country calling code is valid.
+ *
+ * @param {number} countryCallingCode the country calling code.
+ * @return {boolean} NO if country calling code code is valid.
+ * @private
+ */
+- (BOOL)hasValidCountryCallingCode:(NSNumber *)countryCallingCode
+{
+    id res = [self regionCodeFromCountryCode:countryCallingCode];
+    if (res != nil)
+    {
+        return YES;
+    }
+    
+    return NO;
+}
+
+
+/**
+ * Formats a phone number in the specified format using default rules. Note that
+ * this does not promise to produce a phone number that the user can dial from
+ * where they are - although we do format in either 'national' or
+ * 'international' format depending on what the client asks for, we do not
+ * currently support a more abbreviated format, such as for users in the same
+ * 'area' who could potentially dial the number without area code. Note that if
+ * the phone number has a country calling code of 0 or an otherwise invalid
+ * country calling code, we cannot work out which formatting rules to apply so
+ * we return the national significant number with no formatting applied.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number to be
+ *     formatted.
+ * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the
+ *     phone number should be formatted into.
+ * @return {string} the formatted phone number.
+ */
+- (NSString*)format:(NBPhoneNumber*)phoneNumber numberFormat:(NBEPhoneNumberFormat)numberFormat error:(NSError**)error;
+{
+    NSString *res = nil;
+    @try {
+        res = [self format:phoneNumber numberFormat:numberFormat];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+- (NSString*)format:(NBPhoneNumber*)phoneNumber numberFormat:(NBEPhoneNumberFormat)numberFormat
+{
+    if ([phoneNumber.nationalNumber isEqualToNumber:@0] && [self hasValue:phoneNumber.rawInput])
+    {
+        // Unparseable numbers that kept their raw input just use that.
+        // This is the only case where a number can be formatted as E164 without a
+        // leading '+' symbol (but the original number wasn't parseable anyway).
+        // TODO: Consider removing the 'if' above so that unparseable strings
+        // without raw input format to the empty string instead of "+00"
+        /** @type {string} */
+        NSString *rawInput = phoneNumber.rawInput;
+        if ([self hasValue:rawInput]) {
+            return rawInput;
+        }
+    }
+    
+    NSNumber *countryCallingCode = phoneNumber.countryCode;
+    NSString *nationalSignificantNumber = [self getNationalSignificantNumber:phoneNumber];
+    
+    if (numberFormat == NBEPhoneNumberFormatE164)
+    {
+        // Early exit for E164 case (even if the country calling code is invalid)
+        // since no formatting of the national number needs to be applied.
+        // Extensions are not formatted.
+        return [self prefixNumberWithCountryCallingCode:countryCallingCode phoneNumberFormat:NBEPhoneNumberFormatE164
+                                formattedNationalNumber:nationalSignificantNumber formattedExtension:@""];
+    }
+    
+    if ([self hasValidCountryCallingCode:countryCallingCode] == NO)
+    {
+        return nationalSignificantNumber;
+    }
+    
+    // Note getRegionCodeForCountryCode() is used because formatting information
+    // for regions which share a country calling code is contained by only one
+    // region for performance reasons. For example, for NANPA regions it will be
+    // contained in the metadata for US.
+    NSArray *regionCodeArray = [self regionCodeFromCountryCode:countryCallingCode];
+    NSString *regionCode = [regionCodeArray objectAtIndex:0];
+    
+    // Metadata cannot be nil because the country calling code is valid (which
+    // means that the region code cannot be ZZ and must be one of our supported
+    // region codes).
+    NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:regionCode];
+    NSString *formattedExtension = [self maybeGetFormattedExtension:phoneNumber metadata:metadata numberFormat:numberFormat];
+    NSString *formattedNationalNumber = [self formatNsn:nationalSignificantNumber metadata:metadata phoneNumberFormat:numberFormat carrierCode:nil];
+    
+    return [self prefixNumberWithCountryCallingCode:countryCallingCode phoneNumberFormat:numberFormat
+                            formattedNationalNumber:formattedNationalNumber formattedExtension:formattedExtension];
+}
+
+
+/**
+ * Formats a phone number in the specified format using client-defined
+ * formatting rules. Note that if the phone number has a country calling code of
+ * zero or an otherwise invalid country calling code, we cannot work out things
+ * like whether there should be a national prefix applied, or how to format
+ * extensions, so we return the national significant number with no formatting
+ * applied.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone  number to be
+ *     formatted.
+ * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the
+ *     phone number should be formatted into.
+ * @param {Array.<i18n.phonenumbers.NumberFormat>} userDefinedFormats formatting
+ *     rules specified by clients.
+ * @return {string} the formatted phone number.
+ */
+- (NSString*)formatByPattern:(NBPhoneNumber*)number numberFormat:(NBEPhoneNumberFormat)numberFormat userDefinedFormats:(NSArray*)userDefinedFormats error:(NSError**)error
+{
+    NSString *res = nil;
+    @try {
+        res = [self formatByPattern:number numberFormat:numberFormat userDefinedFormats:userDefinedFormats];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (NSString*)formatByPattern:(NBPhoneNumber*)number numberFormat:(NBEPhoneNumberFormat)numberFormat userDefinedFormats:(NSArray*)userDefinedFormats
+{
+    NSNumber *countryCallingCode = number.countryCode;
+    NSString *nationalSignificantNumber = [self getNationalSignificantNumber:number];
+    
+    if ([self hasValidCountryCallingCode:countryCallingCode] == NO)
+    {
+        return nationalSignificantNumber;
+    }
+    
+    // Note getRegionCodeForCountryCode() is used because formatting information
+    // for regions which share a country calling code is contained by only one
+    // region for performance reasons. For example, for NANPA regions it will be
+    // contained in the metadata for US.
+    NSArray *regionCodes = [self regionCodeFromCountryCode:countryCallingCode];
+    NSString *regionCode = nil;
+    if (regionCodes != nil && regionCodes.count > 0)
+    {
+        regionCode = [regionCodes objectAtIndex:0];
+    }
+    
+    // Metadata cannot be nil because the country calling code is valid
+    /** @type {i18n.phonenumbers.PhoneMetadata} */
+    NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:regionCode];
+    
+    NSString *formattedNumber = @"";
+    NBNumberFormat *formattingPattern = [self chooseFormattingPatternForNumber:userDefinedFormats nationalNumber:nationalSignificantNumber];
+    if (formattingPattern == nil)
+    {
+        // If no pattern above is matched, we format the number as a whole.
+        formattedNumber = nationalSignificantNumber;
+    }
+    else
+    {
+        // Before we do a replacement of the national prefix pattern $NP with the
+        // national prefix, we need to copy the rule so that subsequent replacements
+        // for different numbers have the appropriate national prefix.
+        NBNumberFormat *numFormatCopy = [formattingPattern copy];
+        NSString *nationalPrefixFormattingRule = formattingPattern.nationalPrefixFormattingRule;
+        
+        if (nationalPrefixFormattingRule.length > 0)
+        {
+            NSString *nationalPrefix = metadata.nationalPrefix;
+            if (nationalPrefix.length > 0)
+            {
+                // Replace $NP with national prefix and $FG with the first group ($1).
+                nationalPrefixFormattingRule = [self replaceStringByRegex:nationalPrefixFormattingRule regex:NP_PATTERN_ withTemplate:nationalPrefix];
+                nationalPrefixFormattingRule = [self replaceStringByRegex:nationalPrefixFormattingRule regex:FG_PATTERN_ withTemplate:@"\\$1"];
+                numFormatCopy.nationalPrefixFormattingRule = nationalPrefixFormattingRule;
+            }
+            else
+            {
+                // We don't want to have a rule for how to format the national prefix if
+                // there isn't one.
+                numFormatCopy.nationalPrefixFormattingRule = @"";
+            }
+        }
+        
+        formattedNumber = [self formatNsnUsingPattern:nationalSignificantNumber
+                                    formattingPattern:numFormatCopy numberFormat:numberFormat carrierCode:nil];
+    }
+    
+    NSString *formattedExtension = [self maybeGetFormattedExtension:number metadata:metadata numberFormat:numberFormat];
+    
+    //NSLog(@"!@#  prefixNumberWithCountryCallingCode called [%@]", formattedExtension);
+    return [self prefixNumberWithCountryCallingCode:countryCallingCode
+                                  phoneNumberFormat:numberFormat
+                            formattedNationalNumber:formattedNumber
+                                 formattedExtension:formattedExtension];
+}
+
+
+/**
+ * Formats a phone number in national format for dialing using the carrier as
+ * specified in the {@code carrierCode}. The {@code carrierCode} will always be
+ * used regardless of whether the phone number already has a preferred domestic
+ * carrier code stored. If {@code carrierCode} contains an empty string, returns
+ * the number in national format without any carrier code.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number to be
+ *     formatted.
+ * @param {string} carrierCode the carrier selection code to be used.
+ * @return {string} the formatted phone number in national format for dialing
+ *     using the carrier as specified in the {@code carrierCode}.
+ */
+- (NSString*)formatNationalNumberWithCarrierCode:(NBPhoneNumber*)number carrierCode:(NSString*)carrierCode error:(NSError **)error
+{
+    NSString *res = nil;
+    @try {
+        res = [self formatNationalNumberWithCarrierCode:number carrierCode:carrierCode];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (NSString*)formatNationalNumberWithCarrierCode:(NBPhoneNumber*)number carrierCode:(NSString*)carrierCode
+{
+    NSNumber *countryCallingCode = number.countryCode;
+    NSString *nationalSignificantNumber = [self getNationalSignificantNumber:number];
+    if ([self hasValidCountryCallingCode:countryCallingCode] == NO)
+    {
+        return nationalSignificantNumber;
+    }
+    
+    // Note getRegionCodeForCountryCode() is used because formatting information
+    // for regions which share a country calling code is contained by only one
+    // region for performance reasons. For example, for NANPA regions it will be
+    // contained in the metadata for US.
+    NSString *regionCode = [self getRegionCodeForCountryCode:countryCallingCode];
+    // Metadata cannot be nil because the country calling code is valid.
+    NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:regionCode];
+    NSString *formattedExtension = [self maybeGetFormattedExtension:number metadata:metadata numberFormat:NBEPhoneNumberFormatNATIONAL];
+    NSString *formattedNationalNumber = [self formatNsn:nationalSignificantNumber metadata:metadata phoneNumberFormat:NBEPhoneNumberFormatNATIONAL carrierCode:carrierCode];
+    return [self prefixNumberWithCountryCallingCode:countryCallingCode phoneNumberFormat:NBEPhoneNumberFormatNATIONAL formattedNationalNumber:formattedNationalNumber formattedExtension:formattedExtension];
+}
+
+
+/**
+ * @param {number} countryCallingCode
+ * @param {?string} regionCode
+ * @return {i18n.phonenumbers.PhoneMetadata}
+ * @private
+ */
+- (NBPhoneMetaData*)getMetadataForRegionOrCallingCode:(NSNumber*)countryCallingCode regionCode:(NSString*)regionCode
+{
+    return [_REGION_CODE_FOR_NON_GEO_ENTITY isEqualToString:regionCode] ?
+    [self getMetadataForNonGeographicalRegion:countryCallingCode] : [self getMetadataForRegion:regionCode];
+}
+
+
+/**
+ * Formats a phone number in national format for dialing using the carrier as
+ * specified in the preferred_domestic_carrier_code field of the PhoneNumber
+ * object passed in. If that is missing, use the {@code fallbackCarrierCode}
+ * passed in instead. If there is no {@code preferred_domestic_carrier_code},
+ * and the {@code fallbackCarrierCode} contains an empty string, return the
+ * number in national format without any carrier code.
+ *
+ * <p>Use {@link #formatNationalNumberWithCarrierCode} instead if the carrier
+ * code passed in should take precedence over the number's
+ * {@code preferred_domestic_carrier_code} when formatting.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number to be
+ *     formatted.
+ * @param {string} fallbackCarrierCode the carrier selection code to be used, if
+ *     none is found in the phone number itself.
+ * @return {string} the formatted phone number in national format for dialing
+ *     using the number's preferred_domestic_carrier_code, or the
+ *     {@code fallbackCarrierCode} passed in if none is found.
+ */
+- (NSString*)formatNationalNumberWithPreferredCarrierCode:(NBPhoneNumber*)number
+                                      fallbackCarrierCode:(NSString*)fallbackCarrierCode error:(NSError **)error
+{
+    NSString *res = nil;
+    @try {
+        res = [self formatNationalNumberWithCarrierCode:number carrierCode:fallbackCarrierCode];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    
+    return res;
+}
+
+
+- (NSString*)formatNationalNumberWithPreferredCarrierCode:(NBPhoneNumber*)number fallbackCarrierCode:(NSString*)fallbackCarrierCode
+{
+    NSString *domesticCarrierCode = number.preferredDomesticCarrierCode != nil ? number.preferredDomesticCarrierCode : fallbackCarrierCode;
+    return [self formatNationalNumberWithCarrierCode:number carrierCode:domesticCarrierCode];
+}
+
+
+/**
+ * Returns a number formatted in such a way that it can be dialed from a mobile
+ * phone in a specific region. If the number cannot be reached from the region
+ * (e.g. some countries block toll-free numbers from being called outside of the
+ * country), the method returns an empty string.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number to be
+ *     formatted.
+ * @param {string} regionCallingFrom the region where the call is being placed.
+ * @param {boolean} withFormatting whether the number should be returned with
+ *     formatting symbols, such as spaces and dashes.
+ * @return {string} the formatted phone number.
+ */
+- (NSString*)formatNumberForMobileDialing:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom withFormatting:(BOOL)withFormatting error:(NSError**)error
+{
+    NSString *res = nil;
+    @try {
+        res = [self formatNumberForMobileDialing:number regionCallingFrom:regionCallingFrom withFormatting:withFormatting];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (NSString*)formatNumberForMobileDialing:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom withFormatting:(BOOL)withFormatting
+{
+    NSNumber *countryCallingCode = number.countryCode;
+    if ([self hasValidCountryCallingCode:countryCallingCode] == NO)
+    {
+        return [self hasValue:number.rawInput] ? number.rawInput : @"";
+    }
+    
+    NSString *formattedNumber = @"";
+    // Clear the extension, as that part cannot normally be dialed together with
+    // the main number.
+    NBPhoneNumber *numberNoExt = [number copy];
+    numberNoExt.extension = @"";
+    
+    NSString *regionCode = [self getRegionCodeForCountryCode:countryCallingCode];
+    if ([regionCallingFrom isEqualToString:regionCode])
+    {
+        NBEPhoneNumberType numberType = [self getNumberType:numberNoExt];
+        BOOL isFixedLineOrMobile = (numberType == NBEPhoneNumberTypeFIXED_LINE) || (numberType == NBEPhoneNumberTypeMOBILE) || (numberType == NBEPhoneNumberTypeFIXED_LINE_OR_MOBILE);
+        // Carrier codes may be needed in some countries. We handle this here.
+        if ([regionCode isEqualToString:@"CO"] && numberType == NBEPhoneNumberTypeFIXED_LINE)
+        {
+            formattedNumber = [self formatNationalNumberWithCarrierCode:numberNoExt
+                                                            carrierCode:COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX_];
+        }
+        else if ([regionCode isEqualToString:@"BR"] && isFixedLineOrMobile)
+        {
+            formattedNumber = [self hasValue:numberNoExt.preferredDomesticCarrierCode] ?
+            [self formatNationalNumberWithPreferredCarrierCode:numberNoExt fallbackCarrierCode:@""] : @"";
+            // Brazilian fixed line and mobile numbers need to be dialed with a
+            // carrier code when called within Brazil. Without that, most of the
+            // carriers won't connect the call. Because of that, we return an
+            // empty string here.
+        }
+        else
+        {
+            // For NANPA countries, non-geographical countries, and Mexican fixed
+            // line and mobile numbers, we output international format for numbersi
+            // that can be dialed internationally as that always works.
+            if (([countryCallingCode isEqualToNumber:@(NANPA_COUNTRY_CODE_)] ||
+                 [regionCode isEqualToString:_REGION_CODE_FOR_NON_GEO_ENTITY] ||
+                 // MX fixed line and mobile numbers should always be formatted in
+                 // international format, even when dialed within MX. For national
+                 // format to work, a carrier code needs to be used, and the correct
+                 // carrier code depends on if the caller and callee are from the
+                 // same local area. It is trickier to get that to work correctly than
+                 // using international format, which is tested to work fine on all
+                 // carriers.
+                 ([regionCode isEqualToString:@"MX"] && isFixedLineOrMobile)) && [self canBeInternationallyDialled:numberNoExt])
+            {
+                formattedNumber = [self format:numberNoExt numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
+            }
+            else
+            {
+                formattedNumber = [self format:numberNoExt numberFormat:NBEPhoneNumberFormatNATIONAL];
+            }
+        }
+    }
+    else if ([self canBeInternationallyDialled:numberNoExt])
+    {
+        return withFormatting ? [self format:numberNoExt numberFormat:NBEPhoneNumberFormatINTERNATIONAL] :
+        [self format:numberNoExt numberFormat:NBEPhoneNumberFormatE164];
+    }
+    
+    return withFormatting ?
+    formattedNumber : [self normalizeHelper:formattedNumber normalizationReplacements:self.DIALLABLE_CHAR_MAPPINGS_ removeNonMatches:YES];
+}
+
+
+/**
+ * Formats a phone number for out-of-country dialing purposes. If no
+ * regionCallingFrom is supplied, we format the number in its INTERNATIONAL
+ * format. If the country calling code is the same as that of the region where
+ * the number is from, then NATIONAL formatting will be applied.
+ *
+ * <p>If the number itself has a country calling code of zero or an otherwise
+ * invalid country calling code, then we return the number with no formatting
+ * applied.
+ *
+ * <p>Note this function takes care of the case for calling inside of NANPA and
+ * between Russia and Kazakhstan (who share the same country calling code). In
+ * those cases, no international prefix is used. For regions which have multiple
+ * international prefixes, the number in its INTERNATIONAL format will be
+ * returned instead.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number to be
+ *     formatted.
+ * @param {string} regionCallingFrom the region where the call is being placed.
+ * @return {string} the formatted phone number.
+ */
+- (NSString*)formatOutOfCountryCallingNumber:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom error:(NSError**)error
+{
+    NSString *res = nil;
+    @try {
+        res = [self formatOutOfCountryCallingNumber:number regionCallingFrom:regionCallingFrom];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    
+    return res;
+}
+
+- (NSString*)formatOutOfCountryCallingNumber:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom
+{
+    if ([self isValidRegionCode:regionCallingFrom] == NO)
+    {
+        return [self format:number numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
+    }
+    
+    NSNumber *countryCallingCode = number.countryCode;
+    NSString *nationalSignificantNumber = [self getNationalSignificantNumber:number];
+    if ([self hasValidCountryCallingCode:countryCallingCode] == NO)
+    {
+        return nationalSignificantNumber;
+    }
+    
+    if ([countryCallingCode isEqualToNumber: @(NANPA_COUNTRY_CODE_)])
+    {
+        if ([self isNANPACountry:regionCallingFrom])
+        {
+            // For NANPA regions, return the national format for these regions but
+            // prefix it with the country calling code.
+            return [NSString stringWithFormat:@"%@ %@", countryCallingCode, [self format:number numberFormat:NBEPhoneNumberFormatNATIONAL]];
+        }
+    }
+    else if ([countryCallingCode isEqualToNumber: [self getCountryCodeForValidRegion:regionCallingFrom]])
+    {
+        // If regions share a country calling code, the country calling code need
+        // not be dialled. This also applies when dialling within a region, so this
+        // if clause covers both these cases. Technically this is the case for
+        // dialling from La Reunion to other overseas departments of France (French
+        // Guiana, Martinique, Guadeloupe), but not vice versa - so we don't cover
+        // this edge case for now and for those cases return the version including
+        // country calling code. Details here:
+        // http://www.petitfute.com/voyage/225-info-pratiques-reunion
+        return [self format:number numberFormat:NBEPhoneNumberFormatNATIONAL];
+    }
+    // Metadata cannot be nil because we checked 'isValidRegionCode()' above.
+    NBPhoneMetaData *metadataForRegionCallingFrom = [self getMetadataForRegion:regionCallingFrom];
+    NSString *internationalPrefix = metadataForRegionCallingFrom.internationalPrefix;
+    
+    // For regions that have multiple international prefixes, the international
+    // format of the number is returned, unless there is a preferred international
+    // prefix.
+    NSString *internationalPrefixForFormatting = @"";
+    if ([self matchesEntirely:UNIQUE_INTERNATIONAL_PREFIX_ string:internationalPrefix])
+    {
+        internationalPrefixForFormatting = internationalPrefix;
+    }
+    else if ([self hasValue:metadataForRegionCallingFrom.preferredInternationalPrefix])
+    {
+        internationalPrefixForFormatting = metadataForRegionCallingFrom.preferredInternationalPrefix;
+    }
+    
+    NSString *regionCode = [self getRegionCodeForCountryCode:countryCallingCode];
+    // Metadata cannot be nil because the country calling code is valid.
+    NBPhoneMetaData *metadataForRegion = [self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:regionCode];
+    NSString *formattedNationalNumber = [self formatNsn:nationalSignificantNumber metadata:metadataForRegion
+                                      phoneNumberFormat:NBEPhoneNumberFormatINTERNATIONAL carrierCode:nil];
+    NSString *formattedExtension = [self maybeGetFormattedExtension:number metadata:metadataForRegion numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
+    
+    NSString *hasLenth = [NSString stringWithFormat:@"%@ %@ %@%@", internationalPrefixForFormatting, countryCallingCode, formattedNationalNumber, formattedExtension];
+    NSString *hasNotLength = [self prefixNumberWithCountryCallingCode:countryCallingCode phoneNumberFormat:NBEPhoneNumberFormatINTERNATIONAL
+                                              formattedNationalNumber:formattedNationalNumber formattedExtension:formattedExtension];
+    
+    return internationalPrefixForFormatting.length > 0 ? hasLenth:hasNotLength;
+}
+
+
+/**
+ * A helper function that is used by format and formatByPattern.
+ *
+ * @param {number} countryCallingCode the country calling code.
+ * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the
+ *     phone number should be formatted into.
+ * @param {string} formattedNationalNumber
+ * @param {string} formattedExtension
+ * @return {string} the formatted phone number.
+ * @private
+ */
+- (NSString*)prefixNumberWithCountryCallingCode:(NSNumber*)countryCallingCode phoneNumberFormat:(NBEPhoneNumberFormat)numberFormat
+                        formattedNationalNumber:(NSString*)formattedNationalNumber
+                             formattedExtension:(NSString*)formattedExtension
+{
+    switch (numberFormat)
+    {
+        case NBEPhoneNumberFormatE164:
+            return [NSString stringWithFormat:@"+%@%@%@", countryCallingCode, formattedNationalNumber, formattedExtension];
+        case NBEPhoneNumberFormatINTERNATIONAL:
+            return [NSString stringWithFormat:@"+%@ %@%@", countryCallingCode, formattedNationalNumber, formattedExtension];
+        case NBEPhoneNumberFormatRFC3966:
+            return [NSString stringWithFormat:@"%@+%@-%@%@", RFC3966_PREFIX_, countryCallingCode, formattedNationalNumber, formattedExtension];
+        case NBEPhoneNumberFormatNATIONAL:
+        default:
+            return [NSString stringWithFormat:@"%@%@", formattedNationalNumber, formattedExtension];
+    }
+}
+
+
+/**
+ * Formats a phone number using the original phone number format that the number
+ * is parsed from. The original format is embedded in the country_code_source
+ * field of the PhoneNumber object passed in. If such information is missing,
+ * the number will be formatted into the NATIONAL format by default. When the
+ * number contains a leading zero and this is unexpected for this country, or we
+ * don't have a formatting pattern for the number, the method returns the raw
+ * input when it is available.
+ *
+ * Note this method guarantees no digit will be inserted, removed or modified as
+ * a result of formatting.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number that needs to
+ *     be formatted in its original number format.
+ * @param {string} regionCallingFrom the region whose IDD needs to be prefixed
+ *     if the original number has one.
+ * @return {string} the formatted phone number in its original number format.
+ */
+- (NSString*)formatInOriginalFormat:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom error:(NSError **)error
+{
+    NSString *res = nil;
+    @try {
+        res = [self formatInOriginalFormat:number regionCallingFrom:regionCallingFrom];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    
+    return res;
+}
+
+
+- (NSString*)formatInOriginalFormat:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom
+{
+    if ([self hasValue:number.rawInput] && ([self hasUnexpectedItalianLeadingZero:number] || [self hasFormattingPatternForNumber:number] == NO))
+    {
+        // We check if we have the formatting pattern because without that, we might
+        // format the number as a group without national prefix.
+        return number.rawInput;
+    }
+    
+    if (number.countryCodeSource == nil)
+    {
+        return [self format:number numberFormat:NBEPhoneNumberFormatNATIONAL];
+    }
+    
+    NSString *formattedNumber = @"";
+    
+    switch ([number.countryCodeSource intValue])
+    {
+        case NBECountryCodeSourceFROM_NUMBER_WITH_PLUS_SIGN:
+            formattedNumber = [self format:number numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
+            break;
+        case NBECountryCodeSourceFROM_NUMBER_WITH_IDD:
+            formattedNumber = [self formatOutOfCountryCallingNumber:number regionCallingFrom:regionCallingFrom];
+            break;
+        case NBECountryCodeSourceFROM_NUMBER_WITHOUT_PLUS_SIGN:
+            formattedNumber = [[self format:number numberFormat:NBEPhoneNumberFormatINTERNATIONAL] substringFromIndex:1];
+            break;
+        case NBECountryCodeSourceFROM_DEFAULT_COUNTRY:
+            // Fall-through to default case.
+        default:
+        {
+            NSString *regionCode = [self getRegionCodeForCountryCode:number.countryCode];
+            // We strip non-digits from the NDD here, and from the raw input later,
+            // so that we can compare them easily.
+            NSString *nationalPrefix = [self getNddPrefixForRegion:regionCode stripNonDigits:YES];
+            NSString *nationalFormat = [self format:number numberFormat:NBEPhoneNumberFormatNATIONAL];
+            if (nationalPrefix == nil || nationalPrefix.length == 0)
+            {
+                // If the region doesn't have a national prefix at all, we can safely
+                // return the national format without worrying about a national prefix
+                // being added.
+                formattedNumber = nationalFormat;
+                break;
+            }
+            // Otherwise, we check if the original number was entered with a national
+            // prefix.
+            if ([self rawInputContainsNationalPrefix:number.rawInput nationalPrefix:nationalPrefix regionCode:regionCode])
+            {
+                // If so, we can safely return the national format.
+                formattedNumber = nationalFormat;
+                break;
+            }
+            // Metadata cannot be nil here because getNddPrefixForRegion() (above)
+            // returns nil if there is no metadata for the region.
+            NBPhoneMetaData *metadata = [self getMetadataForRegion:regionCode];
+            NSString *nationalNumber = [self getNationalSignificantNumber:number];
+            NBNumberFormat *formatRule = [self chooseFormattingPatternForNumber:metadata.numberFormats nationalNumber:nationalNumber];
+            // The format rule could still be nil here if the national number was 0
+            // and there was no raw input (this should not be possible for numbers
+            // generated by the phonenumber library as they would also not have a
+            // country calling code and we would have exited earlier).
+            if (formatRule == nil)
+            {
+                formattedNumber = nationalFormat;
+                break;
+            }
+            // When the format we apply to this number doesn't contain national
+            // prefix, we can just return the national format.
+            // TODO: Refactor the code below with the code in
+            // isNationalPrefixPresentIfRequired.
+            NSString *candidateNationalPrefixRule = formatRule.nationalPrefixFormattingRule;
+            // We assume that the first-group symbol will never be _before_ the
+            // national prefix.
+            NSRange firstGroupRange = [candidateNationalPrefixRule rangeOfString:@"$1"];
+            if (firstGroupRange.location == NSNotFound)
+            {
+                formattedNumber = nationalFormat;
+                break;
+            }
+            
+            if (firstGroupRange.location <= 0)
+            {
+                formattedNumber = nationalFormat;
+                break;
+            }
+            candidateNationalPrefixRule = [candidateNationalPrefixRule substringWithRange:NSMakeRange(0, firstGroupRange.location)];
+            candidateNationalPrefixRule = [self normalizeDigitsOnly:candidateNationalPrefixRule];
+            if (candidateNationalPrefixRule.length == 0)
+            {
+                // National prefix not used when formatting this number.
+                formattedNumber = nationalFormat;
+                break;
+            }
+            // Otherwise, we need to remove the national prefix from our output.
+            NBNumberFormat *numFormatCopy = [formatRule copy];
+            numFormatCopy.nationalPrefixFormattingRule = nil;
+            formattedNumber = [self formatByPattern:number numberFormat:NBEPhoneNumberFormatNATIONAL userDefinedFormats:@[numFormatCopy]];
+            break;
+        }
+    }
+    
+    NSString *rawInput = number.rawInput;
+    // 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.
+    if (formattedNumber != nil && rawInput.length > 0)
+    {
+        NSString *normalizedFormattedNumber = [self normalizeHelper:formattedNumber normalizationReplacements:_DIALLABLE_CHAR_MAPPINGS_ removeNonMatches:YES];
+        /** @type {string} */
+        NSString *normalizedRawInput =[self normalizeHelper:rawInput normalizationReplacements:_DIALLABLE_CHAR_MAPPINGS_ removeNonMatches:YES];
+        
+        if ([normalizedFormattedNumber isEqualToString:normalizedRawInput] == NO)
+        {
+            formattedNumber = rawInput;
+        }
+    }
+    return formattedNumber;
+}
+
+
+/**
+ * Check if rawInput, which is assumed to be in the national format, has a
+ * national prefix. The national prefix is assumed to be in digits-only form.
+ * @param {string} rawInput
+ * @param {string} nationalPrefix
+ * @param {string} regionCode
+ * @return {boolean}
+ * @private
+ */
+- (BOOL)rawInputContainsNationalPrefix:(NSString*)rawInput nationalPrefix:(NSString*)nationalPrefix regionCode:(NSString*)regionCode
+{
+    NSString *normalizedNationalNumber = [self normalizeDigitsOnly:rawInput];
+    if ([self isStartingStringByRegex:normalizedNationalNumber regex:nationalPrefix])
+    {
+        @try {
+            // Some Japanese numbers (e.g. 00777123) might be mistaken to contain the
+            // national prefix when written without it (e.g. 0777123) if we just do
+            // prefix matching. To tackle that, we check the validity of the number if
+            // the assumed national prefix is removed (777123 won't be valid in
+            // Japan).
+            NSString *subString = [normalizedNationalNumber substringFromIndex:nationalPrefix.length];
+            return [self isValidNumber:[self parse:subString defaultRegion:regionCode]];
+        }
+        @catch (NSException *ex) {
+            return NO;
+        }
+    }
+    return NO;
+}
+
+
+/**
+ * Returns NO if a number is from a region whose national significant number
+ * couldn't contain a leading zero, but has the italian_leading_zero field set
+ * to NO.
+ * @param {i18n.phonenumbers.PhoneNumber} number
+ * @return {boolean}
+ * @private
+ */
+- (BOOL)hasUnexpectedItalianLeadingZero:(NBPhoneNumber*)number
+{
+    return number.italianLeadingZero && [self isLeadingZeroPossible:number.countryCode] == NO;
+}
+
+
+/**
+ * @param {i18n.phonenumbers.PhoneNumber} number
+ * @return {boolean}
+ * @private
+ */
+- (BOOL)hasFormattingPatternForNumber:(NBPhoneNumber*)number
+{
+    NSNumber *countryCallingCode = number.countryCode;
+    NSString *phoneNumberRegion = [self getRegionCodeForCountryCode:countryCallingCode];
+    NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:phoneNumberRegion];
+    
+    if (metadata == nil)
+    {
+        return NO;
+    }
+    
+    NSString *nationalNumber = [self getNationalSignificantNumber:number];
+    NBNumberFormat *formatRule = [self chooseFormattingPatternForNumber:metadata.numberFormats nationalNumber:nationalNumber];
+    return formatRule != nil;
+}
+
+
+/**
+ * Formats a phone number for out-of-country dialing purposes.
+ *
+ * Note that in this version, if the number was entered originally using alpha
+ * characters and this version of the number is stored in raw_input, this
+ * representation of the number will be used rather than the digit
+ * representation. Grouping information, as specified by characters such as '-'
+ * and ' ', will be retained.
+ *
+ * <p><b>Caveats:</b></p>
+ * <ul>
+ * <li>This will not produce good results if the country calling code is both
+ * present in the raw input _and_ is the start of the national number. This is
+ * not a problem in the regions which typically use alpha numbers.
+ * <li>This will also not produce good results if the raw input has any grouping
+ * information within the first three digits of the national number, and if the
+ * function needs to strip preceding digits/words in the raw input before these
+ * digits. Normally people group the first three digits together so this is not
+ * a huge problem - and will be fixed if it proves to be so.
+ * </ul>
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number that needs to
+ *     be formatted.
+ * @param {string} regionCallingFrom the region where the call is being placed.
+ * @return {string} the formatted phone number.
+ */
+- (NSString*)formatOutOfCountryKeepingAlphaChars:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom error:(NSError **)error
+{
+    NSString *res = nil;
+    @try {
+        res = [self formatOutOfCountryKeepingAlphaChars:number regionCallingFrom:regionCallingFrom];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (NSString*)formatOutOfCountryKeepingAlphaChars:(NBPhoneNumber*)number regionCallingFrom:(NSString*)regionCallingFrom
+{
+    NSString *rawInput = number.rawInput;
+    // If there is no raw input, then we can't keep alpha characters because there
+    // aren't any. In this case, we return formatOutOfCountryCallingNumber.
+    if (rawInput == nil || rawInput.length == 0)
+    {
+        return [self formatOutOfCountryCallingNumber:number regionCallingFrom:regionCallingFrom];
+    }
+    
+    NSNumber *countryCode = number.countryCode;
+    if ([self hasValidCountryCallingCode:countryCode] == NO)
+    {
+        return rawInput;
+    }
+    // Strip any prefix such as country calling code, IDD, that was present. We do
+    // this by comparing the number in raw_input with the parsed number. To do
+    // this, first we normalize punctuation. We retain number grouping symbols
+    // such as ' ' only.
+    rawInput = [self normalizeHelper:rawInput normalizationReplacements:_ALL_PLUS_NUMBER_GROUPING_SYMBOLS_ removeNonMatches:NO];
+    //NSLog(@"---- formatOutOfCountryKeepingAlphaChars normalizeHelper rawInput [%@]", rawInput);
+    // Now we trim everything before the first three digits in the parsed number.
+    // We choose three because all valid alpha numbers have 3 digits at the start
+    // - if it does not, then we don't trim anything at all. Similarly, if the
+    // national number was less than three digits, we don't trim anything at all.
+    NSString *nationalNumber = [self getNationalSignificantNumber:number];
+    if (nationalNumber.length > 3)
+    {
+        NSInteger firstNationalNumberDigit = [self indexOfStringByString:rawInput target:[nationalNumber substringWithRange:NSMakeRange(0, 3)]];
+        if (firstNationalNumberDigit != -1)
+        {
+            rawInput = [rawInput substringFromIndex:firstNationalNumberDigit];
+        }
+    }
+    
+    NBPhoneMetaData *metadataForRegionCallingFrom = [self getMetadataForRegion:regionCallingFrom];
+    if ([countryCode isEqualToNumber: @(NANPA_COUNTRY_CODE_)])
+    {
+        if ([self isNANPACountry:regionCallingFrom])
+        {
+            return [NSString stringWithFormat:@"%@ %@", countryCode, rawInput];
+        }
+    }
+    else if (metadataForRegionCallingFrom != nil && [countryCode isEqualToNumber: [self getCountryCodeForValidRegion:regionCallingFrom]])
+    {
+        NBNumberFormat *formattingPattern = [self chooseFormattingPatternForNumber:metadataForRegionCallingFrom.numberFormats
+                                                                    nationalNumber:nationalNumber];
+        if (formattingPattern == nil)
+        {
+            // If no pattern above is matched, we format the original input.
+            return rawInput;
+        }
+        
+        NBNumberFormat *newFormat = [formattingPattern copy];
+        // The first group is the first group of digits that the user wrote
+        // together.
+        newFormat.pattern = @"(\\d+)(.*)";
+        // Here we just concatenate them back together after the national prefix
+        // has been fixed.
+        newFormat.format = @"$1$2";
+        // Now we format using this pattern instead of the default pattern, but
+        // with the national prefix prefixed if necessary.
+        // This will not work in the cases where the pattern (and not the leading
+        // digits) decide whether a national prefix needs to be used, since we have
+        // overridden the pattern to match anything, but that is not the case in the
+        // metadata to date.
+        
+        return [self formatNsnUsingPattern:rawInput formattingPattern:newFormat numberFormat:NBEPhoneNumberFormatNATIONAL carrierCode:nil];
+    }
+    
+    NSString *internationalPrefixForFormatting = @"";
+    // If an unsupported region-calling-from is entered, or a country with
+    // multiple international prefixes, the international format of the number is
+    // returned, unless there is a preferred international prefix.
+    if (metadataForRegionCallingFrom != nil)
+    {
+        NSString *internationalPrefix = metadataForRegionCallingFrom.internationalPrefix;
+        internationalPrefixForFormatting =
+        [self matchesEntirely:UNIQUE_INTERNATIONAL_PREFIX_ string:internationalPrefix] ? internationalPrefix : metadataForRegionCallingFrom.preferredInternationalPrefix;
+    }
+    
+    NSString *regionCode = [self getRegionCodeForCountryCode:countryCode];
+    // Metadata cannot be nil because the country calling code is valid.
+    NBPhoneMetaData *metadataForRegion = [self getMetadataForRegionOrCallingCode:countryCode regionCode:regionCode];
+    NSString *formattedExtension = [self maybeGetFormattedExtension:number metadata:metadataForRegion numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
+    if (internationalPrefixForFormatting.length > 0)
+    {
+        return [NSString stringWithFormat:@"%@ %@ %@%@", internationalPrefixForFormatting, countryCode, rawInput, formattedExtension];
+    }
+    else
+    {
+        // Invalid region entered as country-calling-from (so no metadata was found
+        // for it) or the region chosen has multiple international dialling
+        // prefixes.
+        return [self prefixNumberWithCountryCallingCode:countryCode phoneNumberFormat:NBEPhoneNumberFormatINTERNATIONAL formattedNationalNumber:rawInput formattedExtension:formattedExtension];
+    }
+}
+
+
+/**
+ * Note in some regions, the national number can be written in two completely
+ * different ways depending on whether it forms part of the NATIONAL format or
+ * INTERNATIONAL format. The numberFormat parameter here is used to specify
+ * which format to use for those cases. If a carrierCode is specified, this will
+ * be inserted into the formatted string to replace $CC.
+ *
+ * @param {string} number a string of characters representing a phone number.
+ * @param {i18n.phonenumbers.PhoneMetadata} metadata the metadata for the
+ *     region that we think this number is from.
+ * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the
+ *     phone number should be formatted into.
+ * @param {string=} opt_carrierCode
+ * @return {string} the formatted phone number.
+ * @private
+ */
+- (NSString*)formatNsn:(NSString*)phoneNumber metadata:(NBPhoneMetaData*)metadata phoneNumberFormat:(NBEPhoneNumberFormat)numberFormat carrierCode:(NSString*)opt_carrierCode
+{
+    NSMutableArray *intlNumberFormats = metadata.intlNumberFormats;
+    // When the intlNumberFormats exists, we use that to format national number
+    // for the INTERNATIONAL format instead of using the numberDesc.numberFormats.
+    NSArray *availableFormats = ([intlNumberFormats count] <= 0 || numberFormat == NBEPhoneNumberFormatNATIONAL) ? metadata.numberFormats : intlNumberFormats;
+    NBNumberFormat *formattingPattern = [self chooseFormattingPatternForNumber:availableFormats nationalNumber:phoneNumber];
+    
+    if (formattingPattern == nil)
+    {
+        return phoneNumber;
+    }
+    
+    return [self formatNsnUsingPattern:phoneNumber formattingPattern:formattingPattern numberFormat:numberFormat carrierCode:opt_carrierCode];
+}
+
+
+/**
+ * @param {Array.<i18n.phonenumbers.NumberFormat>} availableFormats the
+ *     available formats the phone number could be formatted into.
+ * @param {string} nationalNumber a string of characters representing a phone
+ *     number.
+ * @return {i18n.phonenumbers.NumberFormat}
+ * @private
+ */
+- (NBNumberFormat*)chooseFormattingPatternForNumber:(NSArray*)availableFormats nationalNumber:(NSString*)nationalNumber
+{
+    for (NBNumberFormat *numFormat in availableFormats)
+    {
+        NSUInteger size = [numFormat.leadingDigitsPatterns count];
+        // We always use the last leading_digits_pattern, as it is the most detailed.
+        if (size == 0 || [self stringPositionByRegex:nationalNumber regex:[numFormat.leadingDigitsPatterns lastObject]] == 0)
+        {
+            if ([self matchesEntirely:numFormat.pattern string:nationalNumber])
+            {
+                return numFormat;
+            }
+        }
+    }
+    
+    return nil;
+}
+
+
+/**
+ * Note that carrierCode is optional - if nil or an empty string, no carrier
+ * code replacement will take place.
+ *
+ * @param {string} nationalNumber a string of characters representing a phone
+ *     number.
+ * @param {i18n.phonenumbers.NumberFormat} formattingPattern the formatting rule
+ *     the phone number should be formatted into.
+ * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the
+ *     phone number should be formatted into.
+ * @param {string=} opt_carrierCode
+ * @return {string} the formatted phone number.
+ * @private
+ */
+- (NSString*)formatNsnUsingPattern:(NSString*)nationalNumber formattingPattern:(NBNumberFormat*)formattingPattern numberFormat:(NBEPhoneNumberFormat)numberFormat carrierCode:(NSString*)opt_carrierCode
+{
+    NSString *numberFormatRule = formattingPattern.format;
+    NSString *domesticCarrierCodeFormattingRule = formattingPattern.domesticCarrierCodeFormattingRule;
+    NSString *formattedNationalNumber = @"";
+    
+    if (numberFormat == NBEPhoneNumberFormatNATIONAL && [self hasValue:opt_carrierCode] && domesticCarrierCodeFormattingRule.length > 0)
+    {
+        // Replace the $CC in the formatting rule with the desired carrier code.
+        NSString *carrierCodeFormattingRule = [self replaceStringByRegex:domesticCarrierCodeFormattingRule regex:CC_PATTERN_ withTemplate:opt_carrierCode];
+        // Now replace the $FG in the formatting rule with the first group and
+        // the carrier code combined in the appropriate way.
+        numberFormatRule = [self replaceFirstStringByRegex:numberFormatRule regex:FIRST_GROUP_PATTERN_
+                                              withTemplate:carrierCodeFormattingRule];
+        formattedNationalNumber = [self replaceStringByRegex:nationalNumber regex:formattingPattern.pattern withTemplate:numberFormatRule];
+    }
+    else
+    {
+        // Use the national prefix formatting rule instead.
+        NSString *nationalPrefixFormattingRule = formattingPattern.nationalPrefixFormattingRule;
+        if (numberFormat == NBEPhoneNumberFormatNATIONAL && [self hasValue:nationalPrefixFormattingRule])
+        {
+            NSString *replacePattern = [self replaceFirstStringByRegex:numberFormatRule regex:FIRST_GROUP_PATTERN_ withTemplate:nationalPrefixFormattingRule];
+            formattedNationalNumber = [self replaceStringByRegex:nationalNumber regex:formattingPattern.pattern withTemplate:replacePattern];
+        }
+        else
+        {
+            formattedNationalNumber = [self replaceStringByRegex:nationalNumber regex:formattingPattern.pattern withTemplate:numberFormatRule];
+        }
+    }
+    
+    if (numberFormat == NBEPhoneNumberFormatRFC3966)
+    {
+        // Strip any leading punctuation.
+        formattedNationalNumber = [self replaceStringByRegex:formattedNationalNumber regex:[NSString stringWithFormat:@"^%@", self.SEPARATOR_PATTERN_] withTemplate:@""];
+        
+        // Replace the rest with a dash between each number group.
+        formattedNationalNumber = [self replaceStringByRegex:formattedNationalNumber regex:self.SEPARATOR_PATTERN_ withTemplate:@"-"];
+    }
+    return formattedNationalNumber;
+}
+
+
+/**
+ * Gets a valid number for the specified region.
+ *
+ * @param {string} regionCode the region for which an example number is needed.
+ * @return {i18n.phonenumbers.PhoneNumber} a valid fixed-line number for the
+ *     specified region. Returns nil when the metadata does not contain such
+ *     information, or the region 001 is passed in. For 001 (representing non-
+ *     geographical numbers), call {@link #getExampleNumberForNonGeoEntity}
+ *     instead.
+ */
+- (NBPhoneNumber*)getExampleNumber:(NSString*)regionCode error:(NSError *__autoreleasing *)error
+{
+    NBPhoneNumber *res = nil;
+    @try {
+        res = [self getExampleNumber:regionCode];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (NBPhoneNumber*)getExampleNumber:(NSString*)regionCode
+{
+    return [self getExampleNumberForType:regionCode type:NBEPhoneNumberTypeFIXED_LINE];
+}
+
+
+/**
+ * Gets a valid number for the specified region and number type.
+ *
+ * @param {string} regionCode the region for which an example number is needed.
+ * @param {i18n.phonenumbers.PhoneNumberType} type the type of number that is
+ *     needed.
+ * @return {i18n.phonenumbers.PhoneNumber} a valid number for the specified
+ *     region and type. Returns nil when the metadata does not contain such
+ *     information or if an invalid region or region 001 was entered.
+ *     For 001 (representing non-geographical numbers), call
+ *     {@link #getExampleNumberForNonGeoEntity} instead.
+ */
+- (NBPhoneNumber*)getExampleNumberForType:(NSString*)regionCode type:(NBEPhoneNumberType)type error:(NSError *__autoreleasing *)error
+{
+    NBPhoneNumber *res = nil;
+    @try {
+        res = [self getExampleNumberForType:regionCode type:type];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (NBPhoneNumber*)getExampleNumberForType:(NSString*)regionCode type:(NBEPhoneNumberType)type
+{
+    // Check the region code is valid.
+    if ([self isValidRegionCode:regionCode] == NO)
+    {
+        return nil;
+    }
+    
+    NBPhoneNumberDesc *desc = [self getNumberDescByType:[self getMetadataForRegion:regionCode] type:type];
+    
+    @try {
+        if ([self hasValue:desc.exampleNumber ])
+        {
+            return [self parse:desc.exampleNumber defaultRegion:regionCode];
+        }
+    }
+    @catch (NSException *e)
+    {
+    }
+    
+    return nil;
+}
+
+
+/**
+ * Gets a valid number for the specified country calling code for a
+ * non-geographical entity.
+ *
+ * @param {number} countryCallingCode the country calling code for a
+ *     non-geographical entity.
+ * @return {i18n.phonenumbers.PhoneNumber} a valid number for the
+ *     non-geographical entity. Returns nil when the metadata does not contain
+ *     such information, or the country calling code passed in does not belong
+ *     to a non-geographical entity.
+ */
+- (NBPhoneNumber*)getExampleNumberForNonGeoEntity:(NSNumber*)countryCallingCode error:(NSError *__autoreleasing *)error
+{
+    NBPhoneNumber *res = nil;
+    @try {
+        res = [self getExampleNumberForNonGeoEntity:countryCallingCode];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (NBPhoneNumber*)getExampleNumberForNonGeoEntity:(NSNumber*)countryCallingCode
+{
+    NBPhoneMetaData *metadata = [self getMetadataForNonGeographicalRegion:countryCallingCode];
+    
+    if (metadata != nil)
+    {
+        NBPhoneNumberDesc *desc = metadata.generalDesc;
+        @try {
+            if ([self hasValue:desc.exampleNumber])
+            {
+                NSString *callCode = [NSString stringWithFormat:@"+%@%@", countryCallingCode, desc.exampleNumber];
+                return [self parse:callCode defaultRegion:UNKNOWN_REGION_];
+            }
+        }
+        @catch (NSException *e) {
+        }
+    }
+    return nil;
+}
+
+
+/**
+ * Gets the formatted extension of a phone number, if the phone number had an
+ * extension specified. If not, it returns an empty string.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the PhoneNumber that might have
+ *     an extension.
+ * @param {i18n.phonenumbers.PhoneMetadata} metadata the metadata for the
+ *     region that we think this number is from.
+ * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the
+ *     phone number should be formatted into.
+ * @return {string} the formatted extension if any.
+ * @private
+ */
+- (NSString*)maybeGetFormattedExtension:(NBPhoneNumber*)number metadata:(NBPhoneMetaData*)metadata numberFormat:(NBEPhoneNumberFormat)numberFormat
+{
+    if ([self hasValue:number.extension] == NO)
+    {
+        return @"";
+    }
+    else
+    {
+        if (numberFormat == NBEPhoneNumberFormatRFC3966)
+        {
+            return [NSString stringWithFormat:@"%@%@", RFC3966_EXTN_PREFIX_, number.extension];
+        }
+        else
+        {
+            if ([self hasValue:metadata.preferredExtnPrefix])
+            {
+                return [NSString stringWithFormat:@"%@%@", metadata.preferredExtnPrefix, number.extension];
+            }
+            else
+            {
+                return [NSString stringWithFormat:@"%@%@", DEFAULT_EXTN_PREFIX_, number.extension];
+            }
+        }
+    }
+}
+
+
+/**
+ * @param {i18n.phonenumbers.PhoneMetadata} metadata
+ * @param {i18n.phonenumbers.PhoneNumberType} type
+ * @return {i18n.phonenumbers.PhoneNumberDesc}
+ * @private
+ */
+- (NBPhoneNumberDesc*)getNumberDescByType:(NBPhoneMetaData*)metadata type:(NBEPhoneNumberType)type
+{
+    switch (type)
+    {
+        case NBEPhoneNumberTypePREMIUM_RATE:
+            return metadata.premiumRate;
+        case NBEPhoneNumberTypeTOLL_FREE:
+            return metadata.tollFree;
+        case NBEPhoneNumberTypeMOBILE:
+            if (metadata.mobile == nil) return metadata.generalDesc;
+            return metadata.mobile;
+        case NBEPhoneNumberTypeFIXED_LINE:
+        case NBEPhoneNumberTypeFIXED_LINE_OR_MOBILE:
+            if (metadata.fixedLine == nil) return metadata.generalDesc;
+            return metadata.fixedLine;
+        case NBEPhoneNumberTypeSHARED_COST:
+            return metadata.sharedCost;
+        case NBEPhoneNumberTypeVOIP:
+            return metadata.voip;
+        case NBEPhoneNumberTypePERSONAL_NUMBER:
+            return metadata.personalNumber;
+        case NBEPhoneNumberTypePAGER:
+            return metadata.pager;
+        case NBEPhoneNumberTypeUAN:
+            return metadata.uan;
+        case NBEPhoneNumberTypeVOICEMAIL:
+            return metadata.voicemail;
+        default:
+            return metadata.generalDesc;
+    }
+}
+
+/**
+ * Gets the type of a phone number.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number that we want
+ *     to know the type.
+ * @return {i18n.phonenumbers.PhoneNumberType} the type of the phone number.
+ */
+- (NBEPhoneNumberType)getNumberType:(NBPhoneNumber*)phoneNumber
+{
+    NSString *regionCode = [self getRegionCodeForNumber:phoneNumber];
+    NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:phoneNumber.countryCode regionCode:regionCode];
+    if (metadata == nil)
+    {
+        return NBEPhoneNumberTypeUNKNOWN;
+    }
+    
+    NSString *nationalSignificantNumber = [self getNationalSignificantNumber:phoneNumber];
+    return [self getNumberTypeHelper:nationalSignificantNumber metadata:metadata];
+}
+
+
+/**
+ * @param {string} nationalNumber
+ * @param {i18n.phonenumbers.PhoneMetadata} metadata
+ * @return {i18n.phonenumbers.PhoneNumberType}
+ * @private
+ */
+- (NBEPhoneNumberType)getNumberTypeHelper:(NSString*)nationalNumber metadata:(NBPhoneMetaData*)metadata
+{
+    NBPhoneNumberDesc *generalNumberDesc = metadata.generalDesc;
+    
+    //NSLog(@"getNumberTypeHelper - UNKNOWN 1");
+    if ([self hasValue:generalNumberDesc.nationalNumberPattern] == NO ||
+        [self isNumberMatchingDesc:nationalNumber numberDesc:generalNumberDesc] == NO)
+    {
+        //NSLog(@"getNumberTypeHelper - UNKNOWN 2");
+        return NBEPhoneNumberTypeUNKNOWN;
+    }
+    
+    //NSLog(@"getNumberTypeHelper - PREMIUM_RATE 1");
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.premiumRate])
+    {
+        //NSLog(@"getNumberTypeHelper - PREMIUM_RATE 2");
+        return NBEPhoneNumberTypePREMIUM_RATE;
+    }
+    
+    //NSLog(@"getNumberTypeHelper - TOLL_FREE 1");
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.tollFree])
+    {
+        //NSLog(@"getNumberTypeHelper - TOLL_FREE 2");
+        return NBEPhoneNumberTypeTOLL_FREE;
+    }
+    
+    //NSLog(@"getNumberTypeHelper - SHARED_COST 1");
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.sharedCost])
+    {
+        //NSLog(@"getNumberTypeHelper - SHARED_COST 2");
+        return NBEPhoneNumberTypeSHARED_COST;
+    }
+    
+    //NSLog(@"getNumberTypeHelper - VOIP 1");
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.voip])
+    {
+        //NSLog(@"getNumberTypeHelper - VOIP 2");
+        return NBEPhoneNumberTypeVOIP;
+    }
+    
+    //NSLog(@"getNumberTypeHelper - PERSONAL_NUMBER 1");
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.personalNumber])
+    {
+        //NSLog(@"getNumberTypeHelper - PERSONAL_NUMBER 2");
+        return NBEPhoneNumberTypePERSONAL_NUMBER;
+    }
+    
+    //NSLog(@"getNumberTypeHelper - PAGER 1");
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.pager])
+    {
+        //NSLog(@"getNumberTypeHelper - PAGER 2");
+        return NBEPhoneNumberTypePAGER;
+    }
+    
+    //NSLog(@"getNumberTypeHelper - UAN 1");
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.uan])
+    {
+        //NSLog(@"getNumberTypeHelper - UAN 2");
+        return NBEPhoneNumberTypeUAN;
+    }
+    
+    //NSLog(@"getNumberTypeHelper - VOICEMAIL 1");
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.voicemail])
+    {
+        //NSLog(@"getNumberTypeHelper - VOICEMAIL 2");
+        return NBEPhoneNumberTypeVOICEMAIL;
+    }
+    
+    if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.fixedLine])
+    {
+        if (metadata.sameMobileAndFixedLinePattern)
+        {
+            //NSLog(@"getNumberTypeHelper - FIXED_LINE_OR_MOBILE");
+            return NBEPhoneNumberTypeFIXED_LINE_OR_MOBILE;
+        }
+        else if ([self isNumberMatchingDesc:nationalNumber numberDesc:metadata.mobile])
+        {
+            //NSLog(@"getNumberTypeHelper - FIXED_LINE_OR_MOBILE");
+            return NBEPhoneNumberTypeFIXED_LINE_OR_MOBILE;
+        }
+        //NSLog(@"getNumberTypeHelper - FIXED_LINE");
+        return NBEPhoneNumberTypeFIXED_LINE;
+    }
+    
+    // Otherwise, test to see if the number is mobile. Only do this if certain
+    // that the patterns for mobile and fixed line aren't the same.
+    if ([metadata sameMobileAndFixedLinePattern] == NO && [self isNumberMatchingDesc:nationalNumber numberDesc:metadata.mobile])
+    {
+        return NBEPhoneNumberTypeMOBILE;
+    }
+    
+    return NBEPhoneNumberTypeUNKNOWN;
+}
+
+
+/**
+ * Returns the metadata for the given region code or {@code nil} if the region
+ * code is invalid or unknown.
+ *
+ * @param {?string} regionCode
+ * @return {i18n.phonenumbers.PhoneMetadata}
+ */
+- (NBPhoneMetaData*)getMetadataForRegion:(NSString*)regionCode
+{
+    if ([self hasValue:regionCode] == NO)
+    {
+        return nil;
+    }
+    
+    regionCode = [regionCode uppercaseString];
+    
+    NBPhoneMetaData *metadata = [self.coreMetaData objectForKey:regionCode];
+    
+    return metadata;
+}
+
+
+/**
+ * @param {number} countryCallingCode
+ * @return {i18n.phonenumbers.PhoneMetadata}
+ */
+- (NBPhoneMetaData*)getMetadataForNonGeographicalRegion:(NSNumber*)countryCallingCode
+{
+    NSString *countryCallingCodeStr = [NSString stringWithFormat:@"%@", countryCallingCode];
+    return [self getMetadataForRegion:countryCallingCodeStr];
+}
+
+
+/**
+ * @param {string} nationalNumber
+ * @param {i18n.phonenumbers.PhoneNumberDesc} numberDesc
+ * @return {boolean}
+ * @private
+ */
+- (BOOL)isNumberMatchingDesc:(NSString*)nationalNumber numberDesc:(NBPhoneNumberDesc*)numberDesc
+{
+    if (numberDesc == nil)
+        return NO;
+    
+    if ([self hasValue:numberDesc.possibleNumberPattern] == NO || [numberDesc.possibleNumberPattern isEqual:@"NA"])
+        return [self matchesEntirely:numberDesc.nationalNumberPattern string:nationalNumber];
+    
+    if ([self hasValue:numberDesc.nationalNumberPattern] == NO || [numberDesc.nationalNumberPattern isEqual:@"NA"])
+        return [self matchesEntirely:numberDesc.possibleNumberPattern string:nationalNumber];
+    
+    return [self matchesEntirely:numberDesc.possibleNumberPattern string:nationalNumber] &&
+    [self matchesEntirely:numberDesc.nationalNumberPattern string:nationalNumber];
+}
+
+
+/**
+ * Tests whether a phone number matches a valid pattern. Note this doesn't
+ * verify the number is actually in use, which is impossible to tell by just
+ * looking at a number itself.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number that we want
+ *     to validate.
+ * @return {boolean} a boolean that indicates whether the number is of a valid
+ *     pattern.
+ */
+- (BOOL)isValidNumber:(NBPhoneNumber*)number
+{
+    NSString *regionCode = [self getRegionCodeForNumber:number];
+    return [self isValidNumberForRegion:number regionCode:regionCode];
+}
+
+
+/**
+ * Tests whether a phone number is valid for a certain region. Note this doesn't
+ * verify the number is actually in use, which is impossible to tell by just
+ * looking at a number itself. If the country calling code is not the same as
+ * the country calling code for the region, this immediately exits with NO.
+ * After this, the specific number pattern rules for the region are examined.
+ * This is useful for determining for example whether a particular number is
+ * valid for Canada, rather than just a valid NANPA number.
+ * Warning: In most cases, you want to use {@link #isValidNumber} instead. For
+ * example, this method will mark numbers from British Crown dependencies such
+ * as the Isle of Man as invalid for the region "GB" (United Kingdom), since it
+ * has its own region code, "IM", which may be undesirable.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number that we want
+ *     to validate.
+ * @param {?string} regionCode the region that we want to validate the phone
+ *     number for.
+ * @return {boolean} a boolean that indicates whether the number is of a valid
+ *     pattern.
+ */
+- (BOOL)isValidNumberForRegion:(NBPhoneNumber*)number regionCode:(NSString*)regionCode
+{
+    NSNumber *countryCode = number.countryCode;
+
+    NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCode regionCode:regionCode];
+    if (metadata == nil ||
+        ([_REGION_CODE_FOR_NON_GEO_ENTITY isEqualToString:regionCode] == NO &&
+         ![countryCode isEqualToNumber: [self getCountryCodeForValidRegion:regionCode]]))
+    {
+        // Either the region code was invalid, or the country calling code for this
+        // number does not match that of the region code.
+        return NO;
+    }
+    
+    NBPhoneNumberDesc *generalNumDesc = metadata.generalDesc;
+    NSString *nationalSignificantNumber = [self getNationalSignificantNumber:number];
+    
+    // For regions where we don't have metadata for PhoneNumberDesc, we treat any
+    // number passed in as a valid number if its national significant number is
+    // between the minimum and maximum lengths defined by ITU for a national
+    // significant number.
+    if ([self hasValue:generalNumDesc.nationalNumberPattern] == NO)
+    {
+        NSUInteger numberLength = nationalSignificantNumber.length;
+        return numberLength > MIN_LENGTH_FOR_NSN_ && numberLength <= MAX_LENGTH_FOR_NSN_;
+    }
+    
+    return [self getNumberTypeHelper:nationalSignificantNumber metadata:metadata] != NBEPhoneNumberTypeUNKNOWN;
+}
+
+
+/**
+ * Returns the region where a phone number is from. This could be used for
+ * geocoding at the region level.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone number whose origin
+ *     we want to know.
+ * @return {?string} the region where the phone number is from, or nil
+ *     if no region matches this calling code.
+ */
+- (NSString*)getRegionCodeForNumber:(NBPhoneNumber*)phoneNumber
+{
+    if (phoneNumber == nil)
+    {
+        return nil;
+    }
+    
+    NSArray *regionCodes = [self regionCodeFromCountryCode:phoneNumber.countryCode];
+    if (regionCodes == nil || [regionCodes count] <= 0)
+    {
+        return nil;
+    }
+    
+    if ([regionCodes count] == 1)
+    {
+        return [regionCodes objectAtIndex:0];
+    }
+    else
+    {
+        return [self getRegionCodeForNumberFromRegionList:phoneNumber regionCodes:regionCodes];
+    }
+}
+
+
+/**
+ * @param {i18n.phonenumbers.PhoneNumber} number
+ * @param {Array.<string>} regionCodes
+ * @return {?string}
+ * @private
+ 
+ */
+- (NSString*)getRegionCodeForNumberFromRegionList:(NBPhoneNumber*)phoneNumber regionCodes:(NSArray*)regionCodes
+{
+    NSString *nationalNumber = [self getNationalSignificantNumber:phoneNumber];
+    NSUInteger regionCodesCount = [regionCodes count];
+    
+    for (NSUInteger i = 0; i<regionCodesCount; i++)
+    {
+        NSString *regionCode = [regionCodes objectAtIndex:i];
+        NBPhoneMetaData *metadata = [self getMetadataForRegion:regionCode];
+        
+        if ([self hasValue:metadata.leadingDigits])
+        {
+            if ([self stringPositionByRegex:nationalNumber regex:metadata.leadingDigits] == 0)
+            {
+                return regionCode;
+            }
+        }
+        else if ([self getNumberTypeHelper:nationalNumber metadata:metadata] != NBEPhoneNumberTypeUNKNOWN)
+        {
+            return regionCode;
+        }
+    }
+    
+    return nil;
+}
+
+
+/**
+ * Returns the region code that matches the specific country calling code. In
+ * the case of no region code being found, ZZ will be returned. In the case of
+ * multiple regions, the one designated in the metadata as the 'main' region for
+ * this calling code will be returned.
+ *
+ * @param {number} countryCallingCode the country calling code.
+ * @return {string}
+ */
+- (NSString*)getRegionCodeForCountryCode:(NSNumber*)countryCallingCode
+{
+    NSArray *regionCodes = [self regionCodeFromCountryCode:countryCallingCode];
+    return regionCodes == nil ? UNKNOWN_REGION_ : [regionCodes objectAtIndex:0];
+}
+
+
+/**
+ * Returns a list with the region codes that match the specific country calling
+ * code. For non-geographical country calling codes, the region code 001 is
+ * returned. Also, in the case of no region code being found, an empty list is
+ * returned.
+ *
+ * @param {number} countryCallingCode the country calling code.
+ * @return {Array.<string>}
+ */
+- (NSArray*)getRegionCodesForCountryCode:(NSNumber*)countryCallingCode
+{
+    NSArray *regionCodes = [self regionCodeFromCountryCode:countryCallingCode];
+    return regionCodes == nil ? nil : regionCodes;
+}
+
+
+/**
+ * Returns the country calling code for a specific region. For example, this
+ * would be 1 for the United States, and 64 for New Zealand.
+ *
+ * @param {?string} regionCode the region that we want to get the country
+ *     calling code for.
+ * @return {number} the country calling code for the region denoted by
+ *     regionCode.
+ */
+- (NSNumber*)getCountryCodeForRegion:(NSString*)regionCode
+{
+    if ([self isValidRegionCode:regionCode] == NO)
+    {
+        return @0;
+    }
+    
+    NSError *error = nil;
+    NSNumber *res = [self getCountryCodeForValidRegion:regionCode error:&error];
+    if (error != nil)
+        return @0;
+    return res;
+}
+
+
+/**
+ * Returns the country calling code for a specific region. For example, this
+ * would be 1 for the United States, and 64 for New Zealand. Assumes the region
+ * is already valid.
+ *
+ * @param {?string} regionCode the region that we want to get the country
+ *     calling code for.
+ * @return {number} the country calling code for the region denoted by
+ *     regionCode.
+ * @throws {string} if the region is invalid
+ * @private
+ */
+- (NSNumber *)getCountryCodeForValidRegion:(NSString*)regionCode error:(NSError**)error
+{
+    NSNumber * res = nil;
+    @try {
+        res = [self getCountryCodeForValidRegion:regionCode];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+- (NSNumber *)getCountryCodeForValidRegion:(NSString*)regionCode
+{
+    NBPhoneMetaData *metadata = [self getMetadataForRegion:regionCode];
+    if (metadata == nil)
+    {
+        NSException* metaException = [NSException exceptionWithName:@"INVALID_REGION_CODE"
+                                                             reason:[NSString stringWithFormat:@"Invalid region code:%@", regionCode]
+                                                           userInfo:nil];
+        @throw metaException;
+    }
+    return metadata.countryCode;
+}
+
+
+/**
+ * Returns the national dialling prefix for a specific region. For example, this
+ * would be 1 for the United States, and 0 for New Zealand. Set stripNonDigits
+ * to NO to strip symbols like '~' (which indicates a wait for a dialling
+ * tone) from the prefix returned. If no national prefix is present, we return
+ * nil.
+ *
+ * <p>Warning: Do not use this method for do-your-own formatting - for some
+ * regions, the national dialling prefix is used only for certain types of
+ * numbers. Use the library's formatting functions to prefix the national prefix
+ * when required.
+ *
+ * @param {?string} regionCode the region that we want to get the dialling
+ *     prefix for.
+ * @param {boolean} stripNonDigits NO to strip non-digits from the national
+ *     dialling prefix.
+ * @return {?string} the dialling prefix for the region denoted by
+ *     regionCode.
+ */
+- (NSString*)getNddPrefixForRegion:(NSString*)regionCode stripNonDigits:(BOOL)stripNonDigits
+{
+    NBPhoneMetaData *metadata = [self getMetadataForRegion:regionCode];
+    if (metadata == nil)
+    {
+        return nil;
+    }
+    
+    NSString *nationalPrefix = metadata.nationalPrefix;
+    // If no national prefix was found, we return nil.
+    if (nationalPrefix.length == 0)
+    {
+        return nil;
+    }
+    
+    if (stripNonDigits)
+    {
+        // Note: if any other non-numeric symbols are ever used in national
+        // prefixes, these would have to be removed here as well.
+        nationalPrefix = [nationalPrefix stringByReplacingOccurrencesOfString:@"~" withString:@""];
+    }
+    return nationalPrefix;
+}
+
+
+/**
+ * Checks if this is a region under the North American Numbering Plan
+ * Administration (NANPA).
+ *
+ * @param {?string} regionCode the ISO 3166-1 two-letter region code.
+ * @return {boolean} NO if regionCode is one of the regions under NANPA.
+ */
+- (BOOL)isNANPACountry:(NSString*)regionCode
+{
+    BOOL isExists = NO;
+    
+    NSArray *res = [self regionCodeFromCountryCode:@(NANPA_COUNTRY_CODE_)];
+    for (NSString *inRegionCode in res)
+    {
+        if ([inRegionCode isEqualToString:regionCode.uppercaseString])
+        {
+            isExists = YES;
+        }
+    }
+    
+    return regionCode != nil && isExists;
+}
+
+
+/**
+ * Checks whether countryCode represents the country calling code from a region
+ * whose national significant number could contain a leading zero. An example of
+ * such a region is Italy. Returns NO if no metadata for the country is
+ * found.
+ *
+ * @param {number} countryCallingCode the country calling code.
+ * @return {boolean}
+ */
+- (BOOL)isLeadingZeroPossible:(NSNumber*)countryCallingCode
+{
+    NBPhoneMetaData *mainMetadataForCallingCode = [self getMetadataForRegionOrCallingCode:countryCallingCode
+                                                                               regionCode:[self getRegionCodeForCountryCode:countryCallingCode]];
+    
+    return mainMetadataForCallingCode != nil && mainMetadataForCallingCode.leadingZeroPossible;
+}
+
+
+/**
+ * Checks if the number is a valid vanity (alpha) number such as 800 MICROSOFT.
+ * A valid vanity number will start with at least 3 digits and will have three
+ * or more alpha characters. This does not do region-specific checks - to work
+ * out if this number is actually valid for a region, it should be parsed and
+ * methods such as {@link #isPossibleNumberWithReason} and
+ * {@link #isValidNumber} should be used.
+ *
+ * @param {string} number the number that needs to be checked.
+ * @return {boolean} NO if the number is a valid vanity number.
+ */
+- (BOOL)isAlphaNumber:(NSString*)number
+{
+    if ([self isViablePhoneNumber:number] == NO)
+    {
+        // Number is too short, or doesn't match the basic phone number pattern.
+        return NO;
+    }
+    
+    /** @type {!goog.string.StringBuffer} */
+    NSString *strippedNumber = [number copy];
+    [self maybeStripExtension:&strippedNumber];
+    
+    return [self matchesEntirely:VALID_ALPHA_PHONE_PATTERN_STRING string:strippedNumber];
+}
+
+
+/**
+ * Convenience wrapper around {@link #isPossibleNumberWithReason}. Instead of
+ * returning the reason for failure, this method returns a boolean value.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the number that needs to be
+ *     checked.
+ * @return {boolean} NO if the number is possible.
+ */
+- (BOOL)isPossibleNumber:(NBPhoneNumber*)number error:(NSError**)error
+{
+    BOOL res = NO;
+    @try {
+        res = [self isPossibleNumber:number];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (BOOL)isPossibleNumber:(NBPhoneNumber*)number
+{
+    return [self isPossibleNumberWithReason:number] == NBEValidationResultIS_POSSIBLE;
+}
+
+
+/**
+ * Helper method to check a number against a particular pattern and determine
+ * whether it matches, or is too short or too long. Currently, if a number
+ * pattern suggests that numbers of length 7 and 10 are possible, and a number
+ * in between these possible lengths is entered, such as of length 8, this will
+ * return TOO_LONG.
+ *
+ * @param {string} numberPattern
+ * @param {string} number
+ * @return {ValidationResult}
+ * @private
+ */
+- (NBEValidationResult)testNumberLengthAgainstPattern:(NSString*)numberPattern number:(NSString*)number
+{
+    if ([self matchesEntirely:numberPattern string:number])
+    {
+        return NBEValidationResultIS_POSSIBLE;
+    }
+    
+    if ([self stringPositionByRegex:number regex:numberPattern] == 0)
+    {
+        return NBEValidationResultTOO_LONG;
+    }
+    else
+    {
+        return NBEValidationResultTOO_SHORT;
+    }
+}
+
+
+/**
+ * Check whether a phone number is a possible number. It provides a more lenient
+ * check than {@link #isValidNumber} in the following sense:
+ * <ol>
+ * <li>It only checks the length of phone numbers. In particular, it doesn't
+ * check starting digits of the number.
+ * <li>It doesn't attempt to figure out the type of the number, but uses general
+ * rules which applies to all types of phone numbers in a region. Therefore, it
+ * is much faster than isValidNumber.
+ * <li>For fixed line numbers, many regions have the concept of area code, which
+ * together with subscriber number constitute the national significant number.
+ * It is sometimes okay to dial the subscriber number only when dialing in the
+ * same area. This function will return NO if the subscriber-number-only
+ * version is passed in. On the other hand, because isValidNumber validates
+ * using information on both starting digits (for fixed line numbers, that would
+ * most likely be area codes) and length (obviously includes the length of area
+ * codes for fixed line numbers), it will return NO for the
+ * subscriber-number-only version.
+ * </ol>
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the number that needs to be
+ *     checked.
+ * @return {ValidationResult} a
+ *     ValidationResult object which indicates whether the number is possible.
+ */
+- (NBEValidationResult)isPossibleNumberWithReason:(NBPhoneNumber*)number error:(NSError *__autoreleasing *)error
+{
+    NBEValidationResult res = -1;
+    @try {
+        res = [self isPossibleNumberWithReason:number];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    
+    return res;
+}
+
+
+- (NBEValidationResult)isPossibleNumberWithReason:(NBPhoneNumber*)number
+{
+    NSString *nationalNumber = [self getNationalSignificantNumber:number];
+    NSNumber *countryCode = number.countryCode;
+    // Note: For Russian Fed and NANPA numbers, we just use the rules from the
+    // default region (US or Russia) since the getRegionCodeForNumber will not
+    // work if the number is possible but not valid. This would need to be
+    // revisited if the possible number pattern ever differed between various
+    // regions within those plans.
+    if ([self hasValidCountryCallingCode:countryCode] == NO)
+    {
+        return NBEValidationResultINVALID_COUNTRY_CODE;
+    }
+    
+    NSString *regionCode = [self getRegionCodeForCountryCode:countryCode];
+    // Metadata cannot be nil because the country calling code is valid.
+    NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCode regionCode:regionCode];
+    NBPhoneNumberDesc *generalNumDesc = metadata.generalDesc;
+    
+    // Handling case of numbers with no metadata.
+    if ([self hasValue:generalNumDesc.nationalNumberPattern] == NO)
+    {
+        NSUInteger numberLength = nationalNumber.length;
+        
+        if (numberLength < MIN_LENGTH_FOR_NSN_)
+        {
+            return NBEValidationResultTOO_SHORT;
+        }
+        else if (numberLength > MAX_LENGTH_FOR_NSN_)
+        {
+            return NBEValidationResultTOO_LONG;
+        }
+        else
+        {
+            return NBEValidationResultIS_POSSIBLE;
+        }
+    }
+    
+    NSString *possibleNumberPattern = generalNumDesc.possibleNumberPattern;
+    return [self testNumberLengthAgainstPattern:possibleNumberPattern number:nationalNumber];
+}
+
+
+/**
+ * Check whether a phone number is a possible number given a number in the form
+ * of a string, and the region where the number could be dialed from. It
+ * provides a more lenient check than {@link #isValidNumber}. See
+ * {@link #isPossibleNumber} for details.
+ *
+ * <p>This method first parses the number, then invokes
+ * {@link #isPossibleNumber} with the resultant PhoneNumber object.
+ *
+ * @param {string} number the number that needs to be checked, in the form of a
+ *     string.
+ * @param {string} regionDialingFrom the region that we are expecting the number
+ *     to be dialed from.
+ *     Note this is different from the region where the number belongs.
+ *     For example, the number +1 650 253 0000 is a number that belongs to US.
+ *     When written in this form, it can be dialed from any region. When it is
+ *     written as 00 1 650 253 0000, it can be dialed from any region which uses
+ *     an international dialling prefix of 00. When it is written as
+ *     650 253 0000, it can only be dialed from within the US, and when written
+ *     as 253 0000, it can only be dialed from within a smaller area in the US
+ *     (Mountain View, CA, to be more specific).
+ * @return {boolean} NO if the number is possible.
+ */
+- (BOOL)isPossibleNumberString:(NSString*)number regionDialingFrom:(NSString*)regionDialingFrom error:(NSError**)error
+{
+    BOOL res = NO;
+    @try {
+        res = [self isPossibleNumberString:number regionDialingFrom:regionDialingFrom];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (BOOL)isPossibleNumberString:(NSString*)number regionDialingFrom:(NSString*)regionDialingFrom
+{
+    @try {
+        return [self isPossibleNumber:[self parse:number defaultRegion:regionDialingFrom]];
+    }
+    @catch (NSException *e) {
+        return NO;
+    }
+}
+
+
+/**
+ * Attempts to extract a valid number from a phone number that is too long to be
+ * valid, and resets the PhoneNumber object passed in to that valid version. If
+ * no valid number could be extracted, the PhoneNumber object passed in will not
+ * be modified.
+ * @param {i18n.phonenumbers.PhoneNumber} number a PhoneNumber object which
+ *     contains a number that is too long to be valid.
+ * @return {boolean} NO if a valid phone number can be successfully extracted.
+ */
+- (BOOL)truncateTooLongNumber:(NBPhoneNumber*)number error:(NSError**)error
+{
+    BOOL res = NO;
+    @try {
+        res = [self truncateTooLongNumber:number];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (BOOL)truncateTooLongNumber:(NBPhoneNumber*)number
+{
+    if ([self isValidNumber:number])
+    {
+        return YES;
+    }
+
+    NBPhoneNumber *numberCopy = [number copy];
+    NSNumber *nationalNumber = number.nationalNumber;
+    do {
+        nationalNumber = [NSNumber numberWithLongLong:(long long)floor(nationalNumber.unsignedLongLongValue / 10)];
+        numberCopy.nationalNumber = [nationalNumber copy];
+        if ([nationalNumber isEqualToNumber:@0] || [self isPossibleNumberWithReason:numberCopy] == NBEValidationResultTOO_SHORT) {
+            return NO;
+        }
+    }
+    while ([self isValidNumber:numberCopy] == NO);
+    
+    number.nationalNumber = nationalNumber;
+    return YES;
+}
+
+
+/**
+ * Extracts country calling code from fullNumber, returns it and places the
+ * remaining number in nationalNumber. It assumes that the leading plus sign or
+ * IDD has already been removed. Returns 0 if fullNumber doesn't start with a
+ * valid country calling code, and leaves nationalNumber unmodified.
+ *
+ * @param {!goog.string.StringBuffer} fullNumber
+ * @param {!goog.string.StringBuffer} nationalNumber
+ * @return {number}
+ */
+- (NSNumber*)extractCountryCode:(NSString*)fullNumber nationalNumber:(NSString**)nationalNumber
+{
+    if ((fullNumber.length == 0) || ([[fullNumber substringToIndex:1] isEqualToString:@"0"]))
+    {
+        // Country codes do not begin with a '0'.
+        return @0;
+    }
+    
+    NSUInteger numberLength = fullNumber.length;
+    
+    for (NSUInteger i = 1; i <= MAX_LENGTH_COUNTRY_CODE_ && i <= numberLength; ++i)
+    {
+        NSString *subNumber = [fullNumber substringWithRange:NSMakeRange(0, i)];
+        NSNumber *potentialCountryCode = [NSNumber numberWithInteger:[subNumber integerValue]];
+
+        NSArray *regionCodes = [self regionCodeFromCountryCode:potentialCountryCode];
+        if (regionCodes != nil && regionCodes.count > 0)
+        {
+            if (nationalNumber != NULL)
+            {
+                if ((*nationalNumber) == nil)
+                    (*nationalNumber) = [NSString stringWithFormat:@"%@", [fullNumber substringFromIndex:i]];
+                else
+                    (*nationalNumber) = [NSString stringWithFormat:@"%@%@", (*nationalNumber), [fullNumber substringFromIndex:i]];
+            }
+            return potentialCountryCode;
+        }
+    }
+    
+    return @0;
+}
+
+
+/**
+ * Tries to extract a country calling code from a number. This method will
+ * return zero if no country calling code is considered to be present. Country
+ * calling codes are extracted in the following ways:
+ * <ul>
+ * <li>by stripping the international dialing prefix of the region the person is
+ * dialing from, if this is present in the number, and looking at the next
+ * digits
+ * <li>by stripping the '+' sign if present and then looking at the next digits
+ * <li>by comparing the start of the number and the country calling code of the
+ * default region. If the number is not considered possible for the numbering
+ * plan of the default region initially, but starts with the country calling
+ * code of this region, validation will be reattempted after stripping this
+ * country calling code. If this number is considered a possible number, then
+ * the first digits will be considered the country calling code and removed as
+ * such.
+ * </ul>
+ *
+ * It will throw a i18n.phonenumbers.Error if the number starts with a '+' but
+ * the country calling code supplied after this does not match that of any known
+ * region.
+ *
+ * @param {string} number non-normalized telephone number that we wish to
+ *     extract a country calling code from - may begin with '+'.
+ * @param {i18n.phonenumbers.PhoneMetadata} defaultRegionMetadata metadata
+ *     about the region this number may be from.
+ * @param {!goog.string.StringBuffer} nationalNumber a string buffer to store
+ *     the national significant number in, in the case that a country calling
+ *     code was extracted. The number is appended to any existing contents. If
+ *     no country calling code was extracted, this will be left unchanged.
+ * @param {boolean} keepRawInput NO if the country_code_source and
+ *     preferred_carrier_code fields of phoneNumber should be populated.
+ * @param {i18n.phonenumbers.PhoneNumber} phoneNumber the PhoneNumber object
+ *     where the country_code and country_code_source need to be populated.
+ *     Note the country_code is always populated, whereas country_code_source is
+ *     only populated when keepCountryCodeSource is NO.
+ * @return {number} the country calling code extracted or 0 if none could be
+ *     extracted.
+ * @throws {i18n.phonenumbers.Error}
+ */
+- (NSNumber*)maybeExtractCountryCode:(NSString*)number metadata:(NBPhoneMetaData*)defaultRegionMetadata
+                   nationalNumber:(NSString**)nationalNumber keepRawInput:(BOOL)keepRawInput
+                      phoneNumber:(NBPhoneNumber**)phoneNumber error:(NSError**)error
+{
+    if (nationalNumber == NULL || phoneNumber == NULL)
+    {
+        return @0;
+    }
+    
+    NSNumber *res = @0;
+    @try {
+        res = [self maybeExtractCountryCode:number metadata:defaultRegionMetadata
+                             nationalNumber:nationalNumber keepRawInput:keepRawInput phoneNumber:phoneNumber];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    
+    return res;
+}
+
+- (NSNumber*)maybeExtractCountryCode:(NSString*)number metadata:(NBPhoneMetaData*)defaultRegionMetadata
+                   nationalNumber:(NSString**)nationalNumber keepRawInput:(BOOL)keepRawInput
+                      phoneNumber:(NBPhoneNumber**)phoneNumber
+{
+    if (nationalNumber == NULL || phoneNumber == NULL || number.length <= 0)
+    {
+        return @0;
+    }
+    
+    NSString *fullNumber = [number copy];
+    // Set the default prefix to be something that will never match.
+    NSString *possibleCountryIddPrefix = @"";
+    if (defaultRegionMetadata != nil)
+    {
+        possibleCountryIddPrefix = defaultRegionMetadata.internationalPrefix;
+    }
+    
+    if (possibleCountryIddPrefix == nil)
+    {
+        possibleCountryIddPrefix = @"NonMatch";
+    }
+    
+    /** @type {i18n.phonenumbers.PhoneNumber.CountryCodeSource} */
+    NBECountryCodeSource countryCodeSource = [self maybeStripInternationalPrefixAndNormalize:&fullNumber
+                                                                           possibleIddPrefix:possibleCountryIddPrefix];
+    
+    if (keepRawInput)
+    {
+        (*phoneNumber).countryCodeSource = [NSNumber numberWithInt:countryCodeSource];
+    }
+    
+    if (countryCodeSource != NBECountryCodeSourceFROM_DEFAULT_COUNTRY)
+    {
+        if (fullNumber.length <= MIN_LENGTH_FOR_NSN_)
+        {
+            @throw [NSException exceptionWithName:@"TOO_SHORT_AFTER_IDD"
+                                           reason:[NSString stringWithFormat:@"TOO_SHORT_AFTER_IDD:%@", fullNumber]
+                                         userInfo:nil];
+        }
+        
+        NSNumber *potentialCountryCode = [self extractCountryCode:fullNumber nationalNumber:nationalNumber];
+        
+        if (![potentialCountryCode isEqualToNumber:@0])
+        {
+            (*phoneNumber).countryCode = potentialCountryCode;
+            return potentialCountryCode;
+        }
+        
+        // If this fails, they must be using a strange country calling code that we
+        // don't recognize, or that doesn't exist.
+        @throw [NSException exceptionWithName:@"INVALID_COUNTRY_CODE"
+                                       reason:[NSString stringWithFormat:@"INVALID_COUNTRY_CODE:%@", potentialCountryCode]
+                                     userInfo:nil];
+    }
+    else if (defaultRegionMetadata != nil)
+    {
+        // Check to see if the number starts with the country calling code for the
+        // default region. If so, we remove the country calling code, and do some
+        // checks on the validity of the number before and after.
+        NSNumber *defaultCountryCode = defaultRegionMetadata.countryCode;
+        NSString *defaultCountryCodeString = [NSString stringWithFormat:@"%@", defaultCountryCode];
+        NSString *normalizedNumber = [fullNumber copy];
+        
+        if ([normalizedNumber hasPrefix:defaultCountryCodeString])
+        {
+            NSString *potentialNationalNumber = [normalizedNumber substringFromIndex:defaultCountryCodeString.length];
+            NBPhoneNumberDesc *generalDesc = defaultRegionMetadata.generalDesc;
+            
+            NSString *validNumberPattern = generalDesc.nationalNumberPattern;
+            // Passing null since we don't need the carrier code.
+            [self maybeStripNationalPrefixAndCarrierCode:&potentialNationalNumber metadata:defaultRegionMetadata carrierCode:nil];
+            
+            NSString *potentialNationalNumberStr = [potentialNationalNumber copy];
+            NSString *possibleNumberPattern = generalDesc.possibleNumberPattern;
+            // If the number was not valid before but is valid now, or if it was too
+            // long before, we consider the number with the country calling code
+            // stripped to be a better result and keep that instead.
+            if ((![self matchesEntirely:validNumberPattern string:fullNumber] &&
+                 [self matchesEntirely:validNumberPattern string:potentialNationalNumberStr]) ||
+                [self testNumberLengthAgainstPattern:possibleNumberPattern number:fullNumber] == NBEValidationResultTOO_LONG)
+            {
+                (*nationalNumber) = [(*nationalNumber) stringByAppendingString:potentialNationalNumberStr];
+                if (keepRawInput)
+                {
+                    (*phoneNumber).countryCodeSource = [NSNumber numberWithInt:NBECountryCodeSourceFROM_NUMBER_WITHOUT_PLUS_SIGN];
+                }
+                (*phoneNumber).countryCode = defaultCountryCode;
+                return defaultCountryCode;
+            }
+        }
+    }
+    // No country calling code present.
+    (*phoneNumber).countryCode = @0;
+    return @0;
+}
+
+
+/**
+ * Strips the IDD from the start of the number if present. Helper function used
+ * by maybeStripInternationalPrefixAndNormalize.
+ *
+ * @param {!RegExp} iddPattern the regular expression for the international
+ *     prefix.
+ * @param {!goog.string.StringBuffer} number the phone number that we wish to
+ *     strip any international dialing prefix from.
+ * @return {boolean} NO if an international prefix was present.
+ * @private
+ */
+- (BOOL)parsePrefixAsIdd:(NSString*)iddPattern sourceString:(NSString**)number
+{
+    if (number == NULL)
+    {
+        return NO;
+    }
+    
+    NSString *numberStr = [(*number) copy];
+    
+    if ([self stringPositionByRegex:numberStr regex:iddPattern] == 0)
+    {
+        NSTextCheckingResult *matched = [[self matchesByRegex:numberStr regex:iddPattern] objectAtIndex:0];
+        NSString *matchedString = [numberStr substringWithRange:matched.range];
+        NSUInteger matchEnd = matchedString.length;
+        NSString *remainString = [numberStr substringFromIndex:matchEnd];
+        
+        NSRegularExpression *currentPattern = self.CAPTURING_DIGIT_PATTERN;
+        NSArray *matchedGroups = [currentPattern matchesInString:remainString options:0 range:NSMakeRange(0, remainString.length)];
+        
+        if (matchedGroups && [matchedGroups count] > 0 && [matchedGroups objectAtIndex:0] != nil)
+        {
+            NSString *digitMatched = [remainString substringWithRange:((NSTextCheckingResult*)[matchedGroups objectAtIndex:0]).range];
+            if (digitMatched.length > 0)
+            {
+                NSString *normalizedGroup = [self normalizeDigitsOnly:digitMatched];
+                if ([normalizedGroup isEqualToString:@"0"]) {
+                    return NO;
+                }
+            }
+        }
+        
+        (*number) = [remainString copy];
+        return YES;
+    }
+    
+    return NO;
+}
+
+
+/**
+ * Strips any international prefix (such as +, 00, 011) present in the number
+ * provided, normalizes the resulting number, and indicates if an international
+ * prefix was present.
+ *
+ * @param {!goog.string.StringBuffer} number the non-normalized telephone number
+ *     that we wish to strip any international dialing prefix from.
+ * @param {string} possibleIddPrefix the international direct dialing prefix
+ *     from the region we think this number may be dialed in.
+ * @return {CountryCodeSource} the corresponding
+ *     CountryCodeSource if an international dialing prefix could be removed
+ *     from the number, otherwise CountryCodeSource.FROM_DEFAULT_COUNTRY if
+ *     the number did not seem to be in international format.
+ */
+- (NBECountryCodeSource)maybeStripInternationalPrefixAndNormalize:(NSString**)numberStr possibleIddPrefix:(NSString*)possibleIddPrefix error:(NSError**)error
+{
+    if (numberStr == NULL)
+    {
+        return 0;
+    }
+    
+    NBECountryCodeSource res = 0;
+    @try {
+        res = [self maybeStripInternationalPrefixAndNormalize:numberStr possibleIddPrefix:possibleIddPrefix];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+- (NBECountryCodeSource)maybeStripInternationalPrefixAndNormalize:(NSString**)numberStr possibleIddPrefix:(NSString*)possibleIddPrefix
+{
+    if (numberStr == NULL || (*numberStr).length == 0)
+    {
+        return NBECountryCodeSourceFROM_DEFAULT_COUNTRY;
+    }
+    
+    // Check to see if the number begins with one or more plus signs.
+    if ([self isStartingStringByRegex:(*numberStr) regex:self.LEADING_PLUS_CHARS_PATTERN_])
+    {
+        (*numberStr) = [self replaceStringByRegex:(*numberStr) regex:self.LEADING_PLUS_CHARS_PATTERN_ withTemplate:@""];
+        // Can now normalize the rest of the number since we've consumed the '+'
+        // sign at the start.
+        (*numberStr) = [self normalizePhoneNumber:(*numberStr)];
+        return NBECountryCodeSourceFROM_NUMBER_WITH_PLUS_SIGN;
+    }
+    
+    // Attempt to parse the first digits as an international prefix.
+    NSString *iddPattern = [possibleIddPrefix copy];
+    [self normalizeSB:numberStr];
+    
+    return [self parsePrefixAsIdd:iddPattern sourceString:numberStr] ? NBECountryCodeSourceFROM_NUMBER_WITH_IDD : NBECountryCodeSourceFROM_DEFAULT_COUNTRY;
+}
+
+
+/**
+ * Strips any national prefix (such as 0, 1) present in the number provided.
+ *
+ * @param {!goog.string.StringBuffer} number the normalized telephone number
+ *     that we wish to strip any national dialing prefix from.
+ * @param {i18n.phonenumbers.PhoneMetadata} metadata the metadata for the
+ *     region that we think this number is from.
+ * @param {goog.string.StringBuffer} carrierCode a place to insert the carrier
+ *     code if one is extracted.
+ * @return {boolean} NO if a national prefix or carrier code (or both) could
+ *     be extracted.
+ */
+- (BOOL)maybeStripNationalPrefixAndCarrierCode:(NSString**)number metadata:(NBPhoneMetaData*)metadata carrierCode:(NSString**)carrierCode error:(NSError**)error
+{
+    if (number == NULL)
+    {
+        return NO;
+    }
+    
+    BOOL res = NO;
+    @try {
+        res = [self maybeStripNationalPrefixAndCarrierCode:number metadata:metadata carrierCode:carrierCode];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+
+- (BOOL)maybeStripNationalPrefixAndCarrierCode:(NSString**)number metadata:(NBPhoneMetaData*)metadata carrierCode:(NSString**)carrierCode
+{
+    if (number == NULL)
+    {
+        return NO;
+    }
+    
+    NSString *numberStr = [(*number) copy];
+    NSUInteger numberLength = numberStr.length;
+    NSString *possibleNationalPrefix = metadata.nationalPrefixForParsing;
+    
+    if (numberLength == 0 || [self hasValue:possibleNationalPrefix] == NO)
+    {
+        // Early return for numbers of zero length.
+        return NO;
+    }
+    
+    // Attempt to parse the first digits as a national prefix.
+    NSString *prefixPattern = [NSString stringWithFormat:@"^(?:%@)", possibleNationalPrefix];
+    NSError *error = nil;
+    NSRegularExpression *currentPattern = [NSRegularExpression regularExpressionWithPattern:prefixPattern
+                                                                                    options:0 error:&error];
+    
+    NSArray *prefixMatcher = [currentPattern matchesInString:numberStr options:0 range:NSMakeRange(0, numberLength)];
+    if (prefixMatcher && [prefixMatcher count] > 0)
+    {
+        NSString *nationalNumberRule = metadata.generalDesc.nationalNumberPattern;
+        NSTextCheckingResult *firstMatch = [prefixMatcher objectAtIndex:0];
+        NSString *firstMatchString = [numberStr substringWithRange:firstMatch.range];
+        
+        // prefixMatcher[numOfGroups] == null implies nothing was captured by the
+        // capturing groups in possibleNationalPrefix; therefore, no transformation
+        // is necessary, and we just remove the national prefix.
+        NSUInteger numOfGroups = firstMatch.numberOfRanges - 1;
+        NSString *transformRule = metadata.nationalPrefixTransformRule;
+        NSString *transformedNumber = @"";
+        NSRange firstRange = [firstMatch rangeAtIndex:numOfGroups];
+        NSString *firstMatchStringWithGroup = (firstRange.location != NSNotFound && firstRange.location < numberStr.length) ? [numberStr substringWithRange:firstRange] : nil;
+        BOOL noTransform = (transformRule == nil || transformRule.length == 0 || [self hasValue:firstMatchStringWithGroup] == NO);
+        
+        if (noTransform)
+        {
+            transformedNumber = [numberStr substringFromIndex:firstMatchString.length];
+        }
+        else
+        {
+            transformedNumber = [self replaceFirstStringByRegex:numberStr regex:prefixPattern withTemplate:transformRule];
+        }
+        // If the original number was viable, and the resultant number is not,
+        // we return.
+        if ([self hasValue:nationalNumberRule ] && [self matchesEntirely:nationalNumberRule string:numberStr] &&
+            [self matchesEntirely:nationalNumberRule string:transformedNumber] == NO)
+        {
+            return NO;
+        }
+        
+        if ((noTransform && numOfGroups > 0 && [self hasValue:firstMatchStringWithGroup]) || (!noTransform && numOfGroups > 1))
+        {
+            if (carrierCode != NULL && (*carrierCode) != nil)
+            {
+                (*carrierCode) = [(*carrierCode) stringByAppendingString:firstMatchStringWithGroup];
+            }
+        }
+        else if ((noTransform && numOfGroups > 0 && [self hasValue:firstMatchString]) || (!noTransform && numOfGroups > 1))
+        {
+            if (carrierCode != NULL && (*carrierCode) != nil)
+            {
+                (*carrierCode) = [(*carrierCode) stringByAppendingString:firstMatchString];
+            }
+        }
+        
+        (*number) = transformedNumber;
+        return YES;
+    }
+    return NO;
+}
+
+
+/**
+ * Strips any extension (as in, the part of the number dialled after the call is
+ * connected, usually indicated with extn, ext, x or similar) from the end of
+ * the number, and returns it.
+ *
+ * @param {!goog.string.StringBuffer} number the non-normalized telephone number
+ *     that we wish to strip the extension from.
+ * @return {string} the phone extension.
+ */
+- (NSString*)maybeStripExtension:(NSString**)number
+{
+    if (number == NULL)
+    {
+        return @"";
+    }
+    
+    NSString *numberStr = [(*number) copy];
+    NSInteger mStart = [self stringPositionByRegex:numberStr regex:self.EXTN_PATTERN_];
+    
+    // If we find a potential extension, and the number preceding this is a viable
+    // number, we assume it is an extension.
+    if (mStart >= 0 && [self isViablePhoneNumber:[numberStr substringWithRange:NSMakeRange(0, mStart)]])
+    {
+        // The numbers are captured into groups in the regular expression.
+        NSTextCheckingResult *firstMatch = [self matcheFirstByRegex:numberStr regex:self.EXTN_PATTERN_];
+        NSUInteger matchedGroupsLength = [firstMatch numberOfRanges];
+        for (NSUInteger i=1; i<matchedGroupsLength; i++)
+        {
+            NSRange curRange = [firstMatch rangeAtIndex:i];
+            if (curRange.location != NSNotFound && curRange.location < numberStr.length)
+            {
+                NSString *matchString = [(*number) substringWithRange:curRange];
+                // We go through the capturing groups until we find one that captured
+                // some digits. If none did, then we will return the empty string.
+                NSString *tokenedString = [numberStr substringWithRange:NSMakeRange(0, mStart)];
+                (*number) = @"";
+                (*number) = [(*number) stringByAppendingString:tokenedString];
+                
+                return matchString;
+            }
+        }
+    }
+    
+    return @"";
+}
+
+
+/**
+ * Checks to see that the region code used is valid, or if it is not valid, that
+ * the number to parse starts with a + symbol so that we can attempt to infer
+ * the region from the number.
+ * @param {string} numberToParse number that we are attempting to parse.
+ * @param {?string} defaultRegion region that we are expecting the number to be
+ *     from.
+ * @return {boolean} NO if it cannot use the region provided and the region
+ *     cannot be inferred.
+ * @private
+ */
+- (BOOL)checkRegionForParsing:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion
+{
+    // If the number is nil or empty, we can't infer the region.
+    return [self isValidRegionCode:defaultRegion] ||
+    (numberToParse != nil && numberToParse.length > 0 && [self isStartingStringByRegex:numberToParse regex:self.LEADING_PLUS_CHARS_PATTERN_]);
+}
+
+
+/**
+ * Parses a string and returns it in proto buffer format. This method will throw
+ * a {@link i18n.phonenumbers.Error} if the number is not considered to be a
+ * possible number. Note that validation of whether the number is actually a
+ * valid number for a particular region is not performed. This can be done
+ * separately with {@link #isValidNumber}.
+ *
+ * @param {?string} numberToParse number that we are attempting to parse. This
+ *     can contain formatting such as +, ( and -, as well as a phone number
+ *     extension. It can also be provided in RFC3966 format.
+ * @param {?string} 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 of the default region supplied. If the number is
+ *     guaranteed to start with a '+' followed by the country calling code, then
+ *     'ZZ' or nil can be supplied.
+ * @return {i18n.phonenumbers.PhoneNumber} a phone number proto buffer filled
+ *     with the parsed number.
+ * @throws {i18n.phonenumbers.Error} if the string is not considered to be a
+ *     viable phone number or if no default region was supplied and the number
+ *     is not in international format (does not start with +).
+ */
+- (NBPhoneNumber*)parse:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion
+{
+    return [self parseHelper:numberToParse defaultRegion:defaultRegion keepRawInput:NO checkRegion:YES];
+}
+
+
+- (NBPhoneNumber*)parse:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion error:(NSError**)error
+{
+    NBPhoneNumber *phoneNumber = nil;
+    
+    @try {
+        phoneNumber = [self parseHelper:numberToParse defaultRegion:defaultRegion keepRawInput:NO checkRegion:YES];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    
+    return phoneNumber;
+}
+
+/**
+ * Parses a string using the phone's carrier region (when available, ZZ otherwise).
+ * This uses the country the sim card in the phone is registered with.
+ * For example if you have an AT&T sim card but are in Europe, this will parse the
+ * number using +1 (AT&T is a US Carrier) as the default country code.
+ * This also works for CDMA phones which don't have a sim card.
+ */
+- (NBPhoneNumber*)parseWithPhoneCarrierRegion:(NSString*)numberToParse error:(NSError**)error
+{
+	NSString *(^ISOCountryCodeByCarrier)() = ^() {
+		CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
+		CTCarrier *carrier = [networkInfo subscriberCellularProvider];
+		return [carrier isoCountryCode];
+	};
+	NSString *isoCode = ISOCountryCodeByCarrier();
+	
+	if (!isoCode) {
+		isoCode = @"ZZ";
+	}
+	
+	return [self parse:numberToParse defaultRegion:isoCode];
+}
+
+
+/**
+ * Parses a string and returns it in proto buffer format. This method differs
+ * from {@link #parse} in that it always populates the raw_input field of the
+ * protocol buffer with numberToParse as well as the country_code_source field.
+ *
+ * @param {string} numberToParse number that we are attempting to parse. This
+ *     can contain formatting such as +, ( and -, as well as a phone number
+ *     extension.
+ * @param {?string} 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 calling code for the number in this
+ *     case would be stored as that of the default region supplied.
+ * @return {i18n.phonenumbers.PhoneNumber} a phone number proto buffer filled
+ *     with the parsed number.
+ * @throws {i18n.phonenumbers.Error} if the string is not considered to be a
+ *     viable phone number or if no default region was supplied.
+ */
+- (NBPhoneNumber*)parseAndKeepRawInput:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion error:(NSError**)error
+{
+    NBPhoneNumber *res = nil;
+    @try {
+        res = [self parseAndKeepRawInput:numberToParse defaultRegion:defaultRegion];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+- (NBPhoneNumber*)parseAndKeepRawInput:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion
+{
+    if ([self isValidRegionCode:defaultRegion] == NO)
+    {
+        if (numberToParse.length > 0 && [numberToParse hasPrefix:@"+"] == NO)
+        {
+            NSException* metaException = [NSException exceptionWithName:@"INVALID_COUNTRY_CODE"
+                                                                 reason:[NSString stringWithFormat:@"Invalid country code:%@", numberToParse]
+                                                               userInfo:nil];
+            @throw metaException;
+        }
+    }
+    return [self parseHelper:numberToParse defaultRegion:defaultRegion keepRawInput:YES checkRegion:YES];
+}
+
+
+/**
+ * Parses a string and returns it in proto buffer format. This method is the
+ * same as the public {@link #parse} method, with the exception that it allows
+ * the default region to be nil, for use by {@link #isNumberMatch}.
+ *
+ * @param {?string} numberToParse number that we are attempting to parse. This
+ *     can contain formatting such as +, ( and -, as well as a phone number
+ *     extension.
+ * @param {?string} 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 calling code for the number in this
+ *     case would be stored as that of the default region supplied.
+ * @param {boolean} keepRawInput whether to populate the raw_input field of the
+ *     phoneNumber with numberToParse.
+ * @param {boolean} checkRegion should be set to NO if it is permitted for
+ *     the default coregion to be nil or unknown ('ZZ').
+ * @return {i18n.phonenumbers.PhoneNumber} a phone number proto buffer filled
+ *     with the parsed number.
+ * @throws {i18n.phonenumbers.Error}
+ * @private
+ */
+- (NBPhoneNumber*)parseHelper:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion
+                 keepRawInput:(BOOL)keepRawInput checkRegion:(BOOL)checkRegion error:(NSError**)error
+{
+    NBPhoneNumber *res = nil;
+    @try {
+        res = [self parseHelper:numberToParse defaultRegion:defaultRegion keepRawInput:keepRawInput checkRegion:checkRegion];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+- (NBPhoneNumber*)parseHelper:(NSString*)numberToParse defaultRegion:(NSString*)defaultRegion
+                 keepRawInput:(BOOL)keepRawInput checkRegion:(BOOL)checkRegion
+{
+    if (numberToParse == nil)
+    {
+        @throw [NSException exceptionWithName:@"NOT_A_NUMBER" reason:[NSString stringWithFormat:@"NOT_A_NUMBER:%@", numberToParse] userInfo:nil];
+    }
+    else if (numberToParse.length > MAX_INPUT_STRING_LENGTH_)
+    {
+        @throw [NSException exceptionWithName:@"TOO_LONG" reason:[NSString stringWithFormat:@"TOO_LONG:%@", numberToParse] userInfo:nil];
+    }
+    
+    NSString *nationalNumber = @"";
+    [self buildNationalNumberForParsing:numberToParse nationalNumber:&nationalNumber];
+    
+    if ([self isViablePhoneNumber:nationalNumber] == NO)
+    {
+        @throw [NSException exceptionWithName:@"NOT_A_NUMBER" reason:[NSString stringWithFormat:@"NOT_A_NUMBER:%@", nationalNumber] userInfo:nil];
+    }
+    
+    // Check the region supplied is valid, or that the extracted number starts
+    // with some sort of + sign so the number's region can be determined.
+    if (checkRegion && [self checkRegionForParsing:nationalNumber defaultRegion:defaultRegion] == NO)
+    {
+        @throw [NSException exceptionWithName:@"INVALID_COUNTRY_CODE" reason:[NSString stringWithFormat:@"INVALID_COUNTRY_CODE:%@", defaultRegion] userInfo:nil];
+    }
+    
+    NBPhoneNumber *phoneNumber = [[NBPhoneNumber alloc] init];
+    if (keepRawInput)
+    {
+        phoneNumber.rawInput = [numberToParse copy];
+    }
+    // Attempt to parse extension first, since it doesn't require region-specific
+    // data and we want to have the non-normalised number here.
+    NSString *extension = [self maybeStripExtension:&nationalNumber];
+    if (extension.length > 0)
+    {
+        phoneNumber.extension = [extension copy];
+    }
+    
+    NBPhoneMetaData *regionMetadata = [self getMetadataForRegion:defaultRegion];
+    // Check to see if the number is given in international format so we know
+    // whether this number is from the default region or not.
+    NSString *normalizedNationalNumber = @"";
+    NSNumber *countryCode = @0;
+    NSString *nationalNumberStr = [nationalNumber copy];
+    @try {
+        countryCode = [self maybeExtractCountryCode:nationalNumberStr
+                                           metadata:regionMetadata
+                                     nationalNumber:&normalizedNationalNumber
+                                       keepRawInput:keepRawInput
+                                        phoneNumber:&phoneNumber];
+    }
+    @catch (NSException *e) {
+        if ([e.name isEqualToString:@"INVALID_COUNTRY_CODE"] && [self stringPositionByRegex:nationalNumberStr
+                                                                                      regex:self.LEADING_PLUS_CHARS_PATTERN_] >= 0)
+        {
+            // Strip the plus-char, and try again.
+            nationalNumberStr = [self replaceStringByRegex:nationalNumberStr regex:self.LEADING_PLUS_CHARS_PATTERN_ withTemplate:@""];
+            countryCode = [self maybeExtractCountryCode:nationalNumberStr
+                                               metadata:regionMetadata
+                                         nationalNumber:&normalizedNationalNumber
+                                           keepRawInput:keepRawInput
+                                            phoneNumber:&phoneNumber];
+            if ([countryCode isEqualToNumber:@0])
+            {
+                @throw [NSException exceptionWithName:e.name
+                                               reason:[NSString stringWithFormat:@"%@:%@", e.name, nationalNumberStr]
+                                             userInfo:nil];
+            }
+        }
+        else
+        {
+            @throw e;
+        }
+    }
+    
+    if (![countryCode isEqualToNumber:@0])
+    {
+        NSString *phoneNumberRegion = [self getRegionCodeForCountryCode:countryCode];
+        if (phoneNumberRegion != defaultRegion)
+        {
+            // Metadata cannot be nil because the country calling code is valid.
+            regionMetadata = [self getMetadataForRegionOrCallingCode:countryCode regionCode:phoneNumberRegion];
+        }
+    }
+    else
+    {
+        // If no extracted country calling code, use the region supplied instead.
+        // The national number is just the normalized version of the number we were
+        // given to parse.
+        [self normalizeSB:&nationalNumber];
+        normalizedNationalNumber = [normalizedNationalNumber stringByAppendingString:nationalNumber];
+        
+        if (defaultRegion != nil)
+        {
+            countryCode = regionMetadata.countryCode;
+            phoneNumber.countryCode = countryCode;
+        }
+        else if (keepRawInput)
+        {
+            [phoneNumber clearCountryCodeSource];
+        }
+    }
+    
+    if (normalizedNationalNumber.length < MIN_LENGTH_FOR_NSN_)
+    {
+        @throw [NSException exceptionWithName:@"TOO_SHORT_NSN"
+                                       reason:[NSString stringWithFormat:@"TOO_SHORT_NSN:%@", normalizedNationalNumber]
+                                     userInfo:nil];
+    }
+    
+    if (regionMetadata != nil)
+    {
+        NSString *carrierCode = @"";
+        [self maybeStripNationalPrefixAndCarrierCode:&normalizedNationalNumber metadata:regionMetadata carrierCode:&carrierCode];
+        
+        if (keepRawInput)
+        {
+            phoneNumber.PreferredDomesticCarrierCode = [carrierCode copy];
+        }
+    }
+    
+    NSString *normalizedNationalNumberStr = [normalizedNationalNumber copy];
+    
+    NSUInteger lengthOfNationalNumber = normalizedNationalNumberStr.length;
+    if (lengthOfNationalNumber < MIN_LENGTH_FOR_NSN_)
+    {
+        @throw [NSException exceptionWithName:@"TOO_SHORT_NSN"
+                                       reason:[NSString stringWithFormat:@"TOO_SHORT_NSN:%@", normalizedNationalNumberStr]
+                                     userInfo:nil];
+    }
+    
+    if (lengthOfNationalNumber > MAX_LENGTH_FOR_NSN_)
+    {
+        @throw [NSException exceptionWithName:@"TOO_LONG"
+                                       reason:[NSString stringWithFormat:@"TOO_LONG:%@", normalizedNationalNumberStr]
+                                     userInfo:nil];
+    }
+    
+    if ([normalizedNationalNumberStr hasPrefix:@"0"])
+    {
+        phoneNumber.italianLeadingZero = YES;
+    }
+    
+    phoneNumber.nationalNumber = [NSNumber numberWithLongLong:(UInt64)[normalizedNationalNumberStr longLongValue]];
+    return phoneNumber;
+}
+
+
+/**
+ * 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.
+ *
+ * @param {?string} numberToParse number that we are attempting to parse. This
+ *     can contain formatting such as +, ( and -, as well as a phone number
+ *     extension.
+ * @param {!goog.string.StringBuffer} nationalNumber a string buffer for storing
+ *     the national significant number.
+ * @private
+ */
+- (void)buildNationalNumberForParsing:(NSString*)numberToParse nationalNumber:(NSString**)nationalNumber
+{
+    if (nationalNumber == NULL)
+        return;
+    
+    NSInteger indexOfPhoneContext = [self indexOfStringByString:numberToParse target:RFC3966_PHONE_CONTEXT_];
+    if (indexOfPhoneContext > 0)
+    {
+        NSUInteger 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 characterAtIndex:phoneContextStart] == '+')
+        {
+            // 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.
+            NSRange foundRange = [numberToParse rangeOfString:@";" options:NSLiteralSearch range:NSMakeRange(phoneContextStart, numberToParse.length - phoneContextStart)];
+            if (foundRange.location != NSNotFound)
+            {
+                NSRange subRange = NSMakeRange(phoneContextStart, foundRange.location - phoneContextStart);
+                (*nationalNumber) = [(*nationalNumber) stringByAppendingString:[numberToParse substringWithRange:subRange]];
+            }
+            else
+            {
+                (*nationalNumber) = [(*nationalNumber) stringByAppendingString:[numberToParse substringFromIndex: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.
+        NSUInteger rfc3966Start = [self indexOfStringByString:numberToParse target:RFC3966_PREFIX_] + RFC3966_PREFIX_.length;
+        NSString *subString = [numberToParse substringWithRange:NSMakeRange(rfc3966Start, indexOfPhoneContext - rfc3966Start)];
+        (*nationalNumber) = [(*nationalNumber) stringByAppendingString:subString];
+    }
+    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) = [(*nationalNumber) stringByAppendingString:[self 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,
+    NSString *nationalNumberStr = [(*nationalNumber) copy];
+    NSInteger indexOfIsdn = [self indexOfStringByString:nationalNumberStr target:RFC3966_ISDN_SUBADDRESS_];
+    if (indexOfIsdn > 0)
+    {
+        (*nationalNumber) = @"";
+        (*nationalNumber) = [(*nationalNumber) stringByAppendingString:[nationalNumberStr substringWithRange:NSMakeRange(0, 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 and any extension present are the same. Returns NSN_MATCH
+ * if either or both has no region specified, and the NSNs and extensions are
+ * the same. Returns SHORT_NSN_MATCH if either or both has no region specified,
+ * or the region specified is the same, and one NSN could be a shorter version
+ * of the other number. This includes the case where one has an extension
+ * specified, and the other does not. Returns NO_MATCH otherwise. For example,
+ * the numbers +1 345 657 1234 and 657 1234 are a SHORT_NSN_MATCH. The numbers
+ * +1 345 657 1234 and 345 657 are a NO_MATCH.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber|string} firstNumberIn first number to
+ *     compare. If it is a string it can contain formatting, and can have
+ *     country calling code specified with + at the start.
+ * @param {i18n.phonenumbers.PhoneNumber|string} secondNumberIn second number to
+ *     compare. If it is a string it can contain formatting, and can have
+ *     country calling code specified with + at the start.
+ * @return {MatchType} NOT_A_NUMBER, NO_MATCH,
+ *     SHORT_NSN_MATCH, NSN_MATCH or EXACT_MATCH depending on the level of
+ *     equality of the two numbers, described in the method definition.
+ */
+- (NBEMatchType)isNumberMatch:(id)firstNumberIn second:(id)secondNumberIn error:(NSError**)error
+{
+    NBEMatchType res = 0;
+    @try {
+        res = [self isNumberMatch:firstNumberIn second:secondNumberIn];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+- (NBEMatchType)isNumberMatch:(id)firstNumberIn second:(id)secondNumberIn
+{
+    
+    // If the input arguements are strings parse them to a proto buffer format.
+    // Else make copies of the phone numbers so that the numbers passed in are not
+    // edited.
+    /** @type {i18n.phonenumbers.PhoneNumber} */
+    NBPhoneNumber *firstNumber = nil, *secondNumber = nil;
+    if ([firstNumberIn isKindOfClass:[NSString class]])
+    {
+        // First see if the first number has an implicit country calling code, by
+        // attempting to parse it.
+        @try {
+            firstNumber = [self parse:firstNumberIn defaultRegion:UNKNOWN_REGION_];
+        }
+        @catch (NSException *e) {
+            if ([e.name isEqualToString:@"INVALID_COUNTRY_CODE"] == NO)
+            {
+                return NBEMatchTypeNOT_A_NUMBER;
+            }
+            // The first number has no country calling code. EXACT_MATCH is no longer
+            // possible. We parse it as if the region was the same as that for the
+            // second number, and if EXACT_MATCH is returned, we replace this with
+            // NSN_MATCH.
+            if ([secondNumberIn isKindOfClass:[NSString class]] == NO)
+            {
+                NSString *secondNumberRegion = [self getRegionCodeForCountryCode:((NBPhoneNumber*)secondNumberIn).countryCode];
+                if (secondNumberRegion != UNKNOWN_REGION_)
+                {
+                    @try {
+                        firstNumber = [self parse:firstNumberIn defaultRegion:secondNumberRegion];
+                    }
+                    @catch (NSException *e2) {
+                        return NBEMatchTypeNOT_A_NUMBER;
+                    }
+                    
+                    NBEMatchType match = [self isNumberMatch:firstNumber second:secondNumberIn];
+                    if (match == NBEMatchTypeEXACT_MATCH)
+                    {
+                        return NBEMatchTypeNSN_MATCH;
+                    }
+                    return match;
+                }
+            }
+            // If the second number is a string or doesn't have a valid country
+            // calling code, we parse the first number without country calling code.
+            @try {
+                firstNumber = [self parseHelper:firstNumberIn defaultRegion:nil keepRawInput:NO checkRegion:NO];
+            }
+            @catch (NSException *e2)  {
+                return NBEMatchTypeNOT_A_NUMBER;
+            }
+        }
+    }
+    else
+    {
+        firstNumber = [firstNumberIn copy];
+    }
+    
+    if ([secondNumberIn isKindOfClass:[NSString class]])
+    {
+        @try {
+            secondNumber = [self parse:secondNumberIn defaultRegion:UNKNOWN_REGION_];
+            return [self isNumberMatch:firstNumberIn second:secondNumber];
+        }
+        @catch (NSException *e2) {
+            if ([e2.name isEqualToString:@"INVALID_COUNTRY_CODE"] == NO)
+            {
+                return NBEMatchTypeNOT_A_NUMBER;
+            }
+            return [self isNumberMatch:secondNumberIn second:firstNumber];
+        }
+    }
+    else
+    {
+        secondNumber = [secondNumberIn copy];
+    }
+    
+    // First clear raw_input, country_code_source and
+    // preferred_domestic_carrier_code fields and any empty-string extensions so
+    // that we can use the proto-buffer equality method.
+    firstNumber.rawInput = @"";
+    [firstNumber clearCountryCodeSource];
+    firstNumber.PreferredDomesticCarrierCode = @"";
+    
+    secondNumber.rawInput = @"";
+    [secondNumber clearCountryCodeSource];
+    secondNumber.PreferredDomesticCarrierCode = @"";
+    
+    if (firstNumber.extension != nil && firstNumber.extension.length == 0)
+    {
+        firstNumber.extension = nil;
+    }
+    
+    if (secondNumber.extension != nil && secondNumber.extension.length == 0)
+    {
+        secondNumber.extension = nil;
+    }
+    
+    // Early exit if both had extensions and these are different.
+    if ([self hasValue:firstNumber.extension] && [self hasValue:secondNumber.extension] &&
+        [firstNumber.extension isEqualToString:secondNumber.extension] == NO)
+    {
+        return NBEMatchTypeNO_MATCH;
+    }
+    
+    NSNumber *firstNumberCountryCode = firstNumber.countryCode;
+    NSNumber *secondNumberCountryCode = secondNumber.countryCode;
+    
+    // Both had country_code specified.
+    if (![firstNumberCountryCode isEqualToNumber:@0] && ![secondNumberCountryCode isEqualToNumber:@0])
+    {
+        if ([firstNumber isEqual:secondNumber])
+        {
+            return NBEMatchTypeEXACT_MATCH;
+        }
+        else if ([firstNumberCountryCode isEqualToNumber:secondNumberCountryCode] && [self isNationalNumberSuffixOfTheOther:firstNumber second:secondNumber])
+        {
+            // A SHORT_NSN_MATCH occurs if there is a difference because of the
+            // presence or absence of an 'Italian leading zero', the presence or
+            // absence of an extension, or one NSN being a shorter variant of the
+            // other.
+            return NBEMatchTypeSHORT_NSN_MATCH;
+        }
+        // This is not a match.
+        return NBEMatchTypeNO_MATCH;
+    }
+    // Checks cases where one or both country_code fields were not specified. To
+    // make equality checks easier, we first set the country_code fields to be
+    // equal.
+    firstNumber.countryCode = @0;
+    secondNumber.countryCode = @0;
+    // If all else was the same, then this is an NSN_MATCH.
+    if ([firstNumber isEqual:secondNumber])
+    {
+        return NBEMatchTypeNSN_MATCH;
+    }
+    
+    if ([self isNationalNumberSuffixOfTheOther:firstNumber second:secondNumber])
+    {
+        return NBEMatchTypeSHORT_NSN_MATCH;
+    }
+    return NBEMatchTypeNO_MATCH;
+}
+
+
+/**
+ * Returns NO when one national number is the suffix of the other or both are
+ * the same.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} firstNumber the first PhoneNumber
+ *     object.
+ * @param {i18n.phonenumbers.PhoneNumber} secondNumber the second PhoneNumber
+ *     object.
+ * @return {boolean} NO if one PhoneNumber is the suffix of the other one.
+ * @private
+ */
+- (BOOL)isNationalNumberSuffixOfTheOther:(NBPhoneNumber*)firstNumber second:(NBPhoneNumber*)secondNumber
+{
+    NSString *firstNumberNationalNumber = [NSString stringWithFormat:@"%@", firstNumber.nationalNumber];
+    NSString *secondNumberNationalNumber = [NSString stringWithFormat:@"%@", secondNumber.nationalNumber];
+    
+    // Note that endsWith returns NO if the numbers are equal.
+    return [firstNumberNationalNumber hasSuffix:secondNumberNationalNumber] ||
+    [secondNumberNationalNumber hasSuffix:firstNumberNationalNumber];
+}
+
+
+/**
+ * Returns NO if the number can be dialled from outside the region, or
+ * unknown. If the number can only be dialled from within the region, returns
+ * NO. Does not check the number is a valid number.
+ * TODO: Make this method public when we have enough metadata to make it
+ * worthwhile. Currently visible for testing purposes only.
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the phone-number for which we
+ *     want to know whether it is diallable from outside the region.
+ * @return {boolean} NO if the number can only be dialled from within the
+ *     country.
+ */
+- (BOOL)canBeInternationallyDialled:(NBPhoneNumber*)number error:(NSError**)error
+{
+    BOOL res = NO;
+    @try {
+        res = [self canBeInternationallyDialled:number];
+    }
+    @catch (NSException *exception) {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
+                                                             forKey:NSLocalizedDescriptionKey];
+        if (error != NULL)
+            (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
+    }
+    return res;
+}
+
+- (BOOL)canBeInternationallyDialled:(NBPhoneNumber*)number
+{
+    NBPhoneMetaData *metadata = [self getMetadataForRegion:[self getRegionCodeForNumber:number]];
+    if (metadata == nil)
+    {
+        // Note numbers belonging to non-geographical entities (e.g. +800 numbers)
+        // are always internationally diallable, and will be caught here.
+        return YES;
+    }
+    NSString *nationalSignificantNumber = [self getNationalSignificantNumber:number];
+    return [self isNumberMatchingDesc:nationalSignificantNumber numberDesc:metadata.noInternationalDialling] == NO;
+}
+
+
+/**
+ * Check whether the entire input sequence can be matched against the regular
+ * expression.
+ *
+ * @param {!RegExp|string} regex the regular expression to match against.
+ * @param {string} str the string to test.
+ * @return {boolean} NO if str can be matched entirely against regex.
+ * @private
+ */
+- (BOOL)matchesEntirely:(NSString*)regex string:(NSString*)str
+{
+    if ([regex rangeOfString:@"^"].location == NSNotFound)
+    {
+        regex = [NSString stringWithFormat:@"^(?:%@)$", regex];
+    }
+    
+    NSError *error = nil;
+    NSRegularExpression *currentPattern = [NSRegularExpression regularExpressionWithPattern:regex options:0 error:&error];
+    NSTextCheckingResult *matchResult = [currentPattern firstMatchInString:str options:0 range:NSMakeRange(0, str.length)];
+    
+    if (matchResult != nil)
+    {
+        NSString *founds = [str substringWithRange:matchResult.range];
+        
+        if ([founds isEqualToString:str])
+        {
+            return YES;
+        }
+    }
+    
+    return NO;
+}
+
+
+@end
