diff --git a/phone.br.inc b/phone.br.inc
index 16c95ed..1657b7d 100644
--- a/phone.br.inc
+++ b/phone.br.inc"	
@@ -4,141 +4,379 @@
  * @file
  * CCK Field for British phone numbers.
  */
-
 function phone_gb_metadata() {
   // These strings are translated using t() on output.
   return array(
     'label' => 'Phone Numbers - Great Britain - England (UK)',
-    'error' => '"%value" is not a valid British (UK) phone number<br>British Phone numbers should .... ',
+    'error' => '"%value" is not a valid British (UK) phone number<br>British Phone numbers should contain 9 or 10 digits after<br>the 0 trunk code or +44 country code.',
   );
 }
 
+/*
+    Accepts:
+        020 7000 7000
+        0207 000 7000
+        02070 007 000 #4567
+        0117 455 7777
+        01174 557 777
+        0175 061 8888
+        01750 618 888
+        01750 62555
+        01697 355 555
+        01697 73555
+        02030007000
+        02070008888
+        01215557777
+        01174007777
+        01750615777
+        0175062555
+        0169773555
+        01946755555
+        07788555777
+        07010001000
+        08005557777
+        0800555888
+        (020) 7000 7000
+        (0207) 000 7000
+        (01174) 557 777 #333
+        (01970) 234567 #0001
+        (0169) 772444
+        +44 207 000 7000
+        +44 2070 007000
+        +44 16973 55555
+        +44 1697 355 555
+        +441174 008 888 #333
+        +44 203 000 8000 #555
+        +441970234567
+        +44(0)1970234567
+        +44 1970 123 456
+        +44 (0)1970 234 456
+        +441174008888
+        +441174008888#333
+        +44 (0) 203 000 8000
+        +44(1970)234567
+        (+44) 1697 355 555
+        (+44 16973) 55555 #888
+        (+441970)234567
+        (+44) 2070 007 000
+        (+44 20) 3000 8000
+        (+44) (0) 207 000 7000
+        00 44 207 000 7000
+        00 44 16977 3555
+        00442030007777#555
+        00 (44) 1697 73555
+        (00 44) 203 000 8000
+        011 44 207 000 7000
+        011 (44) 20 7000 7000
+        011 44 1697 73555
+        011 44 (0)203 000 8000#222
+    "Be liberal in what you accept and strict in what you return."
+
+    Rejects:
+        06750 618888
+        06750 62555
+        060 5000 7000
+        00 33 20 00 70 00
+        01 69 77 35 55
+        05342030007777#555
+        02230007777
+        062300077
+        06230007777
+        0623000777788
+        (0197) 0123456 #01
+        +44 01970 123 456
+*/
+
 /**
- * Verifies that $phonenumber is a valid eleven-digit United Kingdom phone number
- *
- * Regular expression adapted from Amos Hurd's regex at RegExLib.com
+ * Verifies that $phonenumber is a United Kingdom phone number in a valid
+ * number range. Rejects numbers that are too long or too short or are in
+ * a non-valid range. Accepts a wide range of input formats and a number
+ * of different prefixes.
+ * created by @g1smd
  *
  * @param string $phonenumber
- * @return boolean Returns boolean FALSE if the phone number is not valid.
+ * @return boolean Returns boolean FALSE if the phone number is not valid
  */
-
 function valid_gb_phone_number($phonenumber) {
+    // Check if number entered matches a valid format
+    if (!valid_gb_phone_pattern($phonenumber)) {
+        return FALSE;
+    } else {
+        // Extract number parts: prefix, NSN, extension
+        $phonenumberPartsArray = (extract_gb_phone_parts($phonenumber));
+        if (empty($phonenumberPartsArray)) {
+            return FALSE;
+        } else {
+            $phonenumberNSN = $phonenumberPartsArray['NSN'];
+            // Check if NSN entered is in a valid range
+            if (!valid_gb_phone_range($phonenumberNSN)) {
+                return FALSE;
+            } else {
+                return TRUE;
+            }
+        }
+    }
+}
 
