diff -BurN geocoder.orig/geocoder.module geocoder/geocoder.module
--- geocoder.orig/geocoder.module	2012-02-28 21:48:48.000000000 +0400
+++ geocoder/geocoder.module	2012-03-01 00:05:51.000000000 +0400
@@ -160,38 +158,15 @@
   $valid_fields = array();
   $available_handlers = array();
 
-  // Add in the title/name
-  //@@TODO Do this programatically by getting entity_info
-  switch ($instance['entity_type']) {
-    case 'node':
-      $all_fields['title'] = array(
-        'field_name' => 'title',
-        'type' => 'text',
-      );
-
-      $entity_fields['title']['label'] = t('Title');
-      break;
-
-    case 'taxonomy_term':
-      $all_fields['name'] = array(
-        'field_name' => 'name',
-        'type' => 'text',
-      );
-
-      $entity_fields['name']['label'] = t('Name');
-      break;
-  }
-
   // Get a list of all valid fields that we both support and are part of this entity
-  foreach ($all_fields as $field) {
-    if (array_key_exists($field['field_name'], $entity_fields)) {
-      if (in_array($field['type'], array_keys($supported_field_types)) && ($field['field_name'] != $this_field['field_name'])) {
-        $valid_fields[$field['field_name']] = $entity_fields[$field['field_name']]['label'];
-        foreach ($supported_field_types[$field['type']] as $handler) {
-          $available_handlers[$handler] = $processors[$handler]['title'];
-          $handlers_by_type[$field['type']][] = $handler;
-          $field_types[$field['field_name']] = $field['type'];
-        }
+  foreach ($entity_fields as $key => $v) {
+    $field = $all_fields[$key];
+    if (in_array($field['type'], array_keys($supported_field_types)) && ($field['field_name'] != $this_field['field_name'])) {
+      $valid_fields[$field['field_name']] = $entity_fields[$field['field_name']]['label'];
+      foreach ($supported_field_types[$field['type']] as $handler) {
+        $available_handlers[$handler] = $processors[$handler]['title'];
+        $handlers_by_type[$field['type']][] = $handler;
+        $field_types[$field['field_name']] = $field['type'];
       }
     }
   }
@@ -201,10 +176,17 @@
     '#title' => t('Geocode from field'),
     '#default_value' => isset($settings['geocoder_field']) ? $settings['geocoder_field']: '',
     '#options' => $valid_fields,
-    '#description' => t('Select which field you would like to geocode from.'),
+    '#description' => t('Select which fields you would like to geocode from.'),
     '#required' => TRUE,
+    '#multiple' => TRUE,
     '#attributes' => array('onchange' => 'geocoder_admin_field_selected();'),
   );
+  $form['concate_all_fields'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Concate all selected fields values together'),
+    '#default_value' => isset($settings['concate_all_fields']) ? $settings['concate_all_fields']: false,
+    '#description' => t('Concatenate all field values if multiple selected'),
+  );
 
   $form['geocoder_handler'] = array(
     '#type' => 'select',
@@ -247,7 +229,7 @@
     '#required' => TRUE,
   );
 
-  drupal_add_js(array('geocoder_widget_settings' => array('handlers' => $handlers_by_type, 'types' => $field_types)),'setting');
+  drupal_add_js(array('geocoder_widget_settings' => array('handlers' => $handlers_by_type, 'types' => $field_types)), 'setting');
   drupal_add_js(drupal_get_path('module','geocoder').'/geocoder.admin.js','file');
 
   return $form;
@@ -270,85 +253,22 @@
   foreach (field_info_instances($entity_type, $bundle_name) as $field_instance) {
     if ($field_instance['widget']['type'] === 'geocoder') {
       // Required settings
-      if (isset($field_instance['widget']['settings']['geocoder_handler']) && isset($field_instance['widget']['settings']['geocoder_field'])) {
-        $handler = geocoder_get_handler($field_instance['widget']['settings']['geocoder_handler']);
-        $field_name = is_array($field_instance['widget']['settings']['geocoder_field']) ? reset($field_instance['widget']['settings']['geocoder_field']) : $field_instance['widget']['settings']['geocoder_field'];
-        
-        if (isset($field_instance['widget']['settings']['handler_settings'][$handler['name']])) {
-          $handler_settings = $field_instance['widget']['settings']['handler_settings'][$handler['name']];
-        }
-        
-        // Get values for the data to be geocoded.
-        // First check to see if it's an entity field
-        if (in_array($field_name, $entity_info['entity keys'])) {
-          $items[]['value'] = $entity->$field_name;
-          $field_info = array(
-            'type' => 'text',
-            'entity key' => TRUE,
-          );
-        }
-        else {
-          // It's a normal field-api field
+      $settings = $field_instance['widget']['settings'];
+      if (isset($settings['geocoder_handler']) && isset($settings['geocoder_field'])) {
+        $handler = geocoder_get_handler($settings['geocoder_handler']);
+        $field_names = $settings['geocoder_field'];
+        $items = array();
+        foreach($field_names as $field_name) {
           $field_info = field_info_field($field_name);
           $langcode = field_language($entity_type, $entity, $field_name);
-          $items = field_get_items($entity_type, $entity, $field_name, $langcode);
+          $sub_items = field_get_items($entity_type, $entity, $field_name, $langcode);
+          $items[] = array('info' => $field_info, 'values' => $sub_items);
         }
-        
-        if (count($items)) {
-          $values = array();
-          
-          // Geocode geometries
-          $geometries = array();
-          foreach ($items as $delta => $item) {
-            // Geocode any value from our source field.
-            try {
-              if (isset($handler_settings)) $geometry = call_user_func($handler['field_callback'], $field_info, $item, $handler_settings);
-              else $geometry = call_user_func($handler['field_callback'], $field_info, $item);
-              if ($geometry instanceof Geometry) $geometries[] = $geometry;
-            }
-            catch (Exception $e) {
-              drupal_set_message($e->getMessage(), 'error');
-            }
-          }
-          
-          if (empty($geometries)) $values = array(NULL);
-          else {
-            // Determine how we deal with deltas (multi-value fields)
-            if (empty($field_instance['widget']['settings']['delta_handling'])) {
-              $delta_handling = 'default';
-            }
-            else {
-              $delta_handling = $field_instance['widget']['settings']['delta_handling'];
-            }
-            
-            // Default delta handling: just pass one delta to the next
-            if ($delta_handling == 'default') {
-              foreach ($geometries as $geometry) {
-                $values[] = geofield_get_values_from_geometry($geometry);
-              }
-            }
-            
-            // Single-to-multiple handling - if we can, explode out the component geometries
-            if ($delta_handling == 's_to_m') {
-              $type = $geometries[0]->geometryType();
-              if (in_array($type, array('MultiPoint','MultiLineString','MultiPolygon','GeometryCollection'))) {
-                $components = $geometries[0]->getComponents();
-                foreach ($components as $component) {
-                  $values[] = geofield_get_values_from_geometry($component);
-                }
-              }
-              else {
-                $values[] = geofield_get_values_from_geometry($geometries[0]);
-              }
-            }
-            
-            // For multiple-to-single handling, run it though geometryReduce
-             if ($delta_handling == 'm_to_s') {
-              $reduced_geom = geoPHP::geometryReduce($geometries);
-              $values[] = geofield_get_values_from_geometry($reduced_geom);
-            }
+        if($items) {
+          $values = _geocoder_field_get_geometries($handler['field_callback'], $items, $settings);
+          if(!$values) {
+            $values = array(null);
           }
-          
           // Set the values - geofields do not support languages
           $entity->{$field_instance['field_name']}[LANGUAGE_NONE] = $values;
         }
@@ -357,20 +277,140 @@
   }
 }
 
+function _geocoder_field_concate_field_values($type, $values) {
+    $function = 'geocoder_widget_parse_' . $type;
+    if(!function_exists($function)) {
+      $function = 'geocoder_widget_parse_default';
+    }
+
+    return call_user_func($function, $values);
+}
+
+function _geocoder_field_implode_field_values($fields) {
+  $items = array();
+  foreach($fields as $field) {
+    $type   = $field['info']['type'];
+    $values = $field['values'];
+
+    $value = _geocoder_field_concate_field_values($type, $values);
+
+    if(is_string($value)) {
+      //@todo remove: for compability with addressfield widget parse
+      $value = array($value);
+    }
+
+    $items = array_merge($items, $value);
+  }
+
+  return $items;
+}
+
+function _geocoder_field_get_geometries($handler, $fields, $settings) {
+  $geometries = array();
+
+  if(!empty($settings['concate_all_fields'])) {
+    $items = _geocoder_field_implode_field_values($fields);
+    $address = implode(', ', $items);
+    $items = array(array('value' => $address));
+    $field_info= array(
+      'type' => 'text',
+      'entity key' => TRUE,
+    );
+  } else {
+    //for compability, get last selected field and pass all values to standart geometry loop
+    $field = array_pop($fields);
+    $field_info = $field['info'];
+    $items = $field['values'];
+  }
+
+  foreach ($items as $delta => $item) {
+    // Geocode any value from our source field.
+    try {
+      $geometry = call_user_func($handler, $field_info, $item);
+      if ($geometry instanceof Geometry) {
+        $geometries[] = $geometry;
+      }
+    }
+    catch (Exception $e) {
+      drupal_set_message($e->getMessage(), 'error');
+    }
+  }
+
+  if(!$geometries) {
+    return array();
+  }
+
+  $values = array();
+
+  // Determine how we deal with deltas (multi-value fields)
+  $delta_handling = !empty($settings['delta_handling']) ? $settings['delta_handling'] : null;
+
+  // Single-to-multiple handling - if we can, explode out the component geometries
+  if ($delta_handling == 's_to_m') {
+    $geometry = $geometries[0];
+    $type = $geometry->geometryType();
+    if (in_array($type, array('MultiPoint','MultiLineString','MultiPolygon','GeometryCollection'))) {
+      $components = $geometry->getComponents();
+      foreach ($components as $component) {
+        $values[] = geofield_get_values_from_geometry($component);
+      }
+    }
+    else {
+      $values[] = geofield_get_values_from_geometry($geometry);
+    }
+  }
+  // For multiple-to-single handling, run it though geometryReduce
+  else if ($delta_handling == 'm_to_s') {
+    $reduced_geom = geoPHP::geometryReduce($geometries);
+    $values[] = geofield_get_values_from_geometry($reduced_geom);
+  }
+  // Default delta handling: just pass one delta to the next
+  else {
+    foreach ($geometries as $geometry) {
+      $values[] = geofield_get_values_from_geometry($geometry);
+    }
+  }
+
+  return $values;
+}
+
 /**
  * Helper Function: Parse and address field
  */
-function geocoder_widget_parse_addressfield($field_item) {
-  $address = '';
-  if (!empty($field_item['premise']))                 $address .= $field_item['premise'].',';
-  if (!empty($field_item['thoroughfare']))            $address .= $field_item['thoroughfare'].',';
-  if (!empty($field_item['locality']))                $address .= $field_item['locality'].',';
-  if (!empty($field_item['administrative_area']))     $address .= $field_item['administrative_area'].',';
-  if (!empty($field_item['sub_administrative_area'])) $address .= $field_item['sub_administrative_area'].',';
-  if (!empty($field_item['country']))                 $address .= $field_item['country'].',';
-  if (!empty($field_item['postal_code']))             $address .= $field_item['postal_code'].',';
-  
-  $address = rtrim($address,', ');
-  
-  return $address;
+function geocoder_widget_parse_addressfield($values) {
+  $items = array();
+  $keys = array('premise', 'thoroughfare', 'locality', 'administrative_area', 'sub_administrative_area', 'country', 'postal_code');
+  foreach($keys as $key) {
+    if(!empty($values[$key])) {
+      $items[] = $values[$key];
+    }
+  }
+
+  return implode(', ', $items);
 }
+
+function geocoder_widget_parse_taxonomy_term_reference($values) {
+  $items = array();
+  foreach($values as $value) {
+      $items[] = $value['name'];
+  }
+
+  return $items;
+}
+
+function geocoder_widget_parse_default($values) {
+  $items = array();
+  foreach($values as $value) {
+    if(isset($value['value'])) {
+      $items[] = $value['value'];
+    }
+  }
+
+  return $items;
+}
+
+function geocoder_entity_titles($entity_type) {
+
+
+}
+
diff -BurN geocoder.orig/plugins/geocoder_handler/google.inc geocoder/plugins/geocoder_handler/google.inc
--- geocoder.orig/plugins/geocoder_handler/google.inc	2012-02-28 21:48:48.000000000 +0400
+++ geocoder/plugins/geocoder_handler/google.inc	2012-02-29 23:50:33.000000000 +0400
@@ -14,7 +14,7 @@
   'title' => t("Google Geocoder"),
   'description' => t('Geocodes via google geocoder'),
   'callback' => 'geocoder_google',
-  'field_types' => array('text','text_long','addressfield','text_with_summary','computed'),
+  'field_types' => array('text','text_long','addressfield','text_with_summary','computed', 'taxonomy_term_reference'),
   'field_callback' => 'geocoder_google_field',
   'settings_callback' => 'geocoder_google_form',
 );
diff -BurN geocoder.orig/plugins/geocoder_handler/gpx.inc geocoder/plugins/geocoder_handler/gpx.inc
--- geocoder.orig/plugins/geocoder_handler/gpx.inc	2012-02-28 21:48:48.000000000 +0400
+++ geocoder/plugins/geocoder_handler/gpx.inc	2012-02-29 23:50:33.000000000 +0400
@@ -17,7 +17,7 @@
   'title' => t("GPX"),
   'description' => t('Get the geomtry of a GPX string or file'),
   'callback' => 'geocoder_gpx',
-  'field_types' => array('text','text_long','file','computed'),
+  'field_types' => array('text','text_long','file','computed', 'taxonomy_term_reference'),
   'field_callback' => 'geocoder_gpx_field',
 );
 
diff -BurN geocoder.orig/plugins/geocoder_handler/json.inc geocoder/plugins/geocoder_handler/json.inc
--- geocoder.orig/plugins/geocoder_handler/json.inc	2012-02-28 21:48:48.000000000 +0400
+++ geocoder/plugins/geocoder_handler/json.inc	2012-02-29 23:50:33.000000000 +0400
@@ -14,7 +14,7 @@
   'title' => t("GeoJSON"),
   'description' => t('Get the geometry of a GeoJSON string, file, or URL'),
   'callback' => 'geocoder_json',
-  'field_types' => array('text','text_long','file','computed'),
+  'field_types' => array('text','text_long','file','computed', 'taxonomy_term_reference'),
   'field_callback' => 'geocoder_json_field',
 );
 
diff -BurN geocoder.orig/plugins/geocoder_handler/kml.inc geocoder/plugins/geocoder_handler/kml.inc
--- geocoder.orig/plugins/geocoder_handler/kml.inc	2012-02-28 21:48:48.000000000 +0400
+++ geocoder/plugins/geocoder_handler/kml.inc	2012-02-29 23:50:33.000000000 +0400
@@ -14,7 +14,7 @@
   'title' => t("KML"),
   'description' => t('Get the geometry out of a KML string, file, or URL'),
   'callback' => 'geocoder_kml',
-  'field_types' => array('text','text_long','file','computed'),
+  'field_types' => array('text','text_long','file','computed', 'taxonomy_term_reference'),
   'field_callback' => 'geocoder_kml_field',
 );
 
diff -BurN geocoder.orig/plugins/geocoder_handler/wkt.inc geocoder/plugins/geocoder_handler/wkt.inc
--- geocoder.orig/plugins/geocoder_handler/wkt.inc	2012-02-28 21:48:48.000000000 +0400
+++ geocoder/plugins/geocoder_handler/wkt.inc	2012-02-29 23:50:33.000000000 +0400
@@ -14,7 +14,7 @@
   'title' => t("WKT"),
   'description' => t('Get the geometry of a WKT string'),
   'callback' => 'geocoder_wkt',
-  'field_types' => array('text','text_long','file','geofield','computed'),
+  'field_types' => array('text','text_long','file','geofield','computed', 'taxonomy_term_reference'),
   'field_callback' => 'geocoder_wkt_field',
 );
 
diff -BurN geocoder.orig/plugins/geocoder_handler/yahoo.inc geocoder/plugins/geocoder_handler/yahoo.inc
--- geocoder.orig/plugins/geocoder_handler/yahoo.inc	2012-02-28 21:48:48.000000000 +0400
+++ geocoder/plugins/geocoder_handler/yahoo.inc	2012-02-29 23:50:33.000000000 +0400
@@ -14,7 +14,7 @@
   'title' => t("Yahoo Placefinder"),
   'description' => t('Geocodes via Yahoo Placefinder'),
   'callback' => 'geocoder_yahoo',
-  'field_types' => array('text','text_long','addressfield','text_with_summary','computed'),
+  'field_types' => array('text','text_long','addressfield','text_with_summary','computed', 'taxonomy_term_reference'),
   'field_callback' => 'geocoder_yahoo_field',
 );
 
