--- ./sites/all/modules/geocode/modules/geocode_widget/geocode_widget.module	Tue Dec 22 20:50:30 2009
+++ ./sites/all/modules/geocode/modules/geocode_widget/geocode_widget.module	Wed Nov 03 13:41:12 2010
@@ -89,8 +89,98 @@
     
         if (is_array($form_state['values'][$field])) {
           foreach ($form_state['values'][$field] as $delta => $value) {
+            
+            $field_type = $form[$field][$delta]['#type'];            
+            
+            if ($field_type == 'addresses_elements') {
+              
+              // Filter the input from an addresses field
+              // In an addresses field, each country and province value is a key, not an actual readable country or province              
+              // The key format is such that google can usually decipher the address, but not always.
+              // For example:
+              //  - "Toronto,on,top_ca"       => Hilltop Rd, Toronto, ON M6C, Canada
+              //  - "Toronto,on,ca"           => Toronto, ON, Canada
+              //  - "TypoCity,on,ca"          => California, USA
+              //  - "TypoCity,Ontario,ca"     => Ontario, California, USA
+              //  - "TypoCity,Ontario,Canada" => Ontario, Canada
+              //  - "TypoCity,ON,Canada"      => error
+              // Hence, better to give the full names.
+              // Also, the $value array supplies the fields in reverse
+              
+              module_load_include('inc', 'addresses');
+              if (substr($value['country'], 0, 4) === 'top_') {
+	              $value['country'] = substr($value['country'], 4);
+	            }	                          
+              $clean = array();           
+	            $clean['street'] = $value['street'];
+	            $clean['city'] = $value['city'];
+	            $clean['province'] = theme_addresses_province($value);
+	            $clean['postal_code'] = $value['postal_code'];      
+	            $clean['country'] = theme_addresses_country($value);
+
+	            // The user input may not be clean.  
+	            // For my purposes, it is more important to return a geo, than to report that the geo is not precisely accurate
+	            // The country and province are validated, but the other fields are all suspect.
+	            // Therefore, we will try multiple attempts at generating a geo, by removing text that may be invalid
+	            $attempt = 0;
+	            do {
+	              $clean_subset = $clean;
+	              switch($attempt++) {
+	                case 0:
+	                  // street, city, province, postal_code, country
+	                  break;
+	                case 1:
+	                  // street, city, province, country
+	                  unset ($clean_subset['postal_code']);
+	                  break;
+	                case 2:
+	                  // city, province, postal_code, country
+	                  unset ($clean_subset['street']);
+	                  break;
+	                case 3:
+	                  // province, postal_code, country
+	                  unset ($clean_subset['street']);
+	                  unset ($clean_subset['city']);
+	                  break;
+	                case 4:
+	                  // postal_code, country
+	                  unset ($clean_subset['street']);
+	                  unset ($clean_subset['city']);
+	                  unset ($clean_subset['province']);
+	                  break;
+	                case 5:
+	                  // city, province, country
+	                  unset ($clean_subset['postal_code']);
+	                  unset ($clean_subset['street']);
+	                  break;
+	                case 6:
+	                  // province, country
+	                  unset ($clean_subset['street']);
+	                  unset ($clean_subset['city']);
+	                  unset ($clean_subset['postal_code']);
+	                  break;
+	                case 7:
+	                  // country
+	                  unset ($clean_subset['street']);
+	                  unset ($clean_subset['city']);
+	                  unset ($clean_subset['province']);
+	                  unset ($clean_subset['postal_code']);
+	                  break;
+	                default:
+	                  // give up
+	                  break 2; 
+	              } 	              
+	              $geo = geocode($info['handler'], $clean_subset, $type, $info['options']);               
+	            } while (! $geo);
+	            
+	            if (geo) {
+	              $values[$delta]['geo'] = $geo;
+	            }	                          
+            }
+            else {
             if ($geo = geocode($info['handler'], $value, $type, $info['options'])) {
               $values[$delta]['geo'] = $geo;
+              }
             }
           }
         }