-  /*
-    Accepts:
-        +441970123456
-        +44(0)1970123456
-        +44 1970 123 456
-        +44 (0)1970 123 456
-        (01970) 123456 #0001
-    Rejects:
-        (+441970)123456
-        +44(1970)123456
-        +44 01970 123 456
-        (0197) 0123456 #01
-  */
-  $regex = "/
-    (
-        (^\+44\s?(\(0\))?\d{4}|^\(?0\d{4}\)?){1}\s?\d{3}\s?\d{3}  # 4 digit area code with optional +44 internationalisation or not, optional spaces and brackets.
-        |
-        (^\+44\s?(\(0\))?\d{3}|^\(?0\d{3}\)?){1}\s?\d{3}\s?\d{4}  # 3 digit area code with optional +44 internationalisation or not, optional spaces and brackets.
-        |
-        (^\+44\s?(\(0\))?\d{2}|^\(?0\d{2}\)?){1}\s?\d{4}\s?\d{4}  # 2 digit area code with optional +44 internationalisation or not, optional spaces and brackets.
-        |
-        (^\+44\s?(\(0\))?\d{1}|^\(?0\d{1}\)?){1}\s?\d{5}\s?\d{5}  # 1 digit area code with optional +44 internationalisation or not, optional spaces and brackets.        
-    )
-    (\s?\#\d*)?   # optional extension number shown with a hash divider
-  /x";
-
-  if (!preg_match($regex, $phonenumber)) {
-  	return FALSE;
-  }
-  else
-  {
-	return TRUE;
-  }
+/**
+ * Convert a valid United Kingdom phone number into standard +44 1970 123456 #001
+ * international format. Accepts a wide range of input formats and prefixes and
+ * re-formats the number taking into account the required 2+8, 3+7, 4+6, 4+5, 5+5,
+ * 5+4 and 3+6 formats by number range.
+ * created by @g1smd
+ *
+ * @param $phonenumber must be a valid nine or ten-digit number (with optional extension)
+ * @return string $phonenumber
+ */
+function format_gb_phone_number($phonenumber, $field = FALSE) {
+    $phonenumberPrefix = $phonenumberNSNraw = $phonenumberNSNformatted = $phonenumberExtension = '';
+
+    // Extract optional country prefix, NSN, and optional extension.
+    $phonenumberPartsArray = extract_gb_phone_parts($phonenumber);
+    if (!empty($phonenumberPartsArray)) {
+        $phonenumberNSN = $phonenumberPartsArray['NSN'];
+        if ($phonenumberNSN == null) {
+            return $phonenumber;
+        }
+        // Grab only the NSN part for formatting
+        // NSN part might include spaces, hyphens or ')' and will need to be removed
+        $arrayReplace = array(")", "-", " ");
+        $phonenumberNSN = trim(str_replace($arrayReplace, "", $phonenumberNSN));
+        // Format NSN part of GB number
+        $phonenumberNSNformatted = format_gb_nsn($phonenumberNSN);
+
+        // Set prefix as 44 or 0
+        if (isset($phonenumberPartsArray['prefix']) && $phonenumberPartsArray['prefix'] != null) {
+            $phonenumberPrefix = $phonenumberPartsArray['prefix'];
+    //  } else {
+    //      $phonenumberPrefix = "0";
+        }
+
+        // Extract extension
+        $phonenumberHasExtension = false;
+        $phonenumberExtension = null;
+        if (isset($phonenumberPartsArray['extension']) && $phonenumberPartsArray['extension'] != null) {
+            $phonenumberHasExtension = true;
+            $phonenumberExtension = " " . trim($phonenumberPartsArray['extension']);
+        }
+
+        // Add prefix back on to NSN
+        if ($field['phone_country_code']) {
+            // Use formatting from form selector
+            $phonenumber = '+44 ' . $phonenumberNSNformatted;
+        } else {
+            // Use formatting from type-in
+            $phonenumber = $phonenumberPrefix . $phonenumberNSNformatted;
+        }
+
+        // Add extension back on to number
+        if ($phonenumberHasExtension) {
+            $phonenumber .= $phonenumberExtension;
+        }
+    }
+    return $phonenumber;
 }
 
 /**
- * Convert a valid United Kingdom phone number into standard +44 (0)1970 123 456 #001 international format
+ * Verifies that $phonenumber uses a valid UK phone number input pattern.
+ * Pattern matches any number entered as 2+8, 3+7, 4+6, 4+5, 5+5, 5+4, 3+6
+ * with or without spaces, with a variety of prefixes and optional extension.
+ * RegEx patterns are based on
+ * http://www.aa-asterisk.org.uk/index.php/Number_format and
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_UK_Telephone_Numbers
+ * created by @g1smd
  *
- * @param $phonenumber must be a valid eleven-digit number (with optional extension)
+ * Regular expression is adapted from Amos Hurd's RegEx at RegExLib.com
+ * Reformulated by @g1smd to remove multiple inefficiencies in pattern and 
+ * include various valid number formats that the original pattern omitted.
  *
+ * @param string $phonenumber
+ * @return boolean Returns boolean FALSE if the phone number is not valid.
  */
-function format_gb_phone_number($phonenumber, $field = FALSE) {
+function valid_gb_phone_pattern($phonenumber) {
+    // RegEx to define valid formats for GB numbers
+    $patternRegExGB  = '/^';
+    $patternRegExGB .= '(?:';
+        $patternRegExGB .= '(?:\(?(?:0(?:0|11)\)?\s?\(?|\+)44\)?\s?(?:\(?0\)?\s?)?)';  # leading 00, 011 or + before 44 with optional (0); parentheses and spaces optional
+        $patternRegExGB .= '|';
+        $patternRegExGB .= '(?:\(?0)';                                  # leading (0, 0
+    $patternRegExGB .= ')';
+    $patternRegExGB .= '(?:';
+        $patternRegExGB .= '(?:\d{5}\)?\s?\d{4,5})';                    # [5+4]/[5+5]
+        $patternRegExGB .= '|';
+        $patternRegExGB .= '(?:\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3}))';    # [4+5]/[4+6]
+        $patternRegExGB .= '|';
+        $patternRegExGB .= '(?:\d{3}\)?\s?\d{3}\s?\d{3,4})';            # [3+6]/[3+7]
+        $patternRegExGB .= '|';
+        $patternRegExGB .= '(?:\d{2}\)?\s?\d{4}\s?\d{4})';              # [2+8]
+    $patternRegExGB .= ')';
+    $patternRegExGB .= '(?:';
+        $patternRegExGB .= '(\s?\#\d+)?';                               # optional extension number shown with a hash divider
+    $patternRegExGB .= ')';
+    $patternRegExGB .= '$/x';
+
+// Test number entered for matching format
+    if (!preg_match($patternRegExGB, $phonenumber)) {
+        return FALSE;
+    } else {
+        return TRUE;
+    }
+}
+
+/**
+ * Extract parts from GB phone number: prefix, NSN and optional extension.
+ * Accepts a wide range of input formats and prefixes. This function also
+ * cleans up the NSN part by removing spaces, hyphens and brackets. Returned
+ * prefix is either +44 with space or a 0 without space.
+ * created by @g1smd
+ *
+ * @param string $phonenumber must be a valid UK phone number (with optional extension)
+ * @return array $phonenumberPartsArray Returns prefix, NSN and extension in array.
+ */
+function extract_gb_phone_parts($phonenumber) {
+    // RegEx to extract number parts: 44 prefix ($2), NSN ($3), extension ($4)
+    $patternGBnumberparts  = '/^';
+    $patternGBnumberparts .= '(\(?(?:0(?:0|11)\)?\s?\(?|\+)(44)\)?\s?)?\(?0?(?:\)\s?)?';    # country or trunk prefix
+    $patternGBnumberparts .= '(';
+        $patternGBnumberparts .= '[1-9]\d{1,4}\)?[\d\s]+';                                  # NSN
+    $patternGBnumberparts .= ')';
+    $patternGBnumberparts .= '(\#\d+)?';                                                    # optional extension
+    $patternGBnumberparts .= '$/x';
+    if (preg_match($patternGBnumberparts, $phonenumber, $matches)) {
+
+        // Extract NSN part of GB number
+        if (ISSET($matches['3'])) {
+            $phonenumberNSNraw = $matches['3'];
+            // Trim NSN and remove space, hyphen or ')' if present
+            $arrayReplace = array(")", "-", " ");
+            $phonenumberNSN = trim(str_replace($arrayReplace, "", $phonenumberNSNraw));
+
+            // Extract 44 prefix if present and set prefix as 0 or as +44 and space
+            if (ISSET($matches['2']) && $matches['2'] == '44') {
+                $phonenumberPrefix = '+44 ';
+            } else {
+                $phonenumberPrefix = '0';
+            }
+
+            // Extract extension
+            $phonenumberExtension = null;
+            if (ISSET($matches['4'])) {
+                $phonenumberExtension = ' ' . $matches['4'];
+            }
+        }
+//  } else {
+    }
+
+    $phonenumberPartsArray = array(
+            'NSN'       => $phonenumberNSN,
+            'prefix'    => $phonenumberPrefix,
+            'extension' => $phonenumberExtension,
+        );
+
+    return $phonenumberPartsArray;
+}
 
-    $area = $number = $extension = '';
-
-    //If we already have the formatting we want just return
-    if (preg_match(
-    "/
-        (
-            \+44\s\(0\)\d{4}\s\d{3}\s\d{3}  # 4 digit area code
-            |
-            \+44\s\(0\)\d{3}\s\d{3}\s\d{4}  # 3 digit area code
-            |
-            \+44\s\(0\)\d{2}\s\d{4}\s\d{4}  # 2 digit area code
-        )
-        (\s\#\d*)?
-    /",$phonenumber)) {
-        return $phonenumber;
+/**
+ * Verifies that $phonenumberNSN is a valid UK phone number range by initial
+ * digits and length. Tests the NSN part for length and number range. Based on
+ * http://www.aa-asterisk.org.uk/index.php/Number_format and
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_UK_Telephone_Numbers
+ * created by @g1smd
+ * 
+ * @param string $phonenumberNSN
+ * @return boolean Returns boolean FALSE if the phone number is not valid.
+ */
+function valid_gb_phone_range($phonenumberNSN) {
+    // RegEx to define valid ranges for NSN by initial digits and length
+    $patternGBvalidrange  = '/^';
+    $patternGBvalidrange .= '(';
+        $patternGBvalidrange .= '(1[1-9]|2[03489]|3[0347]|5[56]|7[04-9]|8[047]|9[018])\d{8}';
+        $patternGBvalidrange .= '|';
+        $patternGBvalidrange .= '(1[2-9]\d|[58]00)\d{6}';
+        $patternGBvalidrange .= '|';
+        $patternGBvalidrange .= '8(001111|45464\d)';
+    $patternGBvalidrange .= ')';
+    $patternGBvalidrange .= '$/x';
+    // Test NSN to see if it matches a valid number range
+    if (preg_match($patternGBvalidrange, $phonenumberNSN)) {
+        return TRUE;
+    } else {
+        return FALSE;
     }
-    else {
-        //Simplify to 10 digit number and clean up ready for international reformat.
-        $phonenumber = preg_replace("/^(\+44)?\s?(\(?0\)?)?/","",$phonenumber);
-        $phonenumber = preg_replace("/\(/","",$phonenumber);
-        $phonenumber = preg_replace("/\(0/","",$phonenumber);
-        $phonenumber = preg_replace("/\)/","",$phonenumber);
-
-        //If there are some spaces in the number assume some level of preformatting
-        if(preg_match("/ /",$phonenumber)) {
-            $regex = "/
-                # 4 digit area code.
-                (
-                    (\d{4}) # capture 4 digit area code
-                    \s+     # ignore required separator to make a distinction with other area codes
-                    (\d{3}) # capture first set of numbers in the local number
-                    \s*     # ignore optional separator
-                    (\d{3}) # capture second set of numbers in the local number
-                |
-                # 3 digit area code.
-                    (\d{3}) # capture 3 digit area code
-                    \s+     # ignore required seperator
-                    (\d{3}) # capture first set of numbers in the local number
-                    \s*     # ignore possible boundary
-                    (\d{4}) # capture second set of numbers in the local number
-                |
-                # 2 digit area code.
-                    (\d{2}) # capture 2 digit area code
-                    \s+     # ignore required boundary to make a distinction with other area codes
-                    (\d{4}) # capture first set of numbers in the local number
-                    \s*     # ignore possible boundary
-                    (\d{4}) # capture second set of numbers in the local number
-                )
-                # capture the optional extension number
-                (\s*\#)?
-                (\d{4}|\d{3})?
-            /x";
-            preg_match($regex, $phonenumber, $matches);
-            $area = $matches[2].$matches[5].$matches[8];
-            $number = $matches[3].$matches[6].$matches[9].' '.$matches[4].$matches[7].$matches[10];
-            $extension = $matches[12];
+}
+
+/**
+ * Format GB phone numbers in correct format per number range. Based on
+ * http://www.aa-asterisk.org.uk/index.php/Number_format and
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_UK_Telephone_Numbers
+ * created by @g1smd
+ *
+ * @param string $phonenumberNSN Must be the 10 or 9 digit NSN part of the number.
+ * @return string $phonenumberNSN Returns correctly formatted NSN by length and range.
+ */
+function format_gb_nsn($phonenumberNSN) {
+    // Trim NSN
+    $phonenumberNSN = trim($phonenumberNSN);
+    // Find NSN string length
+    $phonenumberNSNLength = strlen($phonenumberNSN);
+    // RegEx patterns to define formatting by length and initial digits
+    // [2+8] 2d, 55, 56, 70, 76 (not 7624)
+    $pattern28 = '/^(?:2|5[56]|7(?:0|6(?:[013-9]|2[0-35-9])))/';
+    $capture28 = '/^(\d{2})(\d{4})(\d{4})$/';
+    // [3+7] 11d, 1d1, 3dd, 80d, 84d, 87d, 9dd
+    $pattern37 = '/^(?:1(?:1|\d1)|3|8(?:0[08]|4[2-5]|7[0-3])|9[018])/';
+    $capture37 = '/^(\d{3})(\d{3})(\d{4})$/';
+    // [5+5] 1dddd (12 areas)
+    $pattern55 = '/^(?:1(?:3873|5(?:242|39[456])|697[347]|768[347]|9467))/';
+    $capture55 = '/^(\d{5})(\d{5})$/';
+    // [5+4] 1ddd (1 area)
+    $pattern54 = '/^(?:16977[23])/';
+    $capture54 = '/^(\d{5})(\d{4})$/';
+    // [4+6] 1ddd, 7ddd (inc 7624) (not 70, 76)
+    $pattern46 = '/^(?:1|7(?:[1-5789]|624))/';
+    $capture46 = '/^(\d{4})(\d{6})$/';
+    // [4+5] 1ddd (40 areas)
+    $pattern45 = '/^(?:1(?:2(?:0[48]|54|76|9[78])|3(?:6[34]|8[46])|4(?:04|20|6[01]|8[08])|5(?:27|6[26])|6(?:06|29|35|47|59|95)|7(?:26|44|50)|8(?:27|37|84)|9(?:0[05]|35|49|63|95)))/';
+    $capture45 = '/^(\d{4})(\d{5})$/';
+    // [3+6] 500, 800
+    $pattern36 = '/^([58]00)/';
+    $capture36 = '/^(\d{3})(\d{6})$/';
+    // Format numbers by leading digits and length
+    if ($phonenumberNSNLength == 10 && preg_match($pattern28, $phonenumberNSN)) {
+        if (preg_match($capture28, $phonenumberNSN, $matches)) {
+            $phonenumberNSN = $matches['1'] . " " . $matches['2'] . " " . $matches['3'];
         }
-        //If there are no spaces in the number assume 4 digit area code.
-        else {
-            preg_match("/(\d{4})(\d{3})(\d{3})\#?(\d*)?/",$phonenumber, $matches);
-            $area = $matches[1];
-            $number = $matches[2].' '.$matches[3];
-            $extension = $matches[4];
+    } else if ($phonenumberNSNLength == 10 && preg_match($pattern37, $phonenumberNSN)) {
+        if (preg_match($capture37, $phonenumberNSN, $matches)) {
+            $phonenumberNSN = $matches['1'] . " " . $matches['2'] . " " . $matches['3'];
         }
-	
-      if ($field['phone_country_code']) {	
-      	$phonenumber = '+44 (0)'.$area.' '.$number;
-      }
-      else {
-      	$phonenumber = '0'.$area.' '.$number;
-      }
-      $phonenumber .= (empty($extension))?'':" #$extension";
-  }
-  return $phonenumber;
+    } else if ($phonenumberNSNLength == 10 && preg_match($pattern55, $phonenumberNSN)) {
+        if (preg_match($capture55, $phonenumberNSN, $matches)) {
+            $phonenumberNSN = $matches['1'] . " " . $matches['2'];
+        }
+    } else if ($phonenumberNSNLength == 9  && preg_match($pattern54, $phonenumberNSN)) {
+        if (preg_match($capture54, $phonenumberNSN, $matches)) {
+            $phonenumberNSN = $matches['1'] . " " . $matches['2'];
+        }
+    } else if ($phonenumberNSNLength == 10 && preg_match($pattern46, $phonenumberNSN)) {
+        if (preg_match($capture46, $phonenumberNSN, $matches)) {
+            $phonenumberNSN = $matches['1'] . " " . $matches['2'];
+        }
+    } else if ($phonenumberNSNLength == 9  && preg_match($pattern45, $phonenumberNSN)) {
+        if (preg_match($capture45, $phonenumberNSN, $matches)) {
+            $phonenumberNSN = $matches['1'] . " " . $matches['2'];
+        }
+    } else if ($phonenumberNSNLength == 9  && preg_match($pattern36, $phonenumberNSN)) {
+        if (preg_match($capture36, $phonenumberNSN, $matches)) {
+            $phonenumberNSN = $matches['1'] . " " . $matches['2'];
+        }
+    } else if ($phonenumberNSNLength > 5) {
+        // Default format for non-valid numbers (shouldn't ever get here)
+        if (preg_match("/^(\d)(\d{4})(\d*)$/", $phonenumberNSN, $matches)) {
+            $phonenumberNSN = $matches['1'] . " " . $matches['2'] . " " . $matches['3'];
+        }
+    }
+    return $phonenumberNSN;
 }
+
+?>
