diff -urp location_old/geocoding/google.inc location/geocoding/google.inc
--- location_old/geocoding/google.inc	2011-01-04 04:57:06.000000000 -0500
+++ location/geocoding/google.inc	2011-02-24 15:04:58.000000000 -0500
@@ -107,10 +107,13 @@ function google_geocode_info() {
  * Perform a geocode on a location array.
  * @param $location
  *   The location array to process.
+ * @param $reverse
+ *   Whether to perform reverse geocoding (address from lat/lon) or not. 
+ *   Default FALSE (i.e., regular geocoding.)
  * @return
  *   an associative array with keys 'lat' and 'lon' containing the coordinates.
  */
-function google_geocode_location($location = array()) {
+function google_geocode_location($location = array(), $reverse = FALSE) {
 
   if (function_exists('gmap_get_key')) {
     $key = gmap_get_key();
@@ -119,14 +122,21 @@ function google_geocode_location($locati
     $key = variable_get('location_geocode_google_apikey', '');
   }
 
+  if($reverse == TRUE) {
+    $gmap_q = _google_geocode_flatten($location, TRUE);
+   }
+  else {
+    $gmap_q = _google_geocode_flatten($location);
+  }
+
   $query = array(
     'key' => $key,
     'sensor' => 'false', // Required by TOS.
-    'output' => 'xml',
+    'output' => 'json',
     //'ll' => 0,
     //'spn' => 0,
     'gl' => $location['country'],
-    'q' => _google_geocode_flatten($location),
+    'q' => $gmap_q,
   );
 
   $url = url('http://maps.google.com/maps/geo', array(
@@ -134,31 +144,34 @@ function google_geocode_location($locati
     'external' => TRUE,
   ));
 
+  $google_geocode_data = array();
   $http_reply = drupal_http_request($url);
+  $google_geocode_data = _google_geocode_get_json_array($http_reply->data);
 
-  $status_code_match = array();
-  preg_match('/<code>(.*)<\/code>/', $http_reply->data, $status_code_match);
-  $status_code = $status_code_match[1];
+  $status_code = $google_geocode_data['Status']['code'];
   if ($status_code != 200) {
     watchdog('location', 'Google geocoding returned status code: %status_code', array('%status_code' => $status_code));
     return NULL;
   }
 
-  $accuracy_code_match = array();
-  preg_match('/Accuracy="([0-9])"/', $http_reply->data, $accuracy_code_match);
-  $accuracy_code = $accuracy_code_match[1];
+  $accuracy_code = $google_geocode_data['Placemark'][0]['AddressDetails']['Accuracy'];
   $min_accuracy = variable_get('location_geocode_' . $location['country'] . 'google_accuracy_code', variable_get('location_geocode_google_minimum_accuracy', '3'));
   if ($accuracy_code < $min_accuracy) {
     watchdog('location', 'Google geocoding result for %country did not meet the minimum accuracy level of %min_accuracy. Result accuracy: %accuracy_code', array('%country' => $location['country'], '%min_accuracy' => $min_accuracy, '%accuracy_code' => $accuracy_code));
     return NULL;
   }
 
-  $latlon_match = array();
-  preg_match('/<coordinates>(.*)<\/coordinates>/', $http_reply->data, $latlon_match);
-
-  $latlon_exploded = explode(',', $latlon_match[1]);
-
-  return array('lat' => $latlon_exploded[1], 'lon' => $latlon_exploded[0]);
+  // Location data is returned as an associative array from the JSON response of the Google geocoder.
+  return array(
+    'lat' => $google_geocode_data['Placemark'][0]['Point']['coordinates'][1],
+    'lon' => $google_geocode_data['Placemark'][0]['Point']['coordinates'][0],
+    'geocoded_street' => $google_geocode_data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['Thoroughfare']['ThoroughfareName'],
+    'geocoded_city' => $google_geocode_data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['LocalityName'],
+    'geocoded_state' => $google_geocode_data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea']['AdministrativeAreaName'],
+    'geocoded_country' => $google_geocode_data['Placemark'][0]['AddressDetails']['Country']['CountryNameCode'],
+    'geocoded_accuracy' => $google_geocode_data['Placemark'][0]['AddressDetails']['Accuracy'],
+    'geocoded_postalcode' =>$google_geocode_data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['PostalCode']['PostalCodeNumber']
+  );
 }
 
 /**
@@ -203,46 +216,82 @@ function google_geocode_settings() {
   return $form;
 }
 
-function _google_geocode_flatten($location = array()) {
+  /**
+   * function _google_geocode_flatten:
+   * Builds 'q' query string parameter for Google geocoder based on location data.
+   * Uses $reverse parameter if you want reverse geocoding (address based on lat/lon).
+   * @param $location
+   *   The location array to process.
+   * @param $reverse
+   *    Whether to perform reverse geocoding (address from lat/lon) or not. 
+   *   Default FALSE (i.e., regular geocoding.)
+   *  @return $address
+   *    A comma-delimited query string for Google's geocoder.
+   */
+function _google_geocode_flatten($location = array(), $reverse = FALSE) {
   // Check if its a valid address
   if (empty($location)) {
     return '';
   }
-
-  $address = '';
-  if (!empty($location['street'])) {
-    $address .= $location['street'];
+  
+  // If reverse geocoding is wanted, check to see if there's a lat/lon & build query string parameter off of these.
+  if($reverse == TRUE) {
+    $address = '';
+    if(!empty($location['latitude']) && !empty($location['longitude'])) {
+      $address .= $location['latitude'] . ',' . $location['longitude'];
+    }
+    else {
+      return $address;
+    }
   }
-
-  if (!empty($location['city'])) {
+  // Otherwise, build query string parameter off of address values.
+  else {
+    $address = '';
     if (!empty($location['street'])) {
-      $address .= ', ';
+      $address .= $location['street'];
     }
-
+    if (!empty($location['city'])) {
+      if (!empty($location['street'])) {
+        $address .= ', ';
+      }
     $address .= $location['city'];
-  }
-
-  if (!empty($location['province'])) {
-    if (!empty($location['street']) || !empty($location['city'])) {
-      $address .= ', ';
     }
 
-    // @@@ Fix this!
-    if (substr($location['province'], 0, 3) == $location['country'] .'-') {
-      $address .= substr($location['province'], 3);
-      watchdog('Location', 'BUG: Country found in province attribute.');
+    if (!empty($location['province'])) {
+      if (!empty($location['street']) || !empty($location['city'])) {
+        $address .= ', ';
+      }
+      // @@@ Fix this!
+      if (substr($location['province'], 0, 3) == $location['country'] .'-') {
+        $address .= substr($location['province'], 3);
+        watchdog('Location', 'BUG: Country found in province attribute.');
+      }
+      else {
+        $address .= $location['province'];
+      }
     }
-    else {
-      $address .= $location['province'];
-    }
-  }
 
-  if (!empty($location['postal_code'])) {
-    if (!empty($address)) {
-      $address .= ' ';
+    if (!empty($location['postal_code'])) {
+      if (!empty($address)) {
+        $address .= ' ';
+      }
+      $address .= $location['postal_code'];
     }
-    $address .= $location['postal_code'];
   }
 
   return $address;
 }
+
+/**
+ * function _google_geocode_get_JSON_array:
+ * Given JSON data, will return an associative array of the data.
+ *  @param $google_json_contents
+ *    The contents of the JSON response from Google's geocoder.
+ *  @return
+ *    the JSON response converted to an associative array.
+ */
+
+function _google_geocode_get_JSON_array ($google_json_contents) {
+  $geocode_google_data = json_decode($google_json_contents, TRUE);
+  return $geocode_google_data;
+}
diff -urp location_old/location.module location/location.module
--- location_old/location.module	2011-02-09 11:21:25.000000000 -0500
+++ location/location.module	2011-02-24 15:04:58.000000000 -0500
@@ -1024,9 +1024,9 @@ function location_invoke_locationapi(&$l
 /**
  * Apply locpick twiddling to a location.
  * This is needed before saving and comparison.
+ * Geocoding doesn't need to be inhibited since Google can reverse geocode.
  */
 function _location_patch_locpick(&$location) {
-  $inhibit_geocode = FALSE;
   if (!empty($location['locpick'])) {
     $location['locpick']['user_latitude'] = trim($location['locpick']['user_latitude']);
     $location['locpick']['user_longitude'] = trim($location['locpick']['user_longitude']);
@@ -1036,9 +1036,7 @@ function _location_patch_locpick(&$locat
     $location['source'] = LOCATION_LATLON_USER_SUBMITTED;
     $location['latitude'] = $location['locpick']['user_latitude'];
     $location['longitude'] = $location['locpick']['user_longitude'];
-    $inhibit_geocode = TRUE;
   }
-  return $inhibit_geocode;
 }
 
 /**
@@ -1323,11 +1321,26 @@ function location_normalize_settings(&$s
  * Perform geocoding logic, etc., prior to storing in the database.
  */
 function _location_geo_logic(&$location, $changed, $filled, $inhibit_geocode = FALSE) {
-
   if (!$inhibit_geocode) {
-    // Have any of the fields possibly affecting geocoding changed?
+    // Have the latitude and longitude been changed on node save? If so, set location data based on them.
+    if($changed['latitude'] || $changed['longitude'])   {
+      // Include the Google geocoder.
+      $google_geocoder = './'. drupal_get_path('module', 'location') . '/geocoding/google.inc';
+      include_once($google_geocoder);
+      // Attempt exact geocoding based on latitude/longitude.
+      if($data = google_geocode_location($location, TRUE)) {
+        $location['source'] = LOCATION_LATLON_GEOCODED_EXACT;
+        $location['street'] = $data['geocoded_street'];
+        $location['city'] = $data['geocoded_city'];
+        $location['province'] = $data['geocoded_state'];
+        $location['country'] = $data['geocoded_country'];
+        $location['accuracy'] = $data['geocoded_accuracy'];
+        $location['postal_code'] = $data['geocoded_postalcode'];
+      }
+    }
+    // Have any of the address fields possibly affecting geocoding changed?
     // Or, was the location previously user submitted but is no longer?
-    if ($changed['street'] || $changed['additional'] || $changed['city'] || $changed['province'] || $changed['country'] || $changed['postal_code'] || $location['source'] == LOCATION_LATLON_USER_SUBMITTED) {
+    elseif ($changed['street'] || $changed['additional'] || $changed['city'] || $changed['province'] || $changed['country'] || $changed['postal_code'] || $location['source'] == LOCATION_LATLON_USER_SUBMITTED) {
 
       // Attempt exact geocoding.
       if ($data = location_latlon_exact($location)) {
