public function formatByPattern(PhoneNumber $number, $numberFormat, array $userDefinedFormats)
    {
        $countryCallingCode = $number->getCountryCode();
        $nationalSignificantNumber = $this->getNationalSignificantNumber($number);
        if (!$this->hasValidCountryCallingCode($countryCallingCode)) {
            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.
        $regionCode = $this->getRegionCodeForCountryCode($countryCallingCode);
        // Metadata cannot be null because the country calling code is valid
        $metadata = $this->getMetadataForRegionOrCallingCode($countryCallingCode, $regionCode);

        $formattedNumber = '';

        $formattingPattern = $this->chooseFormattingPatternForNumber($userDefinedFormats, $nationalSignificantNumber);
        if ($formattingPattern === null) {
            // If no pattern above is matched, we format the number as a whole.
            $formattedNumber .= $nationalSignificantNumber;
        } else {
            $numFormatCopy = new NumberFormat();
            // 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.
            $numFormatCopy->mergeFrom($formattingPattern);
            $nationalPrefixFormattingRule = $formattingPattern->getNationalPrefixFormattingRule();
            if (mb_strlen($nationalPrefixFormattingRule) > 0) {
                $nationalPrefix = $metadata->getNationalPrefix();
                if (mb_strlen($nationalPrefix) > 0) {
                    // Replace $NP with national prefix and $FG with the first group ($1).
                    $nationalPrefixFormattingRule = str_replace(array(static::NP_STRING, static::FG_STRING),
                        array($nationalPrefix, '$1'), $nationalPrefixFormattingRule);
                    $numFormatCopy->setNationalPrefixFormattingRule($nationalPrefixFormattingRule);
                } else {
                    // We don't want to have a rule for how to format the national prefix if there isn't one.
                    $numFormatCopy->clearNationalPrefixFormattingRule();
                }
            }
            $formattedNumber .= $this->formatNsnUsingPattern($nationalSignificantNumber, $numFormatCopy, $numberFormat);
        }
        $this->maybeAppendFormattedExtension($number, $metadata, $numberFormat, $formattedNumber);
        $this->prefixNumberWithCountryCallingCode($countryCallingCode, $numberFormat, $formattedNumber);
        return $formattedNumber;
    }