diff --git a/includes/EntityReferenceSynonymsBehavior.class.inc b/includes/EntityReferenceSynonymsBehavior.class.inc
index d1a1f3d..4aa818c 100644
--- a/includes/EntityReferenceSynonymsBehavior.class.inc
+++ b/includes/EntityReferenceSynonymsBehavior.class.inc
@@ -8,7 +8,7 @@
 /**
  * Definition of EntityReferenceSynonymsBehavior class.
  */
-class EntityReferenceSynonymsBehavior extends AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehavior, AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
+class EntityReferenceSynonymsBehavior extends AbstractSynonymsBehavior implements AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
 
   public function extractSynonyms($items, $field, $instance, $entity, $entity_type) {
     $synonyms = array();
diff --git a/includes/SynonymsBehavior.interface.inc b/includes/SynonymsBehavior.interface.inc
index 2c30bca..d264362 100644
--- a/includes/SynonymsBehavior.interface.inc
+++ b/includes/SynonymsBehavior.interface.inc
@@ -11,15 +11,6 @@
  * All synonyms behaviors must extend this interface.
  */
 interface SynonymsBehavior {
-}
-
-/**
- * Interface of "synonyms" behavior.
- *
- * The most basic synonyms behavior.
- */
-interface SynonymsSynonymsBehavior extends SynonymsBehavior {
-
   /**
    * Extract synonyms from a field attached to an entity.
    *
@@ -137,9 +128,9 @@ interface SynonymsSynonymsBehavior extends SynonymsBehavior {
 class SynonymsSynonymsBehaviorException extends Exception {}
 
 /**
- * Starting point for implementing SynonymsSynonymsBehavior interface.
+ * Starting point for implementing SynonymsBehavior interface.
  */
-abstract class AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehavior {
+abstract class AbstractSynonymsBehavior implements SynonymsBehavior {
 
   /**
    * Constant which denotes placeholder of a synonym column.
@@ -178,11 +169,11 @@ abstract class AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehav
 /**
  * Interface of the autocomplete synonyms behavior.
  */
-interface AutocompleteSynonymsBehavior extends SynonymsSynonymsBehavior {
+interface AutocompleteSynonymsBehavior extends SynonymsBehavior {
 }
 
 /**
  * Interface of the synonyms friendly select behavior.
  */
-interface SelectSynonymsBehavior extends SynonymsSynonymsBehavior {
+interface SelectSynonymsBehavior extends SynonymsBehavior {
 }
diff --git a/includes/TaxonomySynonymsBehavior.class.inc b/includes/TaxonomySynonymsBehavior.class.inc
index 6e58a6c..c3c6f9b 100644
--- a/includes/TaxonomySynonymsBehavior.class.inc
+++ b/includes/TaxonomySynonymsBehavior.class.inc
@@ -8,7 +8,7 @@
 /**
  * Definition of TaxonomySynonymsBehavior class.
  */
-class TaxonomySynonymsBehavior extends AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehavior, AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
+class TaxonomySynonymsBehavior extends AbstractSynonymsBehavior implements AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
 
   public function extractSynonyms($items, $field, $instance, $entity, $entity_type) {
     $synonyms = array();
diff --git a/includes/TextSynonymsBehavior.class.inc b/includes/TextSynonymsBehavior.class.inc
index 96472e1..4330a2c 100644
--- a/includes/TextSynonymsBehavior.class.inc
+++ b/includes/TextSynonymsBehavior.class.inc
@@ -8,7 +8,7 @@
 /**
  * Definition of TextSynonymsBehavior class.
  */
-class TextSynonymsBehavior extends AbstractSynonymsSynonymsBehavior implements SynonymsSynonymsBehavior, AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
+class TextSynonymsBehavior extends AbstractSynonymsBehavior implements AutocompleteSynonymsBehavior, SelectSynonymsBehavior {
 
   public function extractSynonyms($items, $field, $instance, $entity, $entity_type) {
     $synonyms = array();
diff --git a/plugins/arguments/term_synonyms.inc b/plugins/arguments/term_synonyms.inc
index bc3e1d8..10edcf5 100644
--- a/plugins/arguments/term_synonyms.inc
+++ b/plugins/arguments/term_synonyms.inc
@@ -66,12 +66,12 @@ function synonyms_term_synonyms_context($arg = NULL, $conf = NULL, $empty = FALS
       foreach ($vocabularies as $vocabulary) {
         $condition = db_and();
         if ($conf['transform']) {
-          $condition->where("REPLACE(" . AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :argument", array(
+          $condition->where("REPLACE(" . AbstractSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :argument", array(
             ':argument' => $arg,
           ));
         }
         else {
-          $condition->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $arg);
+          $condition->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $arg);
         }
         $rows = synonyms_synonyms_find($condition, 'taxonomy_term', $vocabulary->machine_name);
         if (!empty($rows)) {
diff --git a/plugins/behavior/autocomplete.inc b/plugins/behavior/autocomplete.inc
index 6d62b8a..761376b 100644
--- a/plugins/behavior/autocomplete.inc
+++ b/plugins/behavior/autocomplete.inc
@@ -23,8 +23,8 @@ function synonyms_behavior_autocomplete_settings_form($form, &$form_state, $sett
   $element['wording'] = array(
     '#type' => 'textfield',
     '#title' => t('Autocomplete wording'),
-    '#default_value' => isset($settings['wording']) ? $settings['wording'] : '@synonym is a synonym of @term',
-    '#description' => t('Specify with what wording the synonyms should be suggested in the autocomplete feature. You may use: <ul><li><em>@synonym</em> to denote value of the synonym</li><li><em>@term</em> to denote term name</li><li><em>@field_name</em> to denote lowercase label of the field from where the synonym originates</li></ul>'),
+    '#default_value' => isset($settings['wording']) ? $settings['wording'] : '@synonym is a synonym of @entity',
+    '#description' => t('Specify with what wording the synonyms should be suggested in the autocomplete feature. You may use: <ul><li><em>@synonym</em> to denote value of the synonym</li><li><em>@entity</em> to denote entity name</li><li><em>@field_name</em> to denote lowercase label of the field from where the synonym originates</li></ul>'),
     '#required' => TRUE,
   );
 
diff --git a/plugins/behavior/select.inc b/plugins/behavior/select.inc
index e10b6d1..a30d4df 100644
--- a/plugins/behavior/select.inc
+++ b/plugins/behavior/select.inc
@@ -24,7 +24,7 @@ function synonyms_behavior_select_settings_form($form, &$form_state, $settings)
     '#type' => 'textfield',
     '#title' => t('Select wording'),
     '#default_value' => isset($settings['wording']) ? $settings['wording'] : '@synonym',
-    '#description' => t('Specify with what wording the synonyms should be placed in the select form element. You may use: <ul><li><em>@synonym</em> to denote value of the synonym</li><li><em>@term</em> to denote term name</li><li><em>@field_name</em> to denote lowercase label of the field from where the synonym originates</li></ul>'),
+    '#description' => t('Specify with what wording the synonyms should be placed in the select form element. You may use: <ul><li><em>@synonym</em> to denote value of the synonym</li><li><em>@entity</em> to denote entity name</li><li><em>@field_name</em> to denote lowercase label of the field from where the synonym originates</li></ul>'),
     '#required' => TRUE,
   );
 
diff --git a/plugins/behavior/synonyms.inc b/plugins/behavior/synonyms.inc
deleted file mode 100644
index b7c44f7..0000000
--- a/plugins/behavior/synonyms.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-/**
- * @file
- * Plugin definition for most general synonyms behavior.
- */
-
-$plugin = array(
-  'title' => t('Include into term synonyms'),
-  'description' => t('Basic behavior that includes values of this field into the list of synonyms of its entity.'),
-  'interface' => 'SynonymsSynonymsBehavior',
-);
diff --git a/synonyms.info b/synonyms.info
index 709384a..caa0034 100644
--- a/synonyms.info
+++ b/synonyms.info
@@ -4,6 +4,8 @@ package = Taxonomy
 core = 7.x
 dependencies[] = taxonomy
 dependencies[] = ctools
+dependencies[] = entity
+dependencies[] = entityreference
 
 files[] = synonyms.test
 
diff --git a/synonyms.module b/synonyms.module
index fe53208..62a4325 100644
--- a/synonyms.module
+++ b/synonyms.module
@@ -11,19 +11,61 @@
 function synonyms_menu() {
   $items = array();
 
-  $items['synonyms/autocomplete/%/%/%'] = array(
+  $items['admin/structure/synonyms'] = array(
+    'title' => 'Synonyms',
+    'description' => 'Manage synonyms settings for all entity types.',
+    'page callback' => 'synonyms_settings_overview',
+    'access arguments' => array('administer synonyms'),
+    'file' => 'synonyms.pages.inc',
+    'type' => MENU_NORMAL_ITEM,
+  );
+
+  $items['admin/structure/synonyms/%synonyms_entity_type/%synonyms_bundle'] = array(
+    'title' => 'Synonyms settings',
+    'title callback' => 'synonyms_settings_title',
+    'title arguments' => array(3, 4),
+    'description' => 'Manage synonyms settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('synonyms_settings_form', 3, 4),
+    'access arguments' => array('administer synonyms'),
+    'load arguments' => array(3),
+    'file' => 'synonyms.pages.inc',
+  );
+
+  $items['synonyms/autocomplete-taxonomy-term/%/%/%'] = array(
     'title' => 'Autocomplete Synonyms',
-    'page callback' => 'synonyms_autocomplete',
+    'page callback' => 'synonyms_autocomplete_taxonomy_term',
     'page arguments' => array(2, 3, 4),
     'access arguments' => array('access content'),
     'file' => 'synonyms.pages.inc',
     'type' => MENU_CALLBACK,
   );
 
+  $items['synonyms/autocomplete-entity/%/%/%'] = array(
+    'title' => 'Autocomplete Synonyms',
+    'page callback' => 'synonyms_autocomplete_entity',
+    'page arguments' => array(2, 3, 4),
+    'access callback' => 'entityreference_autocomplete_access_callback',
+    'access arguments' => array('tags', 2, 3, 4),
+    'file' => 'synonyms.pages.inc',
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
 /**
+ * Implements hook_permission().
+ */
+function synonyms_permission() {
+  return array(
+    'administer synonyms' => array(
+      'title' => t('Administer synonyms'),
+      'description' => t('Administer synonyms of all entity types.'),
+    ),
+  );
+}
+
+/**
  * Implements hook_ctools_plugin_type().
  */
 function synonyms_ctools_plugin_type() {
@@ -81,16 +123,22 @@ function synonyms_theme() {
  */
 function synonyms_entity_property_info() {
   $info = array();
-  $properties = &$info['taxonomy_term']['properties'];
-  $properties['synonyms'] = array(
-    'label' => t('Synonyms'),
-    'description' => t('Synonyms of entity.'),
-    'type' => 'list<text>',
-    'getter callback' => 'synonyms_get_sanitized',
-    'computed' => TRUE,
-    'sanitized' => TRUE,
-    'raw getter callback' => 'synonyms_get_raw',
-  );
+
+  foreach (entity_get_info() as $entity_type => $entity_info) {
+    $entity_info = synonyms_entity_type_load($entity_type);
+    if ($entity_info) {
+      $info[$entity_type]['properties']['synonyms'] = array(
+        'label' => t('Synonyms'),
+        'description' => t('Synonyms of entity.'),
+        'type' => 'list<text>',
+        'getter callback' => 'synonyms_get_sanitized',
+        'computed' => TRUE,
+        'sanitized' => TRUE,
+        'raw getter callback' => 'synonyms_get_raw',
+      );
+    }
+  }
+
   return $info;
 }
 
@@ -115,7 +163,6 @@ function synonyms_synonyms_behavior_implementation_info($behavior) {
   switch ($behavior) {
     case 'autocomplete':
     case 'select':
-    case 'synonyms':
       return array(
         'number_integer' => 'TextSynonymsBehavior',
         'number_decimal' => 'TextSynonymsBehavior',
@@ -133,6 +180,8 @@ function synonyms_synonyms_behavior_implementation_info($behavior) {
  * Implements hook_form_FORM_ID_alter().
  */
 function synonyms_form_taxonomy_form_vocabulary_alter(&$form, &$form_state) {
+  // TODO: remove this function after a few releases of Synonyms module, since
+  // now the module oversees synonyms of all entities, not only taxonomy terms.
   if (isset($form_state['confirm_delete']) && $form_state['confirm_delete']) {
     return;
   }
@@ -145,99 +194,14 @@ function synonyms_form_taxonomy_form_vocabulary_alter(&$form, &$form_state) {
     '#type' => 'fieldset',
     '#title' => t('Synonyms'),
     '#collapsible' => TRUE,
-    '#tree' => TRUE,
   );
 
-  $behaviors = synonyms_behaviors();
-  $bundle = field_extract_bundle('taxonomy_term', $form['#vocabulary']);
-
-  $form['synonyms']['behaviors'] = array(
-    '#theme' => 'synonyms_behaviors_settings',
-    '#id' => 'synonyms-behaviors-settings-wrapper',
+  $form['synonyms']['link'] = array(
+    '#markup' => t('You can configure synonyms of @vocabulary following <a href="@url">this link</a>.', array(
+      '@vocabulary' => $form['#vocabulary']->name,
+      '@url' => url('admin/structure/synonyms/taxonomy_term/' . $form['#vocabulary']->machine_name, array('query' => drupal_get_destination())),
+    )),
   );
-
-  foreach ($behaviors as $behavior => $behavior_info) {
-    $form['synonyms']['behaviors'][$behavior] = array(
-      '#title' => $behavior_info['title'],
-    );
-
-    $behavior_implementations = synonyms_behavior_get($behavior, 'taxonomy_term', $bundle);
-
-    foreach ($behavior_implementations as $implementation) {
-      $instance = field_info_instance($implementation['entity_type'], $implementation['field_name'], $implementation['bundle']);
-      $form['synonyms']['behaviors'][$behavior][$implementation['instance_id']]['#title'] = $instance['label'];
-
-      if (isset($form_state['values']['synonyms']['behaviors'][$behavior][$implementation['instance_id']])) {
-        $behavior_settings = (bool) $form_state['values']['synonyms']['behaviors'][$behavior][$implementation['instance_id']]['enabled'];
-      }
-      else {
-        $behavior_settings = !is_null($implementation['settings']);
-      }
-      if ($behavior_settings) {
-        if (isset($form_state['values']['synonyms']['behaviors'][$behavior][$implementation['instance_id']]['settings'])) {
-          $behavior_settings = $form_state['values']['synonyms']['behaviors'][$behavior][$implementation['instance_id']]['settings'];
-        }
-        elseif ($implementation['settings']) {
-          $behavior_settings = $implementation['settings'];
-        }
-        else {
-          $behavior_settings = array();
-        }
-      }
-
-      $form['synonyms']['behaviors'][$behavior][$implementation['instance_id']]['enabled'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Enable'),
-        '#default_value' => $behavior_settings !== FALSE,
-      );
-
-      $settings_form = ctools_plugin_get_function($behavior_info, 'settings form callback');
-      if ($settings_form) {
-        $form['synonyms']['behaviors'][$behavior][$implementation['instance_id']]['enabled']['#ajax'] = array(
-          'callback' => 'synonyms_behaviors_settings_form_ajax',
-          'wrapper' => $form['synonyms']['behaviors']['#id'],
-        );
-
-        if ($behavior_settings !== FALSE) {
-          $form['synonyms']['behaviors'][$behavior][$implementation['instance_id']]['settings'] = $settings_form($form, $form_state, $behavior_settings);
-        }
-      }
-    }
-  }
-  $form['#submit'][] = 'synonyms_taxonomy_form_vocabulary_submit';
-}
-
-/**
- * Submit handler for Taxonomy vocabulary edit form.
- *
- * Store synonyms behavior settings.
- */
-function synonyms_taxonomy_form_vocabulary_submit($form, &$form_state) {
-  $values = $form_state['values'];
-
-  if ($values['op'] == $form['actions']['submit']['#value']) {
-    foreach ($values['synonyms']['behaviors'] as $behavior => $settings) {
-      foreach ($settings as $instance_id => $behavior_settings) {
-        if ($behavior_settings['enabled']) {
-          synonyms_behavior_settings_save(array(
-            'instance_id' => $instance_id,
-            'behavior' => $behavior,
-            'settings' => isset($behavior_settings['settings']) ? $behavior_settings['settings'] : NULL,
-          ));
-        }
-        else {
-          synonyms_behavior_settings_delete($instance_id, $behavior);
-        }
-      }
-    }
-  }
-}
-
-/**
- * Ajax callback function for synonyms behavior settings form.
- */
-function synonyms_behaviors_settings_form_ajax($form, &$form_state) {
-  return $form['synonyms']['behaviors'];
 }
 
 /**
@@ -245,12 +209,12 @@ function synonyms_behaviors_settings_form_ajax($form, &$form_state) {
  */
 function synonyms_field_widget_info() {
   return array(
-    'synonyms_autocomplete' => array(
-      'label' => t('Synonyms friendly autocomplete term widget'),
+    'synonyms_autocomplete_taxonomy_term' => array(
+      'label' => t('Synonyms friendly autocomplete'),
       'field types' => array('taxonomy_term_reference'),
       'settings' => array(
         'size' => 60,
-        'synonyms_autocomplete_path' => 'synonyms/autocomplete',
+        'synonyms_autocomplete_path' => 'synonyms/autocomplete-taxonomy-term',
         'suggestion_size' => 10,
         'suggest_only_unique' => FALSE,
         'auto_creation' => 1,
@@ -259,7 +223,21 @@ function synonyms_field_widget_info() {
         'multiple values' => FIELD_BEHAVIOR_CUSTOM,
       ),
     ),
-    'synonyms_select' => array(
+    'synonyms_autocomplete_entity' => array(
+      'label' => t('Synonyms friendly autocomplete'),
+      'field types' => array('entityreference'),
+      'settings' => array(
+        'size' => 60,
+        'synonyms_autocomplete_path' => 'synonyms/autocomplete-entity',
+        'suggestion_size' => 10,
+        'suggest_only_unique' => FALSE,
+        'auto_creation' => FALSE,
+      ),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
+      ),
+    ),
+    'synonyms_select_taxonomy_term' => array(
       'label' => t('Synonyms friendly select list'),
       'field types' => array('taxonomy_term_reference'),
       'settings' => array(
@@ -269,6 +247,14 @@ function synonyms_field_widget_info() {
         'multiple values' => FIELD_BEHAVIOR_CUSTOM,
       ),
     ),
+    'synonyms_select_entity' => array(
+      'label' => t('Synonyms friendly select list'),
+      'field types' => array('entityreference'),
+      'settings' => array(),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
+      ),
+    ),
   );
 }
 
@@ -282,13 +268,16 @@ function synonyms_field_widget_settings_form($field, $instance) {
   $form = array();
 
   switch  ($widget['type']) {
-    case 'synonyms_autocomplete':
-      $form['auto_creation'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Allow auto-creation?'),
-        '#description' => t('Whether users may create a new term by typing in a non-existing name into this field.'),
-        '#default_value' => $settings['auto_creation'],
-      );
+    case 'synonyms_autocomplete_taxonomy_term':
+    case 'synonyms_autocomplete_entity':
+      if ($widget['type'] == 'synonyms_autocomplete_taxonomy_term') {
+        $form['auto_creation'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Allow auto-creation?'),
+          '#description' => t('Whether users may create a new term by typing in a non-existing name into this field.'),
+          '#default_value' => $settings['auto_creation'],
+        );
+      }
 
       $form['suggestion_size'] = array(
         '#type' => 'textfield',
@@ -307,7 +296,7 @@ function synonyms_field_widget_settings_form($field, $instance) {
       );
       break;
 
-    case 'synonyms_select':
+    case 'synonyms_select_taxonomy_term':
       $form['sort'] = array(
         '#type' => 'radios',
         '#title' => t('Sort'),
@@ -329,21 +318,43 @@ function synonyms_field_widget_settings_form($field, $instance) {
  */
 function synonyms_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
   $default_value = array();
+  $column = array_keys($field['columns']);
+  $column = reset($column);
   foreach ($items as $item) {
-    $default_value[] = $item['tid'];
+    $default_value[] = $item[$column];
   }
 
   switch ($instance['widget']['type']) {
-    case 'synonyms_autocomplete':
-      $tags = taxonomy_term_load_multiple($default_value);
+    case 'synonyms_autocomplete_taxonomy_term':
+    case 'synonyms_autocomplete_entity':
+      switch ($instance['widget']['type']) {
+        case 'synonyms_autocomplete_taxonomy_term':
+          $default_value_string = taxonomy_implode_tags(taxonomy_term_load_multiple($default_value));
+          $element_validate = array('taxonomy_autocomplete_validate', 'synonyms_autocomplete_taxonomy_term_validate');
+          break;
+
+        case 'synonyms_autocomplete_entity':
+          $default_value_string = array();
+          $entity = isset($element['#entity']) ? $element['#entity'] : NULL;
+          $handler = entityreference_get_selection_handler($field, $instance, $instance['entity_type'], $entity);
+
+          $target_entities = entity_load($field['settings']['target_type'], $default_value);
+          foreach ($target_entities as $target_entity_id => $target_entity) {
+            $default_value_string[] = synonyms_autocomplete_escape($handler->getLabel($target_entity));
+          }
+          $default_value_string = implode(', ', $default_value_string);
+
+          $element_validate = array('synonyms_autocomplete_entity_validate');
+          break;
+      }
 
       $element += array(
         '#type' => 'textfield',
-        '#default_value' => taxonomy_implode_tags($tags),
+        '#default_value' => $default_value_string,
         '#autocomplete_path' => $instance['widget']['settings']['synonyms_autocomplete_path'] . '/' . $field['field_name'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'],
         '#size' => $instance['widget']['settings']['size'],
         '#maxlength' => 1024,
-        '#element_validate' => array('taxonomy_autocomplete_validate', 'synonyms_autocomplete_validate'),
+        '#element_validate' => $element_validate,
         '#auto_creation' => $instance['widget']['settings']['auto_creation'],
         '#attached' => array(
           'js' => array(
@@ -356,7 +367,7 @@ function synonyms_field_widget_form(&$form, &$form_state, $field, $instance, $la
       );
       break;
 
-    case 'synonyms_select':
+    case 'synonyms_select_taxonomy_term':
       $multiple = $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;
 
       $options = array();
@@ -367,10 +378,10 @@ function synonyms_field_widget_form(&$form, &$form_state, $field, $instance, $la
               if ($terms = taxonomy_get_tree($vocabulary->vid, $tree['parent'], NULL, TRUE)) {
                 $behavior_implementations = synonyms_behavior_get('select', 'taxonomy_term', field_extract_bundle('taxonomy_term', $vocabulary), TRUE);
                 foreach ($terms as $term) {
-                  $options[] = synonyms_select_option($term);
+                  $options[] = synonyms_select_option_entity($term, 'taxonomy_term', NULL, NULL, array('depth'));
                   foreach ($behavior_implementations as $implementation) {
                     foreach (synonyms_extract_synonyms($term, $implementation) as $synonym) {
-                      $options[] = synonyms_select_option($term, $synonym, $implementation);
+                      $options[] = synonyms_select_option_entity($term, 'taxonomy_term', $synonym, $implementation, array('depth'));
                     }
                   }
                 }
@@ -379,22 +390,62 @@ function synonyms_field_widget_form(&$form, &$form_state, $field, $instance, $la
 
             case 'name':
               // TODO: is there any way to leverage DB for the sorting routine?
-              $options = synonyms_select_sort_name_options_recursive($vocabulary, $tree['parent']);
+              $options = synonyms_select_taxonomy_term_sort_name_options_recursive($vocabulary, $tree['parent']);
               break;
           }
         }
       }
 
-      if (!$multiple && !$element['#required']) {
-        $options = array('' => t('- None -')) + $options;
+      $element += array(
+        '#type' => 'select',
+        '#multiple' => $multiple,
+        '#options' => $options,
+        '#default_value' => $default_value,
+        '#element_validate' => array('synonyms_select_form_to_storage'),
+        '#empty_option' => t('- None -'),
+      );
+      break;
+
+    case 'synonyms_select_entity':
+      $multiple = $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;
+
+      $options = entityreference_get_selection_handler($field, $instance, $instance['entity_type'], $element['#entity'])->getReferencableEntities();
+      $synonyms_options = array();
+
+      $target_entity_info = entity_get_info($field['settings']['target_type']);
+      $entity_ids = array();
+      foreach ($options as $bundle_entity_ids) {
+        $entity_ids = array_merge($entity_ids, array_keys($bundle_entity_ids));
+      }
+      $entities = entity_load($field['settings']['target_type'], $entity_ids);
+      foreach ($options as $bundle => $bundle_entity_ids) {
+        $synonyms_options[$target_entity_info['bundles'][$bundle]['label']] = array();
+
+        $behavior_implementations = synonyms_behavior_get('select', $field['settings']['target_type'], $bundle, TRUE);
+
+        foreach ($bundle_entity_ids as $entity_id => $v) {
+          $entity = $entities[$entity_id];
+          $synonyms_options[$target_entity_info['bundles'][$bundle]['label']][] = synonyms_select_option_entity($entity, $field['settings']['target_type']);
+          foreach ($behavior_implementations as $behavior_implementation) {
+            foreach (synonyms_extract_synonyms($entity, $behavior_implementation) as $synonym) {
+              $synonyms_options[$target_entity_info['bundles'][$bundle]['label']][] = synonyms_select_option_entity($entity, $field['settings']['target_type'], $synonym, $behavior_implementation);
+            }
+          }
+        }
+        usort($synonyms_options[$target_entity_info['bundles'][$bundle]['label']], 'synonyms_select_sort_name');
+      }
+
+      if (count($synonyms_options) == 1) {
+        $synonyms_options = reset($synonyms_options);
       }
 
       $element += array(
         '#type' => 'select',
         '#multiple' => $multiple,
-        '#options' => $options,
+        '#options' => $synonyms_options,
         '#default_value' => $default_value,
         '#element_validate' => array('synonyms_select_form_to_storage'),
+        '#empty_option' => t('- None -'),
       );
       break;
   }
@@ -414,13 +465,15 @@ function synonyms_field_widget_error($element, $error, $form, &$form_state) {
  *
  * Handle validation for taxonomy term synonym-friendly autocomplete element.
  */
-function synonyms_autocomplete_validate($element, &$form_state) {
+function synonyms_autocomplete_taxonomy_term_validate($element, &$form_state) {
   // After taxonomy_autocomplete_validate() has finished its job any terms it
   // didn't find have been set for autocreation. We need to:
   // (a) Double-check that those terms are not synonyms.
   // (b) Check that synonyms' configurable auto-creation option is enabled.
   $value = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
 
+  $tids = array();
+
   $field = field_widget_field($element, $form_state);
   foreach ($value as $delta => $term) {
     if ($term['tid'] == 'autocreate') {
@@ -428,7 +481,7 @@ function synonyms_autocomplete_validate($element, &$form_state) {
       foreach ($field['settings']['allowed_values'] as $tree) {
         $behavior_implementations = synonyms_behavior_get('autocomplete', 'taxonomy_term', $tree['vocabulary'], TRUE);
         foreach ($behavior_implementations as $behavior_implementation) {
-          $synonyms = synonyms_synonyms_find_behavior(db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $term['name']), $behavior_implementation);
+          $synonyms = synonyms_synonyms_find_behavior(db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $term['name']), $behavior_implementation);
           foreach ($synonyms as $synonym) {
             $synonym_tid = $synonym->entity_id;
             break(2);
@@ -436,21 +489,112 @@ function synonyms_autocomplete_validate($element, &$form_state) {
         }
       }
 
-      if ($synonym_tid != 0) {
+      if ($synonym_tid != 0 && !in_array($synonym_tid, $tids)) {
         $value[$delta]['tid'] = $synonym_tid;
+        $tids[] = $synonym_tid;
       }
       elseif (!$element['#auto_creation']) {
         unset($value[$delta]);
       }
     }
+    else {
+      $tids[] = $term['tid'];
+    }
   }
   $value = array_values($value);
   form_set_value($element, $value, $form_state);
 }
 
 /**
+ * Form element validate handler.
+ *
+ * Validate entity reference synonyms friendly autocomplete element.
+ */
+function synonyms_autocomplete_entity_validate($element, &$form_state) {
+  $input = drupal_map_assoc(drupal_explode_tags(drupal_strtolower($element['#value'])));
+
+  $value = array();
+  if (!empty($input)) {
+    $field = field_info_field($element['#field_name']);
+    $instance = field_info_instance($element['#entity_type'], $field['field_name'], $element['#bundle']);
+    $handler = entityreference_get_selection_handler($field, $instance);
+    $matches = $handler->getReferencableEntities($input, 'IN');
+
+    foreach ($matches as $bundle => $entity_ids) {
+      foreach ($entity_ids as $entity_id => $label) {
+        $value[] = $entity_id;
+        unset($input[drupal_strtolower($label)]);
+      }
+    }
+
+    if (!empty($input)) {
+      $behavior_implementations = synonyms_behavior_get('autocomplete', $field['settings']['target_type'], synonyms_field_target_bundles($field), TRUE);
+      foreach ($behavior_implementations as $implementation) {
+        $condition = db_and();
+        $condition->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $input, 'IN');
+        foreach (synonyms_synonyms_find_behavior($condition, $implementation) as $synonym) {
+          unset($input[drupal_strtolower($synonym->synonym)]);
+          $value[] = $synonym->entity_id;
+        }
+      }
+    }
+  }
+
+  $tmp = array_unique($value);
+  $value = array();
+  foreach ($tmp as $target_id) {
+    $value[] = array('target_id' => $target_id);
+  }
+
+  form_set_value($element, $value, $form_state);
+}
+
+/**
+ * Try finding an entity by its name or synonym.
+ *
+ * @param string $entity_type
+ *   What entity type is being searched
+ * @param string $name
+ *   The look up keyword (the supposed name or synonym)
+ * @param string $bundle
+ *   Optionally limit the search within a specific bundle name of the provided
+ *   entity type
+ *
+ * @return int
+ *   ID of the looked up entity. If such entity was not found, then 0 is
+ *   returned
+ */
+function synonyms_get_entity_by_synonym($entity_type, $name, $bundle = NULL) {
+  $name = trim($name);
+  $entity_info = entity_get_info($entity_type);
+  if (isset($entity_info['entity keys']['label'])) {
+    $efq = new EntityFieldQuery();
+    $efq->entityCondition('entity_type', $entity_type);
+    if ($bundle) {
+      $efq->entityCondition('bundle', $bundle);
+    }
+    $efq->propertyCondition($entity_info['entity keys']['label'], $name);
+    $result = $efq->execute();
+    if (isset($result[$entity_type])) {
+      $result = array_keys($result[$entity_type]);
+      return reset($result);
+    }
+  }
+
+  $synonyms = synonyms_synonyms_find(db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $name), $entity_type, $bundle);
+  if (!empty($synonyms)) {
+    return reset($synonyms)->entity_id;
+  }
+  return 0;
+}
+
+/**
  * Try to find a term by its name or synonym.
  *
+ * You are adviced to use the more general function
+ * synonyms_get_entity_by_synonym() unless you really need $parent input
+ * argument from this function for additional filtering by Taxonomy hierarchy.
+ *
  * @param string $name
  *   The string to be searched for its {taxonomy_term_data}.tid
  * @param object $vocabulary
@@ -481,7 +625,7 @@ function synonyms_get_term_by_synonym($name, $vocabulary, $parent = 0) {
   // We have failed to find a term with the provided $name. So let's search now
   // among the term synonyms.
   $bundle = field_extract_bundle('taxonomy_term', $vocabulary);
-  $synonyms = synonyms_synonyms_find(db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $name), 'taxonomy_term', $bundle);
+  $synonyms = synonyms_synonyms_find(db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $name), 'taxonomy_term', $bundle);
   foreach ($synonyms as $synonym) {
     if (!$parent || synonyms_taxonomy_term_is_child_of($synonym->entity_id, $parent)) {
       // TODO: similarly here, as above, we could have more than 1 match, but
@@ -540,35 +684,35 @@ function synonyms_add_term_by_synonym($name, $vocabulary, $parent = 0) {
 }
 
 /**
- * Retrieve a list of sanitized synonyms of a taxonomy term.
+ * Retrieve list of sanitized synonyms of an entity.
  *
- * @param $item object
- *   Fully loaded taxonomy term
+ * @param $entity object
+ *   Fully loaded entity
  *
  * @return array
- *   List of sanitized synonyms of a taxonomy term
+ *   List of sanitized synonyms of an entity
  */
-function synonyms_get_sanitized($item) {
-  $synonyms = array();
-  foreach (synonyms_get_term_synonyms($item) as $synonym) {
-    $synonyms[] = $synonym['safe_value'];
-  }
-  return $synonyms;
+function synonyms_get_sanitized($entity, array $options, $name, $entity_type, &$context) {
+  return array_map('check_plain', synonyms_get_raw($entity, $options, $name, $entity_type, $context));
 }
 
 /**
- * Retrieve a list of raw synonyms of a taxonomy term.
+ * Retrieve list of raw synonyms of an entity.
  *
- * @param $item object
- *   Fully loaded taxonomy term
+ * @param $entity object
+ *   Fully loaded entity
  *
  * @return array
- *   List of raw synonyms of a taxonomy term
+ *   List of raw synonyms of an entity
  */
-function synonyms_get_raw($item) {
+function synonyms_get_raw($entity, array $options, $name, $entity_type, &$context) {
   $synonyms = array();
-  foreach (synonyms_get_term_synonyms($item) as $synonym) {
-    $synonyms[] = $synonym['value'];
+  $bundle = entity_extract_ids($entity_type, $entity);
+  $bundle = $bundle[2] ? $bundle[2] : $entity_type;
+
+  $behavior_implementations = synonyms_behavior_get_all_enabled($entity_type, $bundle);
+  foreach ($behavior_implementations as $implementation) {
+    $synonyms = array_merge($synonyms, synonyms_extract_synonyms($entity, $implementation));
   }
   return $synonyms;
 }
@@ -596,15 +740,15 @@ function synonyms_get_term_synonyms($term) {
   $vocabulary = taxonomy_vocabulary_load($term->vid);
   $bundle = field_extract_bundle('taxonomy_term', $vocabulary);
 
-  $behavior_implementations = synonyms_behavior_get('synonyms', 'taxonomy_term', $bundle, TRUE);
+  $behavior_implementations = synonyms_behavior_get_all_enabled('taxonomy_term', $bundle);
   foreach ($behavior_implementations as $implementation) {
     foreach  (synonyms_extract_synonyms($term, $implementation) as $synonym) {
-        $synonyms[] = array(
-          'value' => $synonym,
-          'safe_value' => check_plain($synonym),
-        );
-      }
+      $synonyms[] = array(
+        'value' => $synonym,
+        'safe_value' => check_plain($synonym),
+      );
     }
+  }
 
   return $synonyms;
 }
@@ -650,19 +794,20 @@ function synonyms_extract_synonyms($entity, $behavior_implementation) {
  * @param QueryConditionInterface $condition
  *   Object of QueryConditionInterface that specifies conditions by which you
  *   want to find synonyms. When building this condition object, use
- *   AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER as a placeholder for
- *   real column name that contains synonym as text. For example, if you were to
- *   find all entities with synonyms that begin with "synonym-come-here"
- *   substring, case insensitive and replacing all spaces in original synonym
- *   string by a dash sign, then you would have to create the following
- *   condition object:
+ *   AbstractSynonymsBehavior::COLUMN_PLACEHOLDER as a placeholder for real
+ *   column name that contains synonym as text. For example, if you were to find
+ *   all entities with synonyms that begin with "synonym-come-here" substring,
+ *   case insensitive and replacing all spaces in original synonym string by a
+ *   dash sign, then you would have to create the following condition object:
  *   db_and()
- *     ->where("LOWER(REPLACE(" . AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-')) LIKE 'synonym-come-here%'")
+ *     ->where("LOWER(REPLACE(" . AbstractSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-')) LIKE 'synonym-come-here%'")
  *   And then just supply this object as an input parameter to this function
  * @param string $entity_type
  *   Among synonyms of what entity type to search
- * @param string $bundle
- *   Among synonyms of what bundle to search
+ * @param string|array $bundle
+ *   Optionally specifcy among synonyms of what bundle(-s) to search. You can
+ *   specify here a string - bundle name to search within or an array of nundles
+ *   within which to search
  *
  * @return array
  *   Array of found synonyms and entity IDs to which those belong. Each element
@@ -671,10 +816,12 @@ function synonyms_extract_synonyms($entity, $behavior_implementation) {
  *     $condition you specified
  *   - entity_id: (int) ID of the entity to which the found synonym belongs
  */
-function synonyms_synonyms_find(QueryConditionInterface $condition, $entity_type, $bundle) {
+function synonyms_synonyms_find(QueryConditionInterface $condition, $entity_type, $bundle = NULL) {
   $rows = array();
 
-  $behavior_implementations = synonyms_behavior_get('synonyms', $entity_type, $bundle, TRUE);
+  $behavior_implementations = synonyms_behavior_get_all_enabled($entity_type, $bundle);
+  if (!$bundle)
+  debug($behavior_implementations);
   foreach ($behavior_implementations as $behavior_implementation) {
     foreach (synonyms_synonyms_find_behavior($condition, $behavior_implementation) as $row) {
       $rows[] = $row;
@@ -702,14 +849,13 @@ function synonyms_synonyms_find(QueryConditionInterface $condition, $entity_type
  * @param QueryConditionInterface $condition
  *   Object of QueryConditionInterface that specifies conditions by which you
  *   want to find synonyms. When building this condition object, use
- *   AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER as a placeholder for
- *   real column name that contains synonym as text. For example, if you were to
- *   find all entities with synonyms that begin with "synonym-come-here"
- *   substring, case insensitive and replacing all spaces in original synonym
- *   string by a dash sign, then you would have to create the following
- *   condition object:
+ *   AbstractSynonymsBehavior::COLUMN_PLACEHOLDER as a placeholder for real
+ *   column name that contains synonym as text. For example, if you were to find
+ *   all entities with synonyms that begin with "synonym-come-here" substring,
+ *   case insensitive and replacing all spaces in original synonym string by a
+ *   dash sign, then you would have to create the following condition object:
  *   db_and()
- *     ->where("LOWER(REPLACE(" . AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-')) LIKE 'synonym-come-here%'")
+ *     ->where("LOWER(REPLACE(" . AbstractSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-')) LIKE 'synonym-come-here%'")
  *   And then just supply this object as an input parameter to this function
  * @param array $behavior_implementation
  *   Fully loaded behavior implementation. Supply here one of the values from
@@ -759,27 +905,23 @@ function synonyms_synonyms_find_behavior(QueryConditionInterface $condition, $be
  *   Whether synonym has been successfully added
  */
 function synonyms_add_entity_as_synonym($trunk_entity, $trunk_entity_type, $field, $synonym_entity, $synonym_entity_type) {
-  if ($trunk_entity_type != 'taxonomy_term') {
-    // Currently synonyms module only operates on taxonomy terms.
-    return FALSE;
-  }
-
   $bundle = entity_extract_ids($trunk_entity_type, $trunk_entity);
-  $bundle = $bundle[2];
-  $behavior_implementations = synonyms_behavior_get('synonyms', $trunk_entity_type, $bundle, TRUE);
+  $bundle = $bundle[2] ? $bundle[2] : $trunk_entity_type;
+  $behavior_implementations = synonyms_behavior_get_all_enabled($trunk_entity_type, $bundle, $field);
 
   $field = field_info_field($field);
   $instance = field_info_instance($trunk_entity_type, $field['field_name'], $bundle);
-  if (!isset($behavior_implementations[$instance['id']])) {
-    // $field either doesn't exist in the $trunk_entity or it does not have
-    // enabled the behavior of synonyms.
+  if (empty($behavior_implementations)) {
+    // $field either doesn't exist in the $trunk_entity or it does not have any
+    // enabled behavior.
     return FALSE;
   }
 
   $items = field_get_items($trunk_entity_type, $trunk_entity, $field['field_name']);
   $items = is_array($items) ? $items : array();
 
-  $object = synonyms_behavior_implementation_class('synonyms', $field);
+  $behavior_implementation = reset($behavior_implementations);
+  $object = synonyms_behavior_implementation_class($behavior_implementation['behavior'], $field);
   $object = new $object();
   $extra_items = $object->mergeEntityAsSynonym($items, $field, $instance, $synonym_entity, $synonym_entity_type);
 
@@ -805,9 +947,8 @@ function synonyms_add_entity_as_synonym($trunk_entity, $trunk_entity_type, $fiel
   $items = array_values($unique_items);
 
   $trunk_entity->{$field['field_name']}[LANGUAGE_NONE] = $items;
-  // In future if this module eventually becomes a gateway for synonyms for any
-  // entity types, we'll substitute it with entity_save().
-  taxonomy_term_save($trunk_entity);
+
+  entity_save($trunk_entity_type, $trunk_entity);
   return TRUE;
 }
 
@@ -831,7 +972,7 @@ function synonyms_add_entity_as_synonym($trunk_entity, $trunk_entity_type, $fiel
 function synonyms_synonyms_fields($vocabulary) {
   $fields = array();
   $bundle = field_extract_bundle('taxonomy_term', $vocabulary);
-  $behavior_implementations = synonyms_behavior_get('synonyms', 'taxonomy_term', $bundle, TRUE);
+  $behavior_implementations = synonyms_behavior_get_all_enabled('taxonomy_term', $bundle);
   foreach ($behavior_implementations as $v) {
     $fields[] = $v['field_name'];
   }
@@ -857,10 +998,11 @@ function synonyms_views_api() {
  * @param string $entity_type
  *   Optional filter to limit the search for existing implementations only to
  *   those that apply to the provided entity type
- * @param string $bundle
+ * @param string|array $bundle
  *   Optional filter to limit the search for existing implementations only to
  *   those that apply to the provided bundle and entity type (the $entity_type
- *   argument)
+ *   argument). You may supply array of bundle names if you want to limit your
+ *   search within a few bundles
  * @param bool $only_enabled
  *   Optional filter to limit the search for existing implementations only to
  *   those that are currently enabled
@@ -920,6 +1062,59 @@ function synonyms_behavior_get($behavior, $entity_type = NULL, $bundle = NULL, $
 }
 
 /**
+ * Load all enabled behaviors on an entity_type and a bundle.
+ *
+ * This is useful when you want to do some operation on all enabled synonyms
+ * behaviors for a specific entity_type and a bundle.
+ *
+ * @param string $entity_type
+ *   Entity type whose enabled behaviors should be loaded
+ * @param string|array $bundle
+ *   Optionally filter by bundle whose enabled behaviors should be loaded. You
+ *   can supply here string - single bundle name or an array of bundle names
+ * @param string $field_name
+ *   Optional filter to only return enabled synonyms behaviors of a specific
+ *   field
+ *
+ * @return array
+ *   Array of enabled behaviors for a provided entity type and a bundle. Each
+ *   sub array will have the following structure:
+ *   - behavior: (string) Name of the synonyms behavior
+ *   - settings: (mixed) Behavior settings, its internal structure depends on
+ *     the type of behavior.
+ *   - entity_type: (string) Entity type to which this behavior implementation
+ *     applies
+ *   - bundle: (string) Bundle name to which this behavior implementation
+ *     applies
+ *   - field_name: (string) Name of the field on which this synonyms behavior is
+ *     enabled
+ *   - instance_id: (int) ID of the field instance to which this behavior
+ *     implementation applies
+ */
+function synonyms_behavior_get_all_enabled($entity_type, $bundle = NULL, $field_name = NULL) {
+  $query = db_select('synonyms_settings', 's');
+  $instance_alias = $query->innerJoin('field_config_instance', 'i', 'i.id = s.instance_id');
+  $query->fields($instance_alias, array('field_name', 'entity_type', 'bundle'));
+  $query->fields('s', array('behavior', 'settings_serialized'));
+  $query->addField($instance_alias, 'id', 'instance_id');
+
+  $query->condition($instance_alias . '.entity_type', $entity_type);
+  if ($bundle) {
+    $query->condition($instance_alias . '.bundle', $bundle);
+  }
+  if ($field_name) {
+    $query->condition($instance_alias . '.field_name', $field_name);
+  }
+
+  $result = $query->execute();
+  $rows = array();
+  foreach ($result as $row) {
+    $rows[] = (array) $row;
+  }
+  return synonyms_behavior_settings_unpack($rows);
+}
+
+/**
  * Retrieve information about all ctools plugins of type 'synonyms behavior'.
  *
  * @return array
@@ -1038,14 +1233,18 @@ function synonyms_behavior_settings_save($settings) {
  *   Name of behavior for which settings should be removed
  */
 function synonyms_behavior_settings_delete($instance_id, $behavior) {
+
+
   $behavior_definition = synonyms_behaviors();
   $behavior_definition = $behavior_definition[$behavior];
   $disabled_callback = ctools_plugin_get_function($behavior_definition, 'disabled callback');
   if ($disabled_callback) {
     $instance = synonyms_instance_id_load($instance_id);
-    $behavior_implementation = synonyms_behavior_get($behavior, $instance['entity_type'], $instance['bundle'], FALSE, TRUE);
-    $behavior_implementation = $behavior_implementation[$instance_id];
-    $disabled_callback($behavior_definition, $behavior_implementation, $instance);
+    $behavior_implementation = synonyms_behavior_get($behavior, $instance['entity_type'], $instance['bundle'], TRUE, TRUE);
+    if (isset($behavior_implementation[$instance_id])) {
+      $behavior_implementation = $behavior_implementation[$instance_id];
+      $disabled_callback($behavior_definition, $behavior_implementation, $instance);
+    }
   }
   db_delete('synonyms_settings')
     ->condition('instance_id', $instance_id)
@@ -1058,17 +1257,23 @@ function synonyms_behavior_settings_delete($instance_id, $behavior) {
  *
  * @param int $instance_id
  *   ID of the instance that should be loaded
+ * @param bool $reset
+ *   Whether to reset static cache of this function
  *
  * @return array
  *   Instance definition array
  */
-function synonyms_instance_id_load($instance_id) {
-  $result = db_select('field_config_instance', 'i')
-    ->fields('i', array('entity_type', 'bundle', 'field_name'))
-    ->condition('id', $instance_id)
-    ->execute()
-    ->fetchAssoc();
-  return field_info_instance($result['entity_type'], $result['field_name'], $result['bundle']);
+function synonyms_instance_id_load($instance_id, $reset = FALSE) {
+  $cache = &drupal_static(__FILE__, array(), $reset);
+
+  if (!isset($cache[$instance_id])) {
+    $cache[$instance_id] = db_select('field_config_instance', 'i')
+      ->fields('i', array('entity_type', 'bundle', 'field_name'))
+      ->condition('id', $instance_id)
+      ->execute()
+      ->fetchAssoc();
+  }
+  return field_info_instance($cache[$instance_id]['entity_type'], $cache[$instance_id]['field_name'], $cache[$instance_id]['bundle']);
 }
 
 /**
@@ -1088,23 +1293,24 @@ function synonyms_select_form_to_storage($element, &$form_state) {
   }
 
   foreach ($value as $k => $v) {
-    // For the cases when a synonym was selected and not a term option, we
+    // For the cases when a synonym was selected and not an entity option, we
     // process the selected values stripping everything that goes after
     // semicolon.
     if (!is_numeric($v)) {
-      $tid = explode(':', $v);
-      $value[$k] = $tid[0];
+      $id = explode(':', $v);
+      $value[$k] = $id[0];
     }
   }
 
-  // The user also might have selected multiple times the same term, given that
-  // a term can be represented by more than 1 option (a term and its synonym),
-  // then it's possible in theory, so we should be ready for this scenario.
+  // The user also might have selected multiple times the same entity, given
+  // that an entity can be represented by more than 1 option (an entity and its
+  // synonym), then it's possible in theory, so we should be ready for this
+  // scenario.
   $value = array_unique($value);
 
   $form_state_value = array();
-  foreach ($value as $tid) {
-    $form_state_value[] = array('tid' => $tid);
+  foreach ($value as $id) {
+    $form_state_value[] = array($element['#columns'][0] => $id);
   }
 
   form_set_value($element, $form_state_value, $form_state);
@@ -1141,37 +1347,53 @@ function synonyms_taxonomy_term_is_child_of($tid, $parent_tid) {
 }
 
 /**
- * Format an option for select form element.
+ * Format an option for entity reference select form element.
  *
- * @param object $term
- *   Fully loaded taxonomy term which is represented by this option
+ * @param object $entity
+ *   Fully loaded entity which is represented by this option
+ * @param string $entity_type
+ *   Entity type of the $entity object
  * @param string $synonym
- *   If the provided term is represented in this option by a synonym, then
+ *   If the provided entity is represented in this option by a synonym, then
  *   provide it here
  * @param array $behavior_implementation
  *   Behavior implementation array from which the $synonym comes from
+ * @param array $options
+ *   Array of additional settings or options that may influence execution of
+ *   this function. Currently supported options are:
+ *   - depth: Whether to prefix wording of option labels with depth of the
+ *     entity. This will work only for taxonomy term entities, as they are the
+ *     only ones that have notion of depth
  *
  * @return object
- *   An option for select form element
+ *   An option for entity reference select form element
  */
-function synonyms_select_option($term, $synonym = NULL, $behavior_implementation = NULL) {
-  $key = $synonym ? $term->tid . ':' . drupal_html_class($synonym) : $term->tid;
-  $wording = $term->name;
+function synonyms_select_option_entity($entity, $entity_type, $synonym = NULL, $behavior_implementation = NULL, $options = array()) {
+  $entity_id = entity_extract_ids($entity_type, $entity);
+  $entity_id = $entity_id[0];
+  $key = $synonym ? $entity_id . ':' . drupal_html_class($synonym) : $entity_id;
+  $wording = entity_label($entity_type, $entity);
   if ($synonym) {
     $instance = field_info_instance($behavior_implementation['entity_type'], $behavior_implementation['field_name'], $behavior_implementation['bundle']);
     $wording = format_string($behavior_implementation['settings']['wording'], array(
       '@synonym' => $synonym,
-      '@term' => $term->name,
+      '@entity' => entity_label($behavior_implementation['entity_type'], $entity),
       '@field_name' => drupal_strtolower($instance['label']),
     ));
   }
+
+  if (in_array('depth', $options) && $entity_type == 'taxonomy_term') {
+    $depth = count(taxonomy_get_parents_all($entity_id)) - 1;
+    $wording = str_repeat('-', $depth) . $wording;
+  }
+
   return (object) array(
-    'option' => array($key => str_repeat('-', $term->depth) . $wording),
+    'option' => array($key => $wording),
   );
 }
 
 /**
- * Supportive function to build options array with sorting by name logic.
+ * Supportive function to build taxonomy term options array sorted by name.
  *
  * The function starts from the 0-depth level and starts to recursively build
  * the options and to sort the labels on each level, then it merges the bottom
@@ -1194,10 +1416,10 @@ function synonyms_select_option($term, $synonym = NULL, $behavior_implementation
  *   The options will be sorted by name (term or synonym), respecting the
  *   hierarchy restrictions
  */
-function synonyms_select_sort_name_options_recursive($vocabulary, $parent = 0, $depth = 0) {
+function synonyms_select_taxonomy_term_sort_name_options_recursive($vocabulary, $parent = 0, $depth = 0) {
   // We statically cache behavior implementations in order to not DDOS the data
   // base.
-  $behavior_implementations = drupal_static(__FUNCTION__, array());
+  $behavior_implementations = &drupal_static(__FUNCTION__, array());
 
   $bundle = field_extract_bundle('taxonomy_term', $vocabulary);
   if (!isset($behavior_implementations[$bundle])) {
@@ -1209,10 +1431,10 @@ function synonyms_select_sort_name_options_recursive($vocabulary, $parent = 0, $
     $options = array();
     foreach ($terms as $term) {
       $term->depth = $depth;
-      $options[] = synonyms_select_option($term);
+      $options[] = synonyms_select_option_entity($term, 'taxonomy_term', NULL, NULL, array('depth'));
       foreach ($behavior_implementations[$bundle] as $implementation) {
         foreach (synonyms_extract_synonyms($term, $implementation) as $synonym) {
-          $options[] = synonyms_select_option($term, $synonym, $implementation);
+          $options[] = synonyms_select_option_entity($term, 'taxonomy_term', $synonym, $implementation, array('depth'));
         }
       }
     }
@@ -1228,7 +1450,7 @@ function synonyms_select_sort_name_options_recursive($vocabulary, $parent = 0, $
       $tid = array_keys($v->option);
       $tid = $tid[0];
       if (is_numeric($tid)) {
-        $nested_options = synonyms_select_sort_name_options_recursive($vocabulary, $tid, $depth + 1);
+        $nested_options = synonyms_select_taxonomy_term_sort_name_options_recursive($vocabulary, $tid, $depth + 1);
         $options = array_merge(array_slice($options, 0, $i), $nested_options, array_slice($options, $i));
       }
     }
@@ -1244,3 +1466,105 @@ function synonyms_select_sort_name_options_recursive($vocabulary, $parent = 0, $
 function synonyms_select_sort_name($a, $b) {
   return strcasecmp(reset($a->option), reset($b->option));
 }
+
+/**
+ * Test if entity type is applicable for having synonyms.
+ *
+ * Only fieldable entity types can have synonyms for the very reason that
+ * synonyms are stored in fields.
+ *
+ * @param string $entity_type
+ *   Entity type to test
+ *
+ * @return bool|string
+ *   Whether the provided entity type is applicable for having synonyms. If it
+ *   is applicable, the $entity_type input argument will be returned. Otherwise
+ *   FALSE is returned
+ */
+function synonyms_entity_type_load($entity_type) {
+  $entity_info = entity_get_info($entity_type);
+  if ($entity_info && $entity_info['fieldable']) {
+    return $entity_type;
+  }
+  return FALSE;
+}
+
+/**
+ * Test if provided entity type and bundle exist.
+ *
+ * @param string $bundle
+ *   Bundle name to test for existence
+ * @param string $entity_type
+ *   Entity type to test for existence
+ *
+ * @return bool|string
+ *   Whether the provided entity type and bundle exist. If they exist, the
+ *   $bundle input argument is returned. Otherwise FALSE is returned
+ */
+function synonyms_bundle_load($bundle, $entity_type) {
+  $entity_info = entity_get_info($entity_type);
+  if ($entity_info && isset($entity_info['bundles'][$bundle])) {
+    return $bundle;
+  }
+  return FALSE;
+}
+
+/**
+ * Menu title callback function for synonyms settings page.
+ *
+ * @param string $entity_type
+ *   Entity type whose synonyms settings are managed
+ * @param string $bundle
+ *   Bundle whose synonyms settings are managed
+ *
+ * @return string
+ *   Title of the synonyms settings page
+ */
+function synonyms_settings_title($entity_type, $bundle) {
+  $entity_info = entity_get_info($entity_type);
+  $entity_label = isset($entity_info['plural label']) ? $entity_info['plural label'] : $entity_info['label'];
+  if ($entity_type == $bundle) {
+    return t('Synonyms settings of @entity_type', array(
+      '@entity_type' => $entity_label,
+    ));
+  }
+  return t('Synonyms settings of @bundle @entity_type', array(
+    '@bundle' => $entity_info['bundles'][$bundle]['label'],
+    '@entity_type' => $entity_label,
+  ));
+}
+
+/**
+ * Escape string to safely use in autocomplete text field as default value.
+ *
+ * @param string $value
+ *   String to be escaped
+ *
+ * @return string
+ *   Escaped string $value
+ */
+function synonyms_autocomplete_escape($value) {
+  // Commas or quotes must be wrapped in quotes.
+  if (strpos($value, ',') !== FALSE || strpos($value, '"') !== FALSE) {
+    $value = '"' . str_replace('"', '""', $value) . '"';
+  }
+  return $value;
+}
+
+/**
+ * Determine a list of target bundles of an entityreference field.
+ *
+ * @param array $field
+ *   Field definition array. This field must be of type 'entityreference'
+ *
+ * @return array|null
+ *   List of target bundles per the settings of provided field or NULL if the
+ *   provided field does not expose any limitations on target bundles
+ */
+function synonyms_field_target_bundles($field) {
+  $target_bundles = isset($field['settings']['handler_settings']['target_bundles']) ? array_values($field['settings']['handler_settings']['target_bundles']) : array();
+  if (empty($target_bundles)) {
+    $target_bundles = NULL;
+  }
+  return $target_bundles;
+}
diff --git a/synonyms.pages.inc b/synonyms.pages.inc
index 04e6ec2..0ebb43d 100644
--- a/synonyms.pages.inc
+++ b/synonyms.pages.inc
@@ -26,7 +26,7 @@
  *   autocomplete form element. Only the last term is used for autocompletion.
  *   Defaults to '' (an empty string).
  */
-function synonyms_autocomplete($field_name, $entity_type, $bundle, $tags_typed = '') {
+function synonyms_autocomplete_taxonomy_term($field_name, $entity_type, $bundle, $tags_typed = '') {
   // If the request has a '/' in the search text, then the menu system will have
   // split it into multiple arguments, recover the intended $tags_typed.
   $args = func_get_args();
@@ -56,7 +56,7 @@ function synonyms_autocomplete($field_name, $entity_type, $bundle, $tags_typed =
     exit;
   }
 
-  $widget = $instance['widget']['type'] == 'synonyms_autocomplete' ? $instance['widget']['settings'] : field_info_widget_settings('synonyms_autocomplete');
+  $widget = $instance['widget']['type'] == 'synonyms_autocomplete_taxonomy_term' ? $instance['widget']['settings'] : field_info_widget_settings('synonyms_autocomplete_taxonomy_term');
 
   // How many suggestions maximum we are able to output.
   $max_suggestions = $widget['suggestion_size'];
@@ -81,7 +81,14 @@ function synonyms_autocomplete($field_name, $entity_type, $bundle, $tags_typed =
     }
   }
 
-  $term_matches = array();
+  // Array of found suggestions. Each subarray of this array will represent a
+  // single suggestion entry.
+  // - tid: (int) tid of the suggested term
+  // - name: (string) name of the suggested term
+  // - synonym: (string) optional synonym string that matched this entry
+  // - behavior_implementation: (array) optional behavior implementation that
+  //   provided the synonym
+  $tags_return = array();
   if ($tag_last != '') {
     // Part of the criteria for the query come from the field's own settings.
     $vocabularies = array();
@@ -91,14 +98,6 @@ function synonyms_autocomplete($field_name, $entity_type, $bundle, $tags_typed =
     }
     $vocabularies = taxonomy_vocabulary_load_multiple(array_keys($vocabularies));
 
-    // Array of found suggestions. Each subarray of this array will represent
-    // a single suggestion entry. The sub array must contain the following keys:
-    // - tid: (int) tid of the suggested term
-    // - name: (string) name of the suggested term
-    // - wording: (string) human friendly XSS escaped text of the suggestion
-    //   entry
-    $tags_return = array();
-
     // Firstly getting a list of tids that match by $term->name.
     $query = db_select('taxonomy_term_data', 't');
     $query->addTag('translatable');
@@ -116,9 +115,7 @@ function synonyms_autocomplete($field_name, $entity_type, $bundle, $tags_typed =
       ->range(0, $max_suggestions)
       ->execute();
     foreach ($result as $v) {
-      $v = (array) $v;
-      $v['wording'] = check_plain($v['name']);
-      $tags_return[] = $v;
+      $tags_return[] = (array) $v;
     }
 
     // Now we go vocabulary by vocabulary looking through synonym fields.
@@ -129,7 +126,7 @@ function synonyms_autocomplete($field_name, $entity_type, $bundle, $tags_typed =
       $behavior_implementations = synonyms_behavior_get('autocomplete', 'taxonomy_term', $bundle, TRUE);
       foreach ($behavior_implementations as $implementation) {
         $condition = db_and();
-        $condition->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like($tag_last) . '%', 'LIKE');
+        $condition->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like($tag_last) . '%', 'LIKE');
 
         if (!empty($tags_typed_tids)) {
           $condition->condition('entity_id', $tags_typed_tids, 'NOT IN');
@@ -149,7 +146,7 @@ function synonyms_autocomplete($field_name, $entity_type, $bundle, $tags_typed =
               'tid' => $synonym->entity_id,
               'name' => '',
               'synonym' => $synonym->synonym,
-              'implementation' => $implementation,
+              'behavior_implementation' => $implementation,
             );
             $new_tids[] = $synonym->entity_id;
           }
@@ -168,36 +165,202 @@ function synonyms_autocomplete($field_name, $entity_type, $bundle, $tags_typed =
       $synonym_terms = taxonomy_term_load_multiple($synonym_terms);
       foreach ($tags_return as &$v) {
         if (isset($v['synonym'])) {
-          $instance = field_info_instance($v['implementation']['entity_type'], $v['implementation']['field_name'], $v['implementation']['bundle']);
           $v['name'] = $synonym_terms[$v['tid']]->name;
-          $v['wording'] = format_string(filter_xss($v['implementation']['settings']['wording']), array(
-            '@synonym' => $v['synonym'],
-            '@term' => $v['name'],
-            '@field_name' => drupal_strtolower($instance['label']),
-          ));
         }
       }
     }
-    $prefix = empty($tags_typed) ? '' : drupal_implode_tags($tags_typed) . ', ';
-
     if (count($tags_return) > $max_suggestions) {
       $tags_return = array_slice($tags_return, 0, $max_suggestions);
     }
+  }
+  $prefix = empty($tags_typed) ? '' : drupal_implode_tags($tags_typed) . ', ';
+  drupal_json_output(synonyms_autocomplete_format($tags_return, $prefix));
+}
+
+/**
+ * Page callback: Outputs JSON for entity autocomplete suggestions.
+ *
+ * This callback outputs entity name suggestions in response to Ajax requests
+ * made by the synonyms autocomplete widget for entity reference fields. The
+ * output is a JSON object of plain-text entity suggestions, keyed by the
+ * user-entered value with the completed entity name appended. Entity names
+ * containing commas are wrapped in quotes. The search is made with
+ * consideration of synonyms.
+ *
+ * @param string $field_name
+ *   The name of the entity reference field.
+ * @param string $entity_type
+ *   Entity type to which the supplied $field_name is attached to
+ * @param string $bundle
+ *   Bundle name to which the supplied $field_name is attached to
+ * @param string $tags_typed
+ *   (optional) A comma-separated list of entity names entered in the
+ *   autocomplete form element. Only the last term is used for autocompletion.
+ *   Defaults to '' (an empty string).
+ */
+function synonyms_autocomplete_entity($field_name, $entity_type, $bundle, $tags_typed = '') {
+  // If the request has a '/' in the search text, then the menu system will have
+  // split it into multiple arguments, recover the intended $tags_typed.
+  $args = func_get_args();
+  // Shift off the $field_name argument.
+  array_shift($args);
+  // Shift off the $entity_type argument.
+  array_shift($args);
+  // Shift off the $bundle argument.
+  array_shift($args);
+  $tags_typed = implode('/', $args);
+
+  if (!($field = field_info_field($field_name)) || $field['type'] != 'entityreference') {
+    print t('Entity reference field @field_name not found.', array('@field_name' => $field_name));
+    exit;
+  }
+
+  if (!($instance = field_info_instance($entity_type, $field['field_name'], $bundle))) {
+    // Error string. The JavaScript handler will realize this is not JSON and
+    // will display it as debugging information.
+    print t('There was not found an instance of @field_name in @entity_type.', array(
+      '@field_name' => $field_name,
+      '@entity_type' => $entity_type,
+    ));
+    exit;
+  }
+
+  $widget = $instance['widget']['type'] == 'synonyms_autocomplete_entity' ? $instance['widget']['settings'] : field_info_widget_settings('synonyms_autocomplete_entity');
+
+  // How many suggestions maximum we are able to output.
+  $max_suggestions = $widget['suggestion_size'];
+
+  // Whether we are allowed to suggest more than one entry per term, shall that
+  // entry be either term name itself or one of its synonyms.
+  $suggest_only_unique = $widget['suggest_only_unique'];
+
+  $tags_typed = drupal_explode_tags($tags_typed);
+  $tag_last = drupal_strtolower(array_pop($tags_typed));
+  $prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : '';
+
+  $handler = entityreference_get_selection_handler($field, $instance, $entity_type, NULL);
+
+  $tags_typed_entity_ids = array();
+  if (!empty($tags_typed)) {
+    foreach ($handler->getReferencableEntities($tags_typed, 'IN') as $target_entity_ids) {
+      $tags_typed_entity_ids = array_merge($tags_typed_entity_ids, array_keys($target_entity_ids));
+    }
+  }
 
-    // Now formatting the results.
-    foreach ($tags_return as $info) {
-      $n = $info['name'];
-      // Term names containing commas or quotes must be wrapped in quotes.
-      if (strpos($info['name'], ',') !== FALSE || strpos($info['name'], '"') !== FALSE) {
-        $n = '"' . str_replace('"', '""', $info['name']) . '"';
+  $matches = array();
+  if ($tag_last) {
+    foreach ($handler->getReferencableEntities($tag_last) as $target_entity_ids) {
+      foreach (array_diff_key($target_entity_ids, drupal_map_assoc($tags_typed_entity_ids)) as $target_id => $label) {
+        $matches[] = array(
+          'target_id' => $target_id,
+          'name' => $label,
+        );
+        if (count($matches) == $max_suggestions) {
+          break (2);
+        }
       }
-      while (isset($term_matches[$prefix . $n])) {
-        $n .= ' ';
+    }
+
+    if (count($matches) < $max_suggestions) {
+      $behavior_implementations = synonyms_behavior_get('autocomplete', $field['settings']['target_type'], synonyms_field_target_bundles($field), TRUE);
+      foreach ($behavior_implementations as $implementation) {
+        $condition = db_and();
+        $condition->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like($tag_last) . '%', 'LIKE');
+
+        if (!empty($tags_typed_entity_ids)) {
+          $condition->condition('entity_id', $tags_typed_entity_ids, 'NOT IN');
+        }
+        if ($suggest_only_unique && !empty($matches)) {
+          $tmp = array();
+          foreach ($matches as $match) {
+            $tmp[] = $match['target_id'];
+          }
+          $condition->condition('entity_id', $tmp, 'NOT IN');
+        }
+
+        $new_target_ids = array();
+        foreach (synonyms_synonyms_find_behavior($condition, $implementation) as $synonym) {
+          if (!$suggest_only_unique || !in_array($synonym->entity_id, $new_target_ids)) {
+            $matches[] = array(
+              'target_id' => $synonym->entity_id,
+              'synonym' => $synonym->synonym,
+              'behavior_implementation' => $implementation,
+            );
+            $new_target_ids[] = $synonym->entity_id;
+            if (count($matches) == $max_suggestions) {
+              break (2);
+            }
+          }
+        }
       }
-      $term_matches[$prefix . $n] = $info['wording'];
+    }
+
+    $synonym_entities = array();
+    foreach ($matches as $match) {
+      if (!isset($match['wording']) && isset($match['synonym'])) {
+        $synonym_entities[] = $match['target_id'];
+      }
+    }
+    if (!empty($synonym_entities)) {
+      $synonym_entities = entity_load($field['settings']['target_type'], $synonym_entities);
+      foreach ($matches as $k => $match) {
+        if (!isset($match['name']) && isset($match['synonym'])) {
+          if (entity_access('view', $field['settings']['target_type'], $synonym_entities[$match['target_id']])) {
+            $matches[$k]['name'] = entity_label($field['settings']['target_type'], $synonym_entities[$match['target_id']]);
+          }
+          else {
+            unset($matches[$k]);
+          }
+        }
+      }
+      $matches = array_values($matches);
     }
   }
-  drupal_json_output($term_matches);
+
+  drupal_json_output(synonyms_autocomplete_format($matches, $prefix));
+}
+
+/**
+ * Supportive function to format autocomplete suggestions.
+ *
+ * @param array $matches
+ *   Array of matched entries. It should follow this structure:
+ *   - name: (string) String to be inserted into autocomplete textfield if user
+ *     chooses this autocomplete entry
+ *   - synonym: (string) If this entry is matched through a synonym, put that
+ *     synonym here
+ *   - behavior_implementation: (array) If this entry is matched through a
+ *     synonym, put here the behavior implementation array that provided this
+ *     match
+ * @param string $prefix
+ *   Any prefix to be appended to 'name' property of $matches array when
+ *   inserting into the autocomplete textfield. Normally it is the already
+ *   entered entries in the textfield
+ *
+ * @return array
+ *   Array of formatted autocomplete response entries ready to be returned to
+ *   the autocomplete JavaScript
+ */
+function synonyms_autocomplete_format($matches, $prefix) {
+  $output = array();
+
+  foreach ($matches as $match) {
+    $n = synonyms_autocomplete_escape($match['name']);
+    while (isset($output[$prefix . $n])) {
+      $n .= ' ';
+    }
+    $wording = check_plain($match['name']);
+    if (isset($match['synonym'])) {
+      $instance = synonyms_instance_id_load($match['behavior_implementation']['instance_id']);
+      $wording = format_string(filter_xss($match['behavior_implementation']['settings']['wording']), array(
+        '@entity' => $match['name'],
+        '@synonym' => $match['synonym'],
+        '@field_name' => drupal_strtolower($instance['label']),
+      ));
+    }
+    $output[$prefix . $n] = $wording;
+  }
+  return $output;
 }
 
 /**
@@ -238,3 +401,137 @@ function theme_synonyms_behaviors_settings($variables) {
 
   return '<div id="' . $element['#id'] . '">' . theme('table', $table) . drupal_render_children($element) . '</div>';
 }
+
+function synonyms_settings_overview() {
+  $output = array();
+
+  $output['table'] = array(
+    '#theme' => 'table',
+    '#header' => array(t('Entity type'), t('Bundle'), t('Manage')),
+    '#rows' => array(),
+  );
+
+  foreach (entity_get_info() as $entity_type => $entity_info) {
+    if (synonyms_entity_type_load($entity_type)) {
+      foreach ($entity_info['bundles'] as $bundle => $bundle_info) {
+        $output['table']['#rows'][] = array(
+          $entity_info['label'],
+          $bundle == $entity_type ? '' : $bundle_info['label'],
+          l(t('Edit'), 'admin/structure/synonyms/' . $entity_type . '/' . $bundle),
+        );
+      }
+    }
+  }
+
+  return $output;
+}
+
+/**
+ * Synonyms settings form for a specific entity type and bundle name.
+ *
+ * @param string $entity_type
+ *   Entity type for which to generate synonyms settings form
+ * @param string $bundle
+ *   Bundle name for which to generate synonyms settings form
+ */
+function synonyms_settings_form($form, &$form_state, $entity_type, $bundle) {
+  $form['settings'] = array(
+    '#tree' => TRUE,
+    '#theme' => 'synonyms_behaviors_settings',
+    '#id' => 'synonyms-behaviors-settings-wrapper',
+  );
+
+  $behaviors = synonyms_behaviors();
+
+  foreach ($behaviors as $behavior => $behavior_info) {
+    $form['settings'][$behavior] = array(
+      '#title' => $behavior_info['title'],
+    );
+
+    $behavior_implementations = synonyms_behavior_get($behavior, $entity_type, $bundle);
+
+    foreach ($behavior_implementations as $implementation) {
+      $instance = field_info_instance($implementation['entity_type'], $implementation['field_name'], $implementation['bundle']);
+      $form['settings'][$behavior][$implementation['instance_id']]['#title'] = $instance['label'];
+
+      if (isset($form_state['values']['settings'][$behavior][$implementation['instance_id']])) {
+        $behavior_settings = (bool) $form_state['values']['settings'][$behavior][$implementation['instance_id']]['enabled'];
+      }
+      else {
+        $behavior_settings = !is_null($implementation['settings']);
+      }
+
+      if ($behavior_settings) {
+        if (isset($form_state['values']['settings'][$behavior][$implementation['instance_id']]['settings'])) {
+          $behavior_settings = $form_state['values']['settings'][$behavior][$implementation['instance_id']]['settings'];
+        }
+        elseif ($implementation['settings']) {
+          $behavior_settings = $implementation['settings'];
+        }
+        else {
+          $behavior_settings = array();
+        }
+      }
+
+      $form['settings'][$behavior][$implementation['instance_id']]['enabled'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Enable'),
+        '#default_value' => $behavior_settings !== FALSE,
+      );
+
+      $settings_form = ctools_plugin_get_function($behavior_info, 'settings form callback');
+      if ($settings_form) {
+        $form['settings'][$behavior][$implementation['instance_id']]['enabled']['#ajax'] = array(
+          'callback' => 'synonyms_settings_form_ajax',
+          'wrapper' => $form['settings']['#id'],
+        );
+
+        if ($behavior_settings !== FALSE) {
+          $form['settings'][$behavior][$implementation['instance_id']]['settings'] = $settings_form($form, $form_state, $behavior_settings);
+        }
+      }
+    }
+  }
+
+  $form['actions'] = array(
+    '#type' => '#actions',
+  );
+
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+  );
+
+  return $form;
+}
+
+/**
+ * Submit handler for 'synonyms_settings_form' form.
+ *
+ * Store synonyms behavior settings.
+ */
+function synonyms_settings_form_submit($form, &$form_state) {
+  foreach ($form_state['values']['settings'] as $behavior => $settings) {
+    foreach ($settings as $instance_id => $behavior_settings) {
+      if ($behavior_settings['enabled']) {
+        synonyms_behavior_settings_save(array(
+          'instance_id' => $instance_id,
+          'behavior' => $behavior,
+          'settings' => isset($behavior_settings['settings']) ? $behavior_settings['settings'] : NULL,
+        ));
+      }
+      else {
+        synonyms_behavior_settings_delete($instance_id, $behavior);
+      }
+    }
+  }
+  drupal_set_message(t('Synonyms settings have been successfully saved.'));
+  $form_state['redirect'] = array('admin/structure/synonyms');
+}
+
+/**
+ * Ajax callback function for synonyms settings form.
+ */
+function synonyms_settings_form_ajax($form, &$form_state) {
+  return $form['settings'];
+}
diff --git a/synonyms.test b/synonyms.test
index 296929a..e58c47b 100644
--- a/synonyms.test
+++ b/synonyms.test
@@ -76,7 +76,7 @@ abstract class SynonymsWebTestCase extends DrupalWebTestCase {
    * SetUp method.
    */
   public function setUp($modules = array()) {
-    $modules[] = 'synonyms';
+    array_unshift($modules, 'synonyms');
     parent::setUp($modules);
 
     $this->admin = $this->drupalCreateUser(array(
@@ -140,15 +140,15 @@ abstract class SynonymsWebTestCase extends DrupalWebTestCase {
  */
 class SynonymsSynonymsWebTestCase extends SynonymsWebTestCase {
 
-  protected $behavior = 'synonyms';
+  protected $behavior = 'autocomplete';
 
   /**
    * GetInfo method.
    */
   public static function getInfo() {
     return array(
-      'name' => 'Taxonomy synonyms',
-      'description' => 'Ensure that the general "synonyms" behavior works correctly.',
+      'name' => 'Synonyms',
+      'description' => 'Ensure that the general synonyms functionality works correctly.',
       'group' => 'Synonyms',
     );
   }
@@ -235,11 +235,11 @@ class SynonymsSynonymsWebTestCase extends SynonymsWebTestCase {
     taxonomy_term_save($term);
 
     // Testing the 'synonyms' property of 'taxonomy_term' entity.
-    $synonyms = synonyms_get_sanitized($no_synonyms_term);
+    $synonyms = entity_metadata_wrapper('taxonomy_term', $no_synonyms_term)->synonyms->value();
     $this->assertTrue(empty($synonyms), 'Successfully retrieved synonyms_get_sanitized() for a term without synonyms.');
-    $synonyms = synonyms_get_sanitized($one_synonym_term);
+    $synonyms = entity_metadata_wrapper('taxonomy_term', $one_synonym_term)->synonyms->value();
     $this->assertTrue(count($synonyms) == 1 && $synonyms[0] == $synonym1, 'Successfully retrieved synonyms_get_sanitized() for a term with a single synonym.');
-    $synonyms = synonyms_get_sanitized($two_synonyms_term);
+    $synonyms = entity_metadata_wrapper('taxonomy_term', $two_synonyms_term)->synonyms->value();
     $this->assertTrue(count($synonyms) == 2 && $synonyms[0] == $synonym1 && $synonyms[1] == $synonym2, 'Successfully retrieved synonyms_get_sanitized() for a term with 2 synonyms.');
 
     // Testing the function synonyms_get_term_by_synonym().
@@ -270,18 +270,43 @@ class SynonymsSynonymsWebTestCase extends SynonymsWebTestCase {
     $tid = synonyms_add_term_by_synonym($term->{$this->fields['disabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'], $this->vocabulary);
     $new_term = taxonomy_term_load($tid);
     $this->assertNotEqual($new_term->tid, $term->tid, 'Successfully called synonyms_add_term_by_synonym() on a new title and a new term was created (due to a field not being engaged in "synonyms" behavior).');
+
+    // Testing the function synonyms_get_entity_by_synonym().
+    $another_vocabulary = (object) array(
+      'name' => $this->randomName(),
+      'machine_name' => 'another_bundle',
+    );
+    taxonomy_vocabulary_save($another_vocabulary);
+
+    $entity_id = synonyms_get_entity_by_synonym('taxonomy_term', $this->randomName());
+    $this->assertEqual($entity_id, 0, 'synonyms_get_entity_by_synonym() function returns 0 when fails to look up any entity.');
+
+    $entity_id = synonyms_get_entity_by_synonym('taxonomy_term', drupal_strtoupper($term_parent->name));
+    $this->assertEqual($entity_id, $term_parent->tid, 'synonyms_get_entity_by_synonym() function returns entity ID when a name of an existing entity is supplised.');
+
+    $entity_id = synonyms_get_entity_by_synonym('taxonomy_term', drupal_strtoupper($term_parent->name), $another_vocabulary->machine_name);
+    $this->assertEqual($entity_id, 0, 'synonyms_get_entity_by_synonym() returns 0 if an existing entity name is provided, but the search is conducted within another bundle.');
+
+    $entity_id = synonyms_get_entity_by_synonym('taxonomy_term', drupal_strtolower($synonym2));
+    $this->assertEqual($entity_id, $two_synonyms_term->tid, 'synonyms_get_entity_by_synonym() returns entity ID when a synonym of that entity is supplied.');
+
+    $entity_id = synonyms_get_entity_by_synonym('taxonomy_term', drupal_strtolower($parent_synonym), $another_vocabulary->machine_name);
+    $this->assertEqual($entity_id, 0, 'synonyms_get_entity_by_synonym() returns 0 if a synonym of an existing entity is supplied, but the search is conducted within another bundle.');
+
+    $entity_id = synonyms_get_entity_by_synonym('taxonomy_term', $term_parent->{$this->fields['disabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']);
+    $this->assertEqual($entity_id, 0, 'synonyms_get_entity_by_synonym() returns 0 if a non-synonym field value is supplied.');
   }
 }
 
 /**
  * Test "Synonyms friendly autocomplete" widget of Synonyms module.
  */
-class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
+abstract class AbstractAutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
 
   protected $behavior = 'autocomplete';
 
   protected $behavior_settings = array(
-    'wording' => '@synonym @field_name @term',
+    'wording' => '@synonym @field_name @entity',
   );
 
   /**
@@ -311,18 +336,15 @@ class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
    *
    * @var array
    */
-  protected $term_reference_field = array();
+  protected $reference_field = array();
 
   /**
-   * GetInfo method.
+   * Field instance definition array of the field that will be attached to
+   * $this->entity_type with synonyms friendly autocomplete widget.
+   *
+   * @var array
    */
-  public static function getInfo() {
-    return array(
-      'name' => 'Taxonomy synonyms autocomplete',
-      'description' => 'Ensure that the "synonym friendly autocomplete" widget works correctly with taxonomy terms.',
-      'group' => 'Synonyms',
-    );
-  }
+  protected $reference_instance = array();
 
   /**
    * SetUp method.
@@ -335,33 +357,6 @@ class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
       'name' => 'Synonyms Test Content',
       'type' => $this->bundle,
     ), 'Save content type');
-
-    $this->term_reference_field = array(
-      'type' => 'taxonomy_term_reference',
-      'field_name' => 'synonyms_term_enabled',
-      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'settings' => array(
-        'allowed_values' => array(
-          array(
-            'vocabulary' => $this->vocabulary->machine_name,
-            'parent' => 0,
-          ),
-        ),
-      ),
-    );
-    $this->term_reference_field = field_create_field($this->term_reference_field);
-
-    $instance = array(
-      'field_name' => $this->term_reference_field['field_name'],
-      'entity_type' => 'node',
-      'bundle' => $this->bundle,
-      'label' => 'Synonym Terms Autcomplete',
-      'widget' => array(
-        'type' => 'synonyms_autocomplete',
-      ),
-    );
-    $instance = field_create_instance($instance);
-
     drupal_static_reset();
 
     // Now creating taxonomy tree.
@@ -510,48 +505,6 @@ class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
   }
 
   /**
-   * Test auto-creation functionality.
-   *
-   * Test the auto-creation functionality of the synonym friendly autocomplete
-   * widget type. Along the way it tests whether synonyms, submitted into the
-   * widget's textfield are converted into the terms, synonyms of which they
-   * are.
-   */
-  public function testAutoCreation() {
-    // Trying enabled auto creation.
-    $this->drupalPost('admin/structure/types/manage/synonyms-test-content/fields/synonyms_term_enabled', array(
-      'instance[widget][settings][auto_creation]' => TRUE,
-    ), 'Save settings');
-
-    $new_term_name = $this->terms['no_synonyms']->{$this->fields['disabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
-    $this->drupalPost('node/add/synonyms-test-content', array(
-      'title' => $this->randomName(),
-      'synonyms_term_enabled[' . LANGUAGE_NONE . ']' => $this->terms['no_synonyms']->name . ', ' . $new_term_name . ', ' . $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
-    ), 'Save');
-    $this->assertText($this->terms['no_synonyms']->name, 'Existing term was assigned to the new node');
-    $this->assertText($new_term_name, 'Auto created term was assigned to the new node when Auto creation is on.');
-    $this->assertText($this->terms['one_synonym']->name, 'Submitting a synonym into autocomplete widget results in the term, to which the synonym belongs, being assigned to the just created entity (when Auto creation is on).');
-    $term = $this->getLastTerm($this->vocabulary);
-    $this->assertEqual($term->name, $new_term_name, 'The auto created term has been created when Auto creation is on.');
-
-    // Trying disabled auto creation.
-    $this->drupalPost('admin/structure/types/manage/synonyms-test-content/fields/synonyms_term_enabled', array(
-      'instance[widget][settings][auto_creation]' => FALSE,
-    ), 'Save settings');
-
-    $new_term_name = $this->terms['term1']->{$this->fields['disabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
-    $this->drupalPost('node/add/synonyms-test-content', array(
-      'title' => $this->randomName(),
-      'synonyms_term_enabled[' . LANGUAGE_NONE . ']' => $this->terms['no_synonyms']->name . ', ' . $new_term_name . ', ' . $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
-    ), 'Save');
-    $this->assertText($this->terms['no_synonyms']->name, 'Existing term was assigned to the new node');
-    $this->assertNoText($new_term_name, 'Auto created term was not assigned to the new node when Auto creation is off.');
-    $this->assertText($this->terms['one_synonym']->name, 'Submitting a synonym into autocomplete widget results in the term, to which the synonym belongs, being assigned to the just created entity (when Auto creation is off).');
-    $term = $this->getLastTerm($this->vocabulary);
-    $this->assertNotEqual($term->name, $new_term_name, 'The auto created term has not been created when Auto creation is off.');
-  }
-
-  /**
    * Test autocomplete menu path.
    *
    * Feed all known "buggy" input to synonym friendly autocomplete menu path,
@@ -612,6 +565,115 @@ class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
       $this->terms['one_synonym']->name => $this->synonymAutocompleteResult($this->terms['one_synonym'], $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'], $this->fields['enabled']['instance']),
       $this->terms['one_synonym']->name . ' ' => $this->synonymAutocompleteResult($this->terms['one_synonym'], $this->terms['one_synonym']->{$this->fields['disabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'], $this->fields['disabled']['instance']),
     ), 'Autocomplete works correctly when more than 1 field participates in the autocomplete behavior.');
+    synonyms_behavior_settings_delete($this->fields['disabled']['instance']['id'], $this->behavior);
+
+    // Submit a name that is similar to one of our terms and is similar to a
+    // a term from another vocabulary, which should not participate in the
+    // autocomplete. We do this trick in different flavors, all with the idea
+    // to make sure the bundles that should not participate in the field values
+    // are not suggested by the autocomplete menu path. The different flavors
+    // are:
+    // - non valid term similar to valid term
+    // - non valid term similar to valid synonym
+    // - non valid synonym similar to valid term
+    // - non valid synonym similar to valid synonym
+    $another_vocabulary = (object) array(
+      'name' => $this->randomName(),
+      'machine_name' => 'another_vocabulary',
+    );
+    taxonomy_vocabulary_save($another_vocabulary);
+    $instance = field_create_instance(array(
+      'field_name' => $this->fields['enabled']['field']['field_name'],
+      'entity_type' => 'taxonomy_term',
+      'bundle' => $another_vocabulary->machine_name,
+    ));
+    $instance = field_info_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']);
+    synonyms_behavior_settings_save(array(
+      'instance_id' => $instance['id'],
+      'behavior' => $this->behavior,
+      'settings' => $this->behavior_settings,
+    ));
+
+    $term_similar_term = (object) array(
+      'name' => $this->terms['no_synonyms']->name,
+      'vid' => $another_vocabulary->vid,
+    );
+    taxonomy_term_save($term_similar_term);
+    $this->assertAutocompleteMenuPath($this->terms['no_synonyms']->name, array(
+      $this->terms['no_synonyms']->name => $this->terms['no_synonyms']->name,
+    ), 'Submitting term name similar to term from another bundle does not include the term from another bundle.');
+
+    $term_similar_synonym = (object) array(
+      'name' => $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'vid' => $another_vocabulary->vid,
+    );
+    taxonomy_term_save($term_similar_synonym);
+    $this->assertAutocompleteMenuPath($term_similar_synonym->name, array(
+      $this->terms['one_synonym']->name => $this->synonymAutocompleteResult($this->terms['one_synonym'], $term_similar_synonym->name, $this->fields['enabled']['instance']),
+    ), 'Submitting synonym similar to term from another bundle does not include the term from another bundle.');
+
+    $synonym_similar_term = (object) array(
+      'name' => $this->randomName(),
+      'vid' => $another_vocabulary->vid,
+      $this->fields['enabled']['field']['field_name'] => array(LANGUAGE_NONE => array(
+        $this->terms['no_synonyms']->name,
+      )),
+    );
+    taxonomy_term_save($synonym_similar_term);
+    $this->assertAutocompleteMenuPath($this->terms['no_synonyms']->name, array(
+      $this->terms['no_synonyms']->name => $this->terms['no_synonyms']->name,
+    ), 'Submitting term name similar to a synonym of a term from another bundle does not include the term from another bundle.');
+
+    $synonym_similar_synonym = (object) array(
+      'name' => $this->randomName(),
+      'vid' => $another_vocabulary->vid,
+      $this->fields['enabled']['field']['field_name'] => array(LANGUAGE_NONE => array(
+        $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      )),
+    );
+    taxonomy_term_save($synonym_similar_synonym);
+    $this->assertAutocompleteMenuPath($this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'], array(
+      $this->terms['one_synonym']->name => $this->synonymAutocompleteResult($this->terms['one_synonym'], $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'], $this->fields['enabled']['instance'])
+    ), 'Submitting synonym similar to a synonym of a term from another bundle does not includde the term from another bundle.');
+  }
+
+  /**
+   * Test autocomplete text field validation.
+   *
+   * In particular, this test does the following:
+   * - test submitting a synonym into the text field (that should be converted
+   *   into its entity)
+   * - test submitting the same entity name twice (only one reference should be
+   *   saved)
+   * - test submitting entity name and one of its synonyms (only one reference
+   *   should be saved)
+   * - test submitting 2 different synonyms of the same entity (only one
+   *   reference should be saved)
+   */
+  public function testAutocompleteTextField() {
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $this->randomName(),
+      'synonyms_term_enabled[' . LANGUAGE_NONE . ']' => $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    ), 'Save');
+    $this->assertText($this->terms['one_synonym']->name, 'Submitting a synonym into autocomplete text field results into term being saved.');
+
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $this->randomName(),
+      'synonyms_term_enabled[' . LANGUAGE_NONE . ']' => drupal_implode_tags(array($this->terms['one_synonym']->name, $this->terms['one_synonym']->name)),
+    ), 'Save');
+    $this->assertUniqueText($this->terms['one_synonym']->name, 'Submitting the same term name twice into autocomplete text field results in saving the term only once in the field.');
+
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $this->randomName(),
+      'synonyms_term_enabled[' . LANGUAGE_NONE . ']' => drupal_implode_tags(array($this->terms['one_synonym']->name, $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'])),
+    ), 'Save');
+    $this->assertUniqueText($this->terms['one_synonym']->name, 'Submitting term name and one of its synonyms results in saving the term only once in the field.');
+
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $this->randomName(),
+      'synonyms_term_enabled[' . LANGUAGE_NONE . ']' => drupal_implode_tags(array($this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'], $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'])),
+    ), 'Save');
+    $this->assertUniqueText($this->terms['two_synonyms']->name, 'Submitting 2 different synonyms of the same term results in saving the term only once in the field.');
   }
 
   /**
@@ -619,19 +681,18 @@ class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
    */
   public function testWidgetSettingsSuggestionSize() {
     $suggestion_size = 1;
-    $this->drupalPost('admin/structure/types/manage/synonyms-test-content/fields/synonyms_term_enabled', array(
-      'instance[widget][settings][suggestion_size]' => $suggestion_size,
-    ), 'Save settings');
+    $this->reference_instance['widget']['settings']['suggestion_size'] = $suggestion_size;
+    field_update_instance($this->reference_instance);
 
     // If size was bigger than 1, we'd get suggested 2 terms: 'term1' and
     // 'term1_longer_name'.
     $this->assertAutocompleteMenuPath($this->terms['term1']->name, array(
       $this->terms['term1']->name => $this->terms['term1']->name,
-    ), 'Suggestions Size option is respected in autocomplete widget for term suggestion entries.');
+    ), 'Suggestions Size option is respected in autocomplete widget for entity suggestion entries.');
 
     $this->assertAutocompleteMenuPath($this->terms['name_similar_synonym']->name, array(
       $this->terms['name_similar_synonym']->name => $this->terms['name_similar_synonym']->name,
-    ), 'Suggestions Size option is respected in autocomplete widget for term and synonym suggestion entries.');
+    ), 'Suggestions Size option is respected in autocomplete widget for entity and synonym suggestion entries.');
 
     $this->assertAutocompleteMenuPath(drupal_substr($this->terms['similar_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'], 0, 8), array(
       $this->terms['similar_synonyms']->name => $this->synonymAutocompleteResult($this->terms['similar_synonyms'], $this->terms['similar_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'], $this->fields['enabled']['instance']),
@@ -639,7 +700,7 @@ class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
 
     $this->assertAutocompleteMenuPath('one_term_name_another_synonym_', array(
       $this->terms['name_another_synonym']->name => $this->terms['name_another_synonym']->name,
-    ), 'Suggestions Size option is respected in autocomplete widget for the case when there is match by term name and by synonyms; and preference is given to the match by term name.');
+    ), 'Suggestions Size option is respected in autocomplete widget for the case when there is match by entity name and by synonyms; and preference is given to the match by entity name.');
   }
 
   /**
@@ -683,7 +744,7 @@ class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
    *   Drupal assertion message to be displayed on the rest results page
    */
   protected function assertAutocompleteMenuPath($input, $standard, $message) {
-    $response = $this->drupalGet('synonyms/autocomplete/' . $this->term_reference_field['field_name']  . '/' . $this->entity_type . '/' . $this->bundle . '/' . $input);
+    $response = $this->drupalGet($this->reference_instance['widget']['settings']['synonyms_autocomplete_path'] . '/' . $this->reference_field['field_name']  . '/' . $this->entity_type . '/' . $this->bundle . '/' . $input);
     if (!$response) {
       $this->fail($message, 'Autocomplete Menu Path');
       return;
@@ -698,36 +759,168 @@ class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
   /**
    * Return expected autocomplete menu path result.
    *
-   * The result is prepared as if the term was found by the supplied synonym.
+   * The result is prepared as if the entity was found by the supplied synonym.
    *
-   * @param object $term
-   *   Fully loaded taxonomy term object for which the result is generated.
+   * @param object $entity
+   *   Fully loaded entity for which the result is generated.
    * @param string $synonym
-   *   Synonym by which the term was hit in the search
+   *   Synonym by which the entity was hit in the search
    * @param array $instance
    *   Instance definition array which the $synonym originates from
    *
    * @return string
    *   Formatted autocomplete result
    */
-  protected function synonymAutocompleteResult($term, $synonym, $instance) {
+  protected function synonymAutocompleteResult($entity, $synonym, $instance) {
     return format_string($this->behavior_settings['wording'], array(
       '@synonym' => $synonym,
-      '@term' => $term->name,
+      '@entity' => entity_label($this->fields['enabled']['instance']['entity_type'], $entity),
       '@field_name' => drupal_strtolower($instance['label']),
     ));
   }
 }
 
 /**
+ * Test synonyms friendly autocomplete widget for taxonomy term reference field.
+ */
+class TaxonomyTermReferenceAutocompleteSynonymsWebTestCase extends AbstractAutocompleteSynonymsWebTestCase {
+
+  /**
+   * GetInfo method.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Taxonomy synonyms autocomplete',
+      'description' => 'Ensure that the "synonym friendly autocomplete" widget works correctly with taxonomy term reference field type.',
+      'group' => 'Synonyms',
+    );
+  }
+
+  public function setUp($modules = array()) {
+    parent::setUp($modules);
+
+    $this->reference_field = array(
+      'type' => 'taxonomy_term_reference',
+      'field_name' => 'synonyms_term_enabled',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'allowed_values' => array(
+          array(
+            'vocabulary' => $this->vocabulary->machine_name,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+    $this->reference_field = field_create_field($this->reference_field);
+
+    $this->reference_instance = array(
+      'field_name' => $this->reference_field['field_name'],
+      'entity_type' => 'node',
+      'bundle' => $this->bundle,
+      'label' => 'Synonym Terms Autcomplete',
+      'widget' => array(
+        'type' => 'synonyms_autocomplete_taxonomy_term',
+      ),
+    );
+    $this->reference_instance['widget']['settings'] = field_info_widget_settings($this->reference_instance['widget']['type']);
+    $this->reference_instance = field_create_instance($this->reference_instance);
+  }
+
+  /**
+   * Test auto-creation functionality.
+   *
+   * Test the auto-creation functionality of the synonym friendly autocomplete
+   * widget type for taxonomy term reference field type.
+   */
+  public function testAutoCreation() {
+    // Trying enabled auto creation.
+    $this->reference_instance['widget']['settings']['auto_creation'] = TRUE;
+    field_update_instance($this->reference_instance);
+
+    $new_term_name = $this->terms['no_synonyms']->{$this->fields['disabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $this->randomName(),
+      'synonyms_term_enabled[' . LANGUAGE_NONE . ']' => $this->terms['no_synonyms']->name . ', ' . $new_term_name . ', ' . $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    ), 'Save');
+    $this->assertText($this->terms['no_synonyms']->name, 'Existing term was assigned to the new node');
+    $this->assertText($new_term_name, 'Auto created term was assigned to the new node when Auto creation is on.');
+    $this->assertText($this->terms['one_synonym']->name, 'Submitting a synonym into autocomplete widget results in the term, to which the synonym belongs, being assigned to the just created entity (when Auto creation is on).');
+    $term = $this->getLastTerm($this->vocabulary);
+    $this->assertEqual($term->name, $new_term_name, 'The auto created term has been created when Auto creation is on.');
+
+    // Trying disabled auto creation.
+    $this->reference_instance['widget']['settings']['auto_creation'] = FALSE;
+    field_update_instance($this->reference_instance);
+
+    $new_term_name = $this->terms['term1']->{$this->fields['disabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $this->randomName(),
+      'synonyms_term_enabled[' . LANGUAGE_NONE . ']' => $this->terms['no_synonyms']->name . ', ' . $new_term_name . ', ' . $this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    ), 'Save');
+    $this->assertText($this->terms['no_synonyms']->name, 'Existing term was assigned to the new node');
+    $this->assertNoText($new_term_name, 'Auto created term was not assigned to the new node when Auto creation is off.');
+    $this->assertText($this->terms['one_synonym']->name, 'Submitting a synonym into autocomplete widget results in the term, to which the synonym belongs, being assigned to the just created entity (when Auto creation is off).');
+    $term = $this->getLastTerm($this->vocabulary);
+    $this->assertNotEqual($term->name, $new_term_name, 'The auto created term has not been created when Auto creation is off.');
+  }
+}
+
+/**
+ * Test synonyms friendly autocomplete widget for entity reference field type.
+ */
+class EntityReferenceAutocompleteSynonymsWebTestCase extends AbstractAutocompleteSynonymsWebTestCase {
+
+  /**
+   * GetInfo method.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity reference synonyms autocomplete',
+      'description' => 'Ensure that the "synonym friendly autocomplete" widget works correctly with entityreference field type.',
+      'group' => 'Synonyms',
+    );
+  }
+
+  public function setUp($modules = array()) {
+    parent::setUp($modules);
+
+    $this->reference_field = array(
+      'type' => 'entityreference',
+      'field_name' => 'synonyms_term_enabled',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'target_type' => 'taxonomy_term',
+        'handler_settings' => array(
+          'target_bundles' => drupal_map_assoc(array($this->fields['enabled']['instance']['bundle'])),
+        ),
+      ),
+    );
+    $this->reference_field = field_create_field($this->reference_field);
+
+    $this->reference_instance = array(
+      'field_name' => $this->reference_field['field_name'],
+      'entity_type' => 'node',
+      'bundle' => $this->bundle,
+      'label' => 'Synonym Entity Autcomplete',
+      'widget' => array(
+        'type' => 'synonyms_autocomplete_entity',
+      ),
+    );
+    $this->reference_instance['widget']['settings'] = field_info_widget_settings($this->reference_instance['widget']['type']);
+    $this->reference_instance = field_create_instance($this->reference_instance);
+  }
+}
+
+/**
  * Test "Synonyms friendly select" widget of Synonyms module.
  */
-class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
+abstract class AbstractSelectSynonymsWebTestCase extends SynonymsWebTestCase {
 
   protected $behavior = 'select';
 
   protected $behavior_settings = array(
-    'wording' => '@synonym @term @field_name',
+    'wording' => '@synonym @entity @field_name',
   );
 
   /**
@@ -738,14 +931,14 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
   protected $terms = array();
 
   /**
-   * Entity type to which a term reference field with tested widget is attached.
+   * Entity type to which a field with tested widget is attached.
    *
    * @var string
    */
   protected $entity_type = 'node';
 
   /**
-   * Bundle to which a term reference field with tested widget is attached.
+   * Bundle to which a field with tested widget is attached.
    *
    * @var string
    */
@@ -757,12 +950,547 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
    *
    * @var array
    */
-  protected $term_reference_field = array();
+  protected $reference_field = array();
+
+  /**
+   * Field instance definition array of the field that will be attached to
+   * $this->entity_type with synonyms friendly select widget.
+   *
+   * @var array
+   */
+  protected $reference_instance = array();
+
+  public function setUp($modules = array()) {
+    parent::setUp($modules);
+
+    // Creating a test content type.
+    $this->drupalPost('admin/structure/types/add', array(
+      'name' => 'Synonyms Test Content',
+      'type' => $this->bundle,
+    ), 'Save content type');
+
+    $this->terms['parent_term'] = (object) array(
+      'vid' => $this->vocabulary->vid,
+      'name' => 'Parent Term',
+      $this->fields['enabled']['field']['field_name'] => array(
+        LANGUAGE_NONE => array(
+          array('value' => 'Parent TermA' . $this->randomName()),
+          array('value' => 'Parent TermZ' . $this->randomName()),
+        ),
+      ),
+    );
+    taxonomy_term_save($this->terms['parent_term']);
+
+    $this->terms['child_term'] = (object) array(
+      'vid' => $this->vocabulary->vid,
+      'name' => 'Child Term',
+      'parent' => $this->terms['parent_term']->tid,
+      $this->fields['enabled']['field']['field_name'] => array(
+        LANGUAGE_NONE => array(
+          array('value' => 'Child TermZ' . $this->randomName()),
+          array('value' => 'Child TermA' . $this->randomName()),
+        ),
+      ),
+    );
+    taxonomy_term_save($this->terms['child_term']);
+
+    $this->terms['normal_term'] = (object) array(
+      'vid' => $this->vocabulary->vid,
+      'name' => 'Normal Term',
+      $this->fields['enabled']['field']['field_name'] => array(
+        LANGUAGE_NONE => array(
+          array('value' => 'Normal TermA' . $this->randomName()),
+          array('value' => 'Normal TermZ' . $this->randomName()),
+        ),
+      ),
+    );
+    taxonomy_term_save($this->terms['normal_term']);
+  }
+
+  /**
+   * Test sorting options of the widget.
+   */
+  abstract public function testWidgetSorting();
+
+  /**
+   * Test main functionality of the widget.
+   */
+  abstract public function testWidget();
+
+  /**
+   * Assert correctness of the synonyms-friendly select widget.
+   *
+   * @param array $options
+   *   Array of what options must be present in the select form element. It
+   *   should consist of arrays that follow such structure:
+   *   - entity: (object) Entity this option represents
+   *   - synonym: (string) If the option comes from a synonym, then include it
+   *     here
+   *   - selected: (bool) Place here TRUE if this option should be selected by
+   *     default
+   * @param string $message
+   *   Assert message that will be passed on to SimpleTest internals
+   */
+  protected function assertSynonymsSelect($options, $message = '') {
+    $multiple = $this->reference_field['cardinality'] > 1 || $this->reference_field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;
+
+    $element = array(
+      '#options' => array(),
+      '#value' => $multiple ? array() : 'nothing',
+    );
+
+    if (!$multiple) {
+      $element['#options'][''] = t('- None -');
+    }
+
+    foreach ($options as $v) {
+      if (!isset($v['synonym'])) {
+        $v['synonym'] = NULL;
+      }
+      $key = $this->synonymSelectKey($v['entity'], $v['synonym']);
+      $label = entity_label($this->fields['enabled']['instance']['entity_type'], $v['entity']);
+      if ($v['synonym']) {
+        $label = format_string($this->behavior_settings['wording'], array(
+          '@synonym' => $v['synonym'],
+          '@entity'=> $label,
+          '@field_name' => $this->fields['enabled']['instance']['label'],
+        ));
+      }
+
+      if (isset($v['selected']) && $v['selected']) {
+        if ($multiple) {
+          $element['#value'][] = $key;
+        }
+        else {
+          $element['#value'] = $key;
+        }
+      }
+
+      $element['#options'][$key] = $this->synonymsSelectOptionPrefix($v['entity'], $v['synonym']) . $label;
+    }
+    debug(form_select_options($element));
+    $this->assertRaw('>' . form_select_options($element) . '</select>', $message, 'Synonyms friendly select');
+  }
+
+  /**
+   * Generate necessary prefix before the main wording of the label in select.
+   *
+   * It may be useful to insert some kind of hiderarchy indention, for example.
+   *
+   * @param object $entity
+   *   Fully loaded entity object whose prefix is requested in the option label
+   *   of the synonyms friendly select widget
+   * @param string $synonym
+   *   If this option comes from a synonym, that synonym will be supplied here
+   *
+   * @return string
+   *   Any suitable prefix before the main wording of the option for this
+   *   particular option
+   */
+  protected function synonymsSelectOptionPrefix($entity, $synonym = NULL) {
+    return '';
+  }
+
+  /**
+   * Form a key for the option of a synonyms friendly select.
+   *
+   * @param object $entity
+   *   Fully loaded entity for which to generate the key
+   * @param string $synonym
+   *   If the option, whose key is being generated, comes from a synonym, then
+   *   supply it here
+   *
+   * @return string
+   *   Key for the option of a synonym friendly select
+   */
+  protected function synonymSelectKey($entity, $synonym = NULL) {
+    $entity_id = entity_extract_ids($this->fields['enabled']['instance']['entity_type'], $entity);
+    $key = $entity_id[0];
+    if ($synonym) {
+      $key .= ':' . drupal_html_class($synonym);
+    }
+    return $key;
+  }
+}
+
+/**
+ * Test synonyms friendly select widget for taxonomy term reference field.
+ */
+class TaxonomyTermReferenceSelectSynonymsWebTestCase extends AbstractSelectSynonymsWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Taxonomy synonyms select',
+      'description' => 'Ensure that the "synonym friendly select" widget works correctly with taxonomy term reference field.',
+      'group' => 'Synonyms',
+    );
+  }
+
+  public function setUp($modules = array()) {
+    parent::setUp($modules);
+
+    $this->reference_field = array(
+      'type' => 'taxonomy_term_reference',
+      'field_name' => 'synonyms_term',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'allowed_values' => array(
+          array(
+            'vocabulary' => $this->vocabulary->machine_name,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+    $this->reference_field = field_create_field($this->reference_field);
+
+    $this->reference_instance = array(
+      'field_name' => $this->reference_field['field_name'],
+      'entity_type' => 'node',
+      'bundle' => $this->bundle,
+      'label' => 'Synonym Terms Select',
+      'widget' => array(
+        'type' => 'synonyms_select_taxonomy_term',
+      ),
+    );
+    $this->reference_instance = field_create_instance($this->reference_instance);
+  }
+
+  public function testWidgetSorting() {
+    $cardinality = array(
+      1 => 1,
+      FIELD_CARDINALITY_UNLIMITED => 'unlimited',
+    );
+    $required = array(
+      TRUE => 'required',
+      FALSE => 'not required',
+    );
+
+    foreach ($cardinality as $cardinality_k => $cardinality_v) {
+      foreach ($required as $required_k => $required_v) {
+        $this->reference_field['cardinality'] = $cardinality_k;
+        field_update_field($this->reference_field);
+
+        $this->reference_instance['required'] = $required_k;
+        $this->reference_instance['widget']['settings']['sort'] = 'weight';
+        field_update_instance($this->reference_instance);
+
+        $this->terms['parent_term']->weight = 0;
+        taxonomy_term_save($this->terms['parent_term']);
+
+        $options = array();
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $this->drupalGet('node/add/synonyms-test-content');
+        $this->assertSynonymsSelect($options, 'Synonyms select sorting by weight works for the cardinality of ' . $cardinality_v . ' and ' . $required_v);
+
+        $this->terms['parent_term']->weight = -1000;
+        taxonomy_term_save($this->terms['parent_term']);
+        $options = array();
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $this->drupalGet('node/add/synonyms-test-content');
+        $this->assertSynonymsSelect($options, 'Synonyms select sorting by weight works after changing weights of terms for the cardinality of ' . $cardinality_v . ' and ' . $required_v);
+
+        $this->reference_instance['widget']['settings']['sort'] = 'name';
+        field_update_instance($this->reference_instance);
+
+        $options = array();
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['normal_term'],
+          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['child_term'],
+          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+        );
+        $options[] = array(
+          'entity' => $this->terms['parent_term'],
+          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+        );
+        $this->drupalGet('node/add/synonyms-test-content');
+        $this->assertSynonymsSelect($options, 'Synonyms select sorting by name works for the cardinality of ' . $cardinality_v . ' and ' . $required_v);
+      }
+    }
+  }
+
+  public function testWidget() {
+    $name = $this->randomName();
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $name,
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
+        $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
+        $this->terms['child_term']->tid,
+        $this->terms['normal_term']->tid,
+        $this->synonymSelectKey($this->terms['normal_term'], $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
+      ),
+    ), 'Save');
+
+    $node = $this->drupalGetNodeByTitle($name);
+    $this->drupalGet('node/' . $node->nid);
+    $this->assertText($this->terms['parent_term']->name, 'Term is saved when its synonym is submitted through synonyms friendly select for the unlimited cardinality.');
+    $this->assertText($this->terms['child_term']->name, 'Term is saved when it is submitted through synonyms friendly select for the unlimited cardinality.');
+    $this->assertUniqueText($this->terms['normal_term']->name, 'Term is saved only once when the term and its synonym are submitted through synonyms friendly select for the unlimited cardinality.');
+
+    $options = array();
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+      'selected' => TRUE,
+    );
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+      'selected' => TRUE,
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+      'selected' => TRUE,
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $this->drupalGet('node/' . $node->nid . '/edit');
+    $this->assertSynonymsSelect($options, 'Default values are set correctly in the synonyms friendly select widget when working with field cardinality more than 1.');
+
+    $this->reference_field['cardinality'] = 2;
+    field_update_field($this->reference_field);
+    $name = $this->randomName();
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $name,
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
+        $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
+        $this->terms['child_term']->tid,
+        $this->terms['normal_term']->tid,
+      ),
+    ), 'Save');
+    $this->assertText('this field cannot hold more than 2 values.', 'Submitting 3 entries into a field with cardinality of 2, that refer to 3 terms, results in a form error.');
+
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $name,
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
+        $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
+        $this->terms['normal_term']->tid,
+        $this->synonymSelectKey($this->terms['normal_term'], $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
+      ),
+    ), 'Save');
+    $node = $this->drupalGetNodeByTitle($name);
+    $this->drupalGet('node/' .  $node->nid);
+    $this->assertUniqueText($this->terms['parent_term']->name, 'Submitting 3 entries into a field with cardinality of 2, that refer to only 2 terms, results in form getting submitted. Term #1 is saved.');
+    $this->assertUniqueText($this->terms['normal_term']->name, 'Term #2 is saved.');
+
+    $this->reference_field['cardinality'] = 1;
+    field_update_field($this->reference_field);
+    $name = $this->randomName();
+    $this->drupalPost('node/add/synonyms-test-content', array(
+      'title' => $name,
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . ']' => $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
+    ), 'Save');
+    $node = $this->drupalGetNodeByTitle($name);
+    $this->drupalGet('node/' . $node->nid);
+    $this->assertText($this->terms['parent_term']->name, 'Term is saved when its synonym is submitted through synonyms friendly select for the cardinality of 1.');
+
+    $options = array();
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+      'selected' => TRUE,
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $this->drupalGet('node/' .  $node->nid . '/edit');
+    $this->assertSynonymsSelect($options, 'Default values are set correctly in the synonyms friendly select widget when working with the field cardinality of 1.');
+
+    $this->drupalPost('node/' . $node->nid . '/edit', array(
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . ']' => $this->terms['child_term']->tid,
+    ), 'Save');
+    $this->drupalGet('node/' . $node->nid);
+    $this->assertNoText($this->terms['parent_term']->name, 'After updating entity the old term is removed.');
+    $this->assertText($this->terms['child_term']->name, 'Term is saved when it is submitted through synonyms friendly select for the cardinality of 1.');
+
+    $options = array();
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+      'selected' => TRUE,
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+    );
+    $options[] = array(
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+    );
+    $this->drupalGet('node/' .  $node->nid . '/edit');
+    $this->assertSynonymsSelect($options, 'Default values are set correctly in the synonyms friendly select widget when working with the field cardinality of 1.');
+  }
+
+  protected function synonymsSelectOptionPrefix($entity, $synonym = NULL) {
+    $depth = count(taxonomy_get_parents_all($entity->tid)) - 1;
+    return str_repeat('-', $depth) . parent::synonymsSelectOptionPrefix($entity, $synonym);
+  }
+}
+
+/**
+ * Test synonyms friendly select widget for entity reference field type.
+ */
+class EntityReferenceSeelectSynonymsWebTestCase extends AbstractSelectSynonymsWebTestCase {
 
   public static function getInfo() {
     return array(
-      'name' => 'Synonyms friendly select',
-      'description' => 'Ensure that the "synonym friendly select" widget works correctly with taxonomy terms.',
+      'name' => 'Entity reference synonyms select',
+      'description' => 'Ensure that the "synonym friendly select" widget works correctly with entity reference field.',
       'group' => 'Synonyms',
     );
   }
@@ -770,79 +1498,29 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
   public function setUp($modules = array()) {
     parent::setUp($modules);
 
-    // Creating a test content type.
-    $this->drupalPost('admin/structure/types/add', array(
-      'name' => 'Synonyms Test Content',
-      'type' => $this->bundle,
-    ), 'Save content type');
-
-    $this->term_reference_field = array(
-      'type' => 'taxonomy_term_reference',
+    $this->reference_field = array(
+      'type' => 'entityreference',
       'field_name' => 'synonyms_term',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'settings' => array(
-        'allowed_values' => array(
-          array(
-            'vocabulary' => $this->vocabulary->machine_name,
-            'parent' => 0,
-          ),
-        ),
+        'target_type' => 'taxonomy_term',
+        'handler_settings' => array(),
       ),
     );
-    $this->term_reference_field = field_create_field($this->term_reference_field);
+    $this->reference_field = field_create_field($this->reference_field);
 
-    $instance = array(
-      'field_name' => $this->term_reference_field['field_name'],
+    $this->reference_instance = array(
+      'field_name' => $this->reference_field['field_name'],
       'entity_type' => 'node',
       'bundle' => $this->bundle,
       'label' => 'Synonym Terms Select',
       'widget' => array(
-        'type' => 'synonyms_select',
-      ),
-    );
-    $instance = field_create_instance($instance);
-
-    $this->terms['parent_term'] = (object) array(
-      'vid' => $this->vocabulary->vid,
-      'name' => 'Parent Term',
-      $this->fields['enabled']['field']['field_name'] => array(
-        LANGUAGE_NONE => array(
-          array('value' => 'Parent TermA' . $this->randomName()),
-          array('value' => 'Parent TermZ' . $this->randomName()),
-        ),
-      ),
-    );
-    taxonomy_term_save($this->terms['parent_term']);
-
-    $this->terms['child_term'] = (object) array(
-      'vid' => $this->vocabulary->vid,
-      'name' => 'Child Term',
-      'parent' => $this->terms['parent_term']->tid,
-      $this->fields['enabled']['field']['field_name'] => array(
-        LANGUAGE_NONE => array(
-          array('value' => 'Child TermZ' . $this->randomName()),
-          array('value' => 'Child TermA' . $this->randomName()),
-        ),
-      ),
-    );
-    taxonomy_term_save($this->terms['child_term']);
-
-    $this->terms['normal_term'] = (object) array(
-      'vid' => $this->vocabulary->vid,
-      'name' => 'Normal Term',
-      $this->fields['enabled']['field']['field_name'] => array(
-        LANGUAGE_NONE => array(
-          array('value' => 'Normal TermA' . $this->randomName()),
-          array('value' => 'Normal TermZ' . $this->randomName()),
-        ),
+        'type' => 'synonyms_select_entity',
       ),
     );
-    taxonomy_term_save($this->terms['normal_term']);
+    $this->reference_instance = field_create_instance($this->reference_instance);
   }
 
-  /**
-   * Test sorting options of the widget.
-   */
   public function testWidgetSorting() {
     $cardinality = array(
       1 => 1,
@@ -855,129 +1533,44 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
 
     foreach ($cardinality as $cardinality_k => $cardinality_v) {
       foreach ($required as $required_k => $required_v) {
-        $this->term_reference_field['cardinality'] = $cardinality_k;
-        field_update_field($this->term_reference_field);
-
-        $instance = field_info_instance($this->entity_type, $this->term_reference_field['field_name'], $this->bundle);
-        $instance['required'] = $required_k;
-        $instance['widget']['settings']['sort'] = 'weight';
-        field_update_instance($instance);
+        $this->reference_field['cardinality'] = $cardinality_k;
+        field_update_field($this->reference_field);
 
-        $this->terms['parent_term']->weight = 0;
-        taxonomy_term_save($this->terms['parent_term']);
+        $this->reference_instance['required'] = $required_k;
+        field_update_instance($this->reference_instance);
 
         $options = array();
         $options[] = array(
-          'term' => $this->terms['normal_term'],
-        );
-        $options[] = array(
-          'term' => $this->terms['normal_term'],
-          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
-        );
-        $options[] = array(
-          'term' => $this->terms['normal_term'],
-          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
-        );
-        $options[] = array(
-          'term' => $this->terms['parent_term'],
-        );
-        $options[] = array(
-          'term' => $this->terms['parent_term'],
-          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
-        );
-        $options[] = array(
-          'term' => $this->terms['parent_term'],
-          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
-        );
-        $options[] = array(
-          'term' => $this->terms['child_term'],
-        );
-        $options[] = array(
-          'term' => $this->terms['child_term'],
-          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+          'entity' => $this->terms['child_term'],
         );
         $options[] = array(
-          'term' => $this->terms['child_term'],
+          'entity' => $this->terms['child_term'],
           'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
         );
-        $this->drupalGet('node/add/synonyms-test-content');
-        $this->assertSynonymsSelect($options, 'Synonyms select sorting by weight works for the cardinality of ' . $cardinality_v . ' and ' . $required_v);
-
-        $this->terms['parent_term']->weight = -1000;
-        taxonomy_term_save($this->terms['parent_term']);
-        $options = array();
-        $options[] = array(
-          'term' => $this->terms['parent_term'],
-        );
-        $options[] = array(
-          'term' => $this->terms['parent_term'],
-          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
-        );
         $options[] = array(
-          'term' => $this->terms['parent_term'],
-          'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
-        );
-        $options[] = array(
-          'term' => $this->terms['child_term'],
-        );
-        $options[] = array(
-          'term' => $this->terms['child_term'],
+          'entity' => $this->terms['child_term'],
           'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
         );
         $options[] = array(
-          'term' => $this->terms['child_term'],
-          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
-        );
-        $options[] = array(
-          'term' => $this->terms['normal_term'],
+          'entity' => $this->terms['normal_term'],
         );
         $options[] = array(
-          'term' => $this->terms['normal_term'],
+          'entity' => $this->terms['normal_term'],
           'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
         );
         $options[] = array(
-          'term' => $this->terms['normal_term'],
+          'entity' => $this->terms['normal_term'],
           'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
         );
-        $this->drupalGet('node/add/synonyms-test-content');
-        $this->assertSynonymsSelect($options, 'Synonyms select sorting by weight works after changing weights of terms for the cardinality of ' . $cardinality_v . ' and ' . $required_v);
-
-        $instance = field_info_instance($this->entity_type, $this->term_reference_field['field_name'], $this->bundle);
-        $instance['widget']['settings']['sort'] = 'name';
-        field_update_instance($instance);
-
-        $options = array();
-        $options[] = array(
-          'term' => $this->terms['normal_term'],
-        );
-        $options[] = array(
-          'term' => $this->terms['normal_term'],
-          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
-        );
-        $options[] = array(
-          'term' => $this->terms['normal_term'],
-          'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
-        );
-        $options[] = array(
-          'term' => $this->terms['parent_term'],
-        );
-        $options[] = array(
-          'term' => $this->terms['child_term'],
-        );
-        $options[] = array(
-          'term' => $this->terms['child_term'],
-          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
-        );
         $options[] = array(
-          'term' => $this->terms['child_term'],
-          'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+          'entity' => $this->terms['parent_term'],
         );
         $options[] = array(
-          'term' => $this->terms['parent_term'],
+          'entity' => $this->terms['parent_term'],
           'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
         );
         $options[] = array(
-          'term' => $this->terms['parent_term'],
+          'entity' => $this->terms['parent_term'],
           'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
         );
         $this->drupalGet('node/add/synonyms-test-content');
@@ -986,14 +1579,11 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
     }
   }
 
-  /**
-   * Test main functionality of the widget.
-   */
   public function testWidget() {
     $name = $this->randomName();
     $this->drupalPost('node/add/synonyms-test-content', array(
       'title' => $name,
-      $this->term_reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
         $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
         $this->terms['child_term']->tid,
         $this->terms['normal_term']->tid,
@@ -1009,50 +1599,50 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
 
     $options = array();
     $options[] = array(
-      'term' => $this->terms['normal_term'],
+      'entity' => $this->terms['child_term'],
       'selected' => TRUE,
     );
     $options[] = array(
-      'term' => $this->terms['normal_term'],
-      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['normal_term'],
-      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
+      'entity' => $this->terms['normal_term'],
       'selected' => TRUE,
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
-      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
-      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
+      'entity' => $this->terms['parent_term'],
       'selected' => TRUE,
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
-      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
-      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $this->drupalGet('node/' . $node->nid . '/edit');
     $this->assertSynonymsSelect($options, 'Default values are set correctly in the synonyms friendly select widget when working with field cardinality more than 1.');
 
-    $this->term_reference_field['cardinality'] = 2;
-    field_update_field($this->term_reference_field);
+    $this->reference_field['cardinality'] = 2;
+    field_update_field($this->reference_field);
     $name = $this->randomName();
     $this->drupalPost('node/add/synonyms-test-content', array(
       'title' => $name,
-      $this->term_reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
         $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
         $this->terms['child_term']->tid,
         $this->terms['normal_term']->tid,
@@ -1062,7 +1652,7 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
 
     $this->drupalPost('node/add/synonyms-test-content', array(
       'title' => $name,
-      $this->term_reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . '][]' => array(
         $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
         $this->terms['normal_term']->tid,
         $this->synonymSelectKey($this->terms['normal_term'], $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
@@ -1073,12 +1663,12 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
     $this->assertUniqueText($this->terms['parent_term']->name, 'Submitting 3 entries into a field with cardinality of 2, that refer to only 2 terms, results in form getting submitted. Term #1 is saved.');
     $this->assertUniqueText($this->terms['normal_term']->name, 'Term #2 is saved.');
 
-    $this->term_reference_field['cardinality'] = 1;
-    field_update_field($this->term_reference_field);
+    $this->reference_field['cardinality'] = 1;
+    field_update_field($this->reference_field);
     $name = $this->randomName();
     $this->drupalPost('node/add/synonyms-test-content', array(
       'title' => $name,
-      $this->term_reference_field['field_name'] . '[' . LANGUAGE_NONE . ']' => $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . ']' => $this->synonymSelectKey($this->terms['parent_term'], $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']),
     ), 'Save');
     $node = $this->drupalGetNodeByTitle($name);
     $this->drupalGet('node/' . $node->nid);
@@ -1086,44 +1676,44 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
 
     $options = array();
     $options[] = array(
-      'term' => $this->terms['normal_term'],
+      'entity' => $this->terms['child_term'],
     );
     $options[] = array(
-      'term' => $this->terms['normal_term'],
-      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['normal_term'],
-      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
-      'selected' => TRUE,
+      'entity' => $this->terms['normal_term'],
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
-      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
-      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
+      'entity' => $this->terms['parent_term'],
+      'selected' => TRUE,
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
-      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
-      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $this->drupalGet('node/' .  $node->nid . '/edit');
     $this->assertSynonymsSelect($options, 'Default values are set correctly in the synonyms friendly select widget when working with the field cardinality of 1.');
 
     $this->drupalPost('node/' . $node->nid . '/edit', array(
-      $this->term_reference_field['field_name'] . '[' . LANGUAGE_NONE . ']' => $this->terms['child_term']->tid,
+      $this->reference_field['field_name'] . '[' . LANGUAGE_NONE . ']' => $this->terms['child_term']->tid,
     ), 'Save');
     $this->drupalGet('node/' . $node->nid);
     $this->assertNoText($this->terms['parent_term']->name, 'After updating entity the old term is removed.');
@@ -1131,115 +1721,42 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
 
     $options = array();
     $options[] = array(
-      'term' => $this->terms['normal_term'],
+      'entity' => $this->terms['child_term'],
+      'selected' => TRUE,
     );
     $options[] = array(
-      'term' => $this->terms['normal_term'],
-      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['normal_term'],
-      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['child_term'],
+      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
+      'entity' => $this->terms['normal_term'],
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
-      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['parent_term'],
-      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['normal_term'],
+      'synonym' => $this->terms['normal_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
-      'selected' => TRUE,
+      'entity' => $this->terms['parent_term'],
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
-      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'],
     );
     $options[] = array(
-      'term' => $this->terms['child_term'],
-      'synonym' => $this->terms['child_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
+      'entity' => $this->terms['parent_term'],
+      'synonym' => $this->terms['parent_term']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][1]['value'],
     );
     $this->drupalGet('node/' .  $node->nid . '/edit');
     $this->assertSynonymsSelect($options, 'Default values are set correctly in the synonyms friendly select widget when working with the field cardinality of 1.');
   }
-
-  /**
-   * Assert correctness of the synonyms-friendly select widget.
-   *
-   * @param array $options
-   *   Array of what options must be present in the select form element. It
-   *   should consist of arrays that follow such structure:
-   *   - term: (object) Term object this option represents
-   *   - synonym: (string) If the option comes from a term, then include it here
-   *   - selected: (bool) Place here TRUE if this option should be selected by
-   *     default
-   * @param string $message
-   *   Assert message that will be passed on to SimpleTest internals
-   */
-  protected function assertSynonymsSelect($options, $message = '') {
-    $instance = field_info_instance($this->entity_type, $this->term_reference_field['field_name'], $this->bundle);
-    $multiple = $this->term_reference_field['cardinality'] > 1 || $this->term_reference_field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;
-    $required = $instance['required'];
-
-    $element = array(
-      '#options' => array(),
-      '#value' => $multiple ? array() : 'nothing',
-    );
-
-    if (!$multiple && !$required) {
-      $element['#options'][''] = t('- None -');
-    }
-
-    foreach ($options as $v) {
-      $key = $this->synonymSelectKey($v['term'], isset($v['synonym']) ? $v['synonym'] : NULL);
-      $label = $v['term']->name;
-      if (isset($v['synonym'])) {
-        $label = format_string($this->behavior_settings['wording'], array(
-          '@synonym' => $v['synonym'],
-          '@term'=> $v['term']->name,
-          '@field_name' => $this->fields['enabled']['instance']['label'],
-        ));
-      }
-
-      if (isset($v['selected']) && $v['selected']) {
-        if ($multiple) {
-          $element['#value'][] = $key;
-        }
-        else {
-          $element['#value'] = $key;
-        }
-      }
-
-      $depth = count(taxonomy_get_parents_all($v['term']->tid)) - 1;
-      $element['#options'][$key] = str_repeat('-', $depth) . $label;
-    }
-    $this->assertRaw('>' . form_select_options($element) . '</select>', $message, 'Synonyms friendly select');
-  }
-
-  /**
-   * Form a key for the option of a synonyms friendly select.
-   *
-   * @param object $term
-   *   Fully loaded taxonomy term for which to generate the key
-   * @param string $synonym
-   *   If the option, whose key is being generated, comes from a synonym, then
-   *   supply it here
-   *
-   * @return string
-   *   Key for the option of a synonym friendly select
-   */
-  protected function synonymSelectKey($term, $synonym = NULL) {
-    $key = $term->tid;
-    if ($synonym) {
-      $key .= ':' . drupal_html_class($synonym);
-    }
-    return $key;
-  }
 }
 
 /**
@@ -1247,7 +1764,7 @@ class SelectSynonymsWebTestCase extends SynonymsWebTestCase {
  */
 abstract class AbstractSynonymsBehaviorWebTestCase extends SynonymsWebTestCase {
 
-  protected $behavior = 'synonyms';
+  protected $behavior = 'autocomplete';
 
   /**
    * Test synonymsExtract() method.
@@ -1261,7 +1778,7 @@ abstract class AbstractSynonymsBehaviorWebTestCase extends SynonymsWebTestCase {
    *   SimpleTest assertion method
    */
   protected function assertSynonymsExtract($items, $standard, $message = '') {
-    $behavior_implementation = synonyms_behavior_implementation_class('synonyms', $this->fields['enabled']['field']);
+    $behavior_implementation = synonyms_behavior_implementation_class($this->behavior, $this->fields['enabled']['field']);
     $behavior_implementation = new $behavior_implementation();
 
     $term = (object) array(
@@ -1294,7 +1811,7 @@ abstract class AbstractSynonymsBehaviorWebTestCase extends SynonymsWebTestCase {
    *   SimpleTest assertion method
    */
   protected function assertMergeEntityAsSynonym($items, $synonym_entity, $synonym_entity_type, $standard, $message = '') {
-    $behavior_implementation = synonyms_behavior_implementation_class('synonyms', $this->fields['enabled']['field']);
+    $behavior_implementation = synonyms_behavior_implementation_class($this->behavior, $this->fields['enabled']['field']);
     $behavior_implementation = new $behavior_implementation();
 
     $message = get_class($behavior_implementation) . '::mergeEntityAsSynonym() passed: ' . $message;
@@ -1332,7 +1849,7 @@ abstract class AbstractSynonymsBehaviorWebTestCase extends SynonymsWebTestCase {
    *   SimpleTest assertion method
    */
   protected function assertSynonymsFind($meta_data, QueryConditionInterface $condition, $message = '') {
-    $behavior_implementation = synonyms_behavior_implementation_class('synonyms', $this->fields['enabled']['field']);
+    $behavior_implementation = synonyms_behavior_implementation_class($this->behavior, $this->fields['enabled']['field']);
     $behavior_implementation = new $behavior_implementation();
 
     $message = get_class($behavior_implementation) . '::synonymsFind() pass: ' . $message;
@@ -1424,14 +1941,14 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
     $this->assertMergeEntityAsSynonym(array(), $node, 'node', array(array('value' => $node->title)), 'on a node entity.');
 
     // Testing synonymFind() method.
-    $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on empty field.');
+    $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on empty field.');
 
     $meta_data = array();
     $meta_data[] = array(
       'items' => array(),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field without values.');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field without values.');
 
     $meta_data = array();
     $meta_data[] = array(
@@ -1442,7 +1959,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       ),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field with a value, but when searching for another string.');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field with a value, but when searching for another string.');
 
     $meta_data = array();
     $synonym = $this->randomName();
@@ -1454,7 +1971,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       ),
       'found_synonyms' => array($synonym),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym), 'on a field with a single value searching for that string');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym), 'on a field with a single value searching for that string');
 
     $meta_data = array();
     $synonym = $this->randomName();
@@ -1467,7 +1984,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       ),
       'found_synonyms' => array($synonym),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym), 'on a field with 2 values searching for one of those 2 values');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym), 'on a field with 2 values searching for one of those 2 values');
 
     $meta_data = array();
     $synonym = $this->randomName();
@@ -1489,7 +2006,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       ),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym), 'on 2 fields with 2 values each searching for one of those values');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym), 'on 2 fields with 2 values each searching for one of those values');
 
     $meta_data = array();
     $synonym = $this->randomName();
@@ -1501,7 +2018,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       ),
       'found_synonyms' => array($synonym),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr($synonym, 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr($synonym, 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
 
     $meta_data = array();
     $tag = $this->randomName();
@@ -1516,7 +2033,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       ),
       'found_synonyms' => array($synonym1, $synonym2),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
 
     $meta_data = array();
     $synonym1 = $this->randomName();
@@ -1530,7 +2047,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       ),
       'found_synonyms' => array($synonym1, $synonym2),
     );
-    $this->assertSynonymsFind($meta_data, db_or()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym1)->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym2), 'on a field with 2 values searching for value1 or value2');
+    $this->assertSynonymsFind($meta_data, db_or()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym1)->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym2), 'on a field with 2 values searching for value1 or value2');
 
     $meta_data = array();
     $synonym = $this->randomName();
@@ -1543,7 +2060,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       ),
       'found_synonyms' => array($synonym),
     );
-    $this->assertSynonymsFind($meta_data, db_and(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym)->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, db_like(drupal_substr($synonym, 0, -1)) . '%', 'LIKE'), 'on a field with 2 values searching for value1 and LIKE value1%');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym)->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, db_like(drupal_substr($synonym, 0, -1)) . '%', 'LIKE'), 'on a field with 2 values searching for value1 and LIKE value1%');
 
     $meta_data = array();
     $synonym1 = $this->randomName();
@@ -1558,8 +2075,8 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       'found_synonyms' => array($synonym1, $synonym2),
     );
     $condition = db_or();
-    $condition->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym1);
-    $condition->condition(db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym2)->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, db_like(drupal_substr($synonym2, 0, -1)) . '%', 'LIKE'));
+    $condition->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym1);
+    $condition->condition(db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym2)->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, db_like(drupal_substr($synonym2, 0, -1)) . '%', 'LIKE'));
     $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for (value1 or (value2 AND value2%))');
 
     $meta_data = array();
@@ -1575,7 +2092,7 @@ class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTestCas
       'found_synonyms' => array($synonym1, $synonym2),
     );
     $condition = db_and()
-      ->where("REPLACE(" . AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :synonym", array(
+      ->where("REPLACE(" . AbstractSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :synonym", array(
         ':synonym' => $synonym2,
       ));
     $this->assertSynonymsFind($meta_data, $condition, "on a field with 2 values, where 2nd value replaces spaces with dashes in the 1st value, searching for REPLACE(column, ' ', '-') = value2");
@@ -1654,14 +2171,14 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
     $this->assertMergeEntityAsSynonym(array(), $synonym_term, 'taxonomy_term', array(array('tid' => $synonym_term->tid)), 'on a term from referenced vocabulary.');
 
     // Testing synonymFind() method.
-    $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on empty field');
+    $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on empty field');
 
     $meta_data = array();
     $meta_data[] = array(
       'items' => array(),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field without values');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field without values');
 
     $meta_data = array();
     $meta_data[] = array(
@@ -1672,7 +2189,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       ),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field with a value but searching for another string');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field with a value but searching for another string');
 
     $meta_data = array();
     $synonym_term = $this->createSynonymTerm();
@@ -1684,7 +2201,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       ),
       'found_synonyms' => array($synonym_term->name),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term->name), 'on a field with a single value searching for that string');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term->name), 'on a field with a single value searching for that string');
 
     $meta_data = array();
     $synonym_term = $this->createSynonymTerm();
@@ -1697,7 +2214,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       ),
       'found_synonyms' => array($synonym_term->name),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term->name), 'on a field with 2 values searching for one of those 2 values');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term->name), 'on a field with 2 values searching for one of those 2 values');
 
     $meta_data = array();
     $synonym_term = $this->createSynonymTerm();
@@ -1719,7 +2236,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       ),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term->name), 'on 2 fields with 2 values each searching for one of those values');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term->name), 'on 2 fields with 2 values each searching for one of those values');
 
     $meta_data = array();
     $synonym_term = $this->createSynonymTerm();
@@ -1731,7 +2248,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       ),
       'found_synonyms' => array($synonym_term->name),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term->name, 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term->name, 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
 
     $meta_data = array();
     $tag = $this->randomName();
@@ -1746,7 +2263,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       ),
       'found_synonyms' => array($synonym_term1->name, $synonym_term2->name),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
 
     $meta_data = array();
     $synonym_term1 = $this->createSynonymTerm();
@@ -1760,7 +2277,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       ),
       'found_synonyms' => array($synonym_term1->name, $synonym_term2->name),
     );
-    $this->assertSynonymsFind($meta_data, db_or()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term1->name)->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term2->name), 'on a field with 2 values searching for value1 or value2');
+    $this->assertSynonymsFind($meta_data, db_or()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term1->name)->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term2->name), 'on a field with 2 values searching for value1 or value2');
 
     $meta_data = array();
     $synonym_term = $this->createSynonymTerm();
@@ -1773,7 +2290,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       ),
       'found_synonyms' => array($synonym_term->name),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term->name)->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term->name, 1, -1)) . '%', 'LIKE'), 'on a field with 2 values searching for value1 and LIKE value1%');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term->name)->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term->name, 1, -1)) . '%', 'LIKE'), 'on a field with 2 values searching for value1 and LIKE value1%');
 
     $meta_data = array();
     $synonym_term1 = $this->createSynonymTerm();
@@ -1788,10 +2305,10 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       'found_synonyms' => array($synonym_term1->name, $synonym_term2->name),
     );
     $condition = db_or();
-    $condition->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term1->name);
+    $condition->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term1->name);
     $condition->condition(db_and()
-      ->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term2->name)
-      ->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term2->name, 1 -1)) . '%', 'LIKE'));
+      ->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $synonym_term2->name)
+      ->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term2->name, 1 -1)) . '%', 'LIKE'));
     $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for (value1 or (value2 AND value2%))');
 
     $meta_data =  array();
@@ -1807,7 +2324,7 @@ class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsBehaviorWebTes
       'found_synonyms' => array($synonym_term1->name, $synonym_term2->name),
     );
     $condition = db_and()
-      ->where("REPLACE(" . AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :synonym", array(
+      ->where("REPLACE(" . AbstractSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :synonym", array(
         ':synonym' => $synonym_term2->name,
       ));
     $this->assertSynonymsFind($meta_data, $condition, "on a field with 2 values, where 2nd value replaces spaces with dashes in the 1st value, searching for REPLACE(column, ' ', '-') = value2");
@@ -1901,14 +2418,14 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
     $this->assertMergeEntityAsSynonym(array(), $node, 'node', array(array('target_id' => $node->nid)), 'on a node.');
 
     // Testing synonymFind() method.
-    $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on empty field');
+    $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on empty field');
 
     $meta_data = array();
     $meta_data[] = array(
       'items' => array(),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field without values');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field without values');
 
     $meta_data = array();
     $meta_data[] = array(
@@ -1919,7 +2436,7 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       ),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field with a value but searching for another string');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $this->randomName()), 'on a field with a value but searching for another string');
 
     $meta_data = array();
     $synonym_entity = $this->createNode();
@@ -1931,7 +2448,7 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       ),
       'found_synonyms' => array(entity_label('node', $synonym_entity)),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on a field with a single value searching for that string');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on a field with a single value searching for that string');
 
     $meta_data = array();
     $synonym_entity = $this->createNode();
@@ -1944,7 +2461,7 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       ),
       'found_synonyms' => array(entity_label('node', $synonym_entity)),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on a field with 2 values searching for one of those 2 values');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on a field with 2 values searching for one of those 2 values');
 
     $meta_data = array();
     $synonym_entity = $this->createNode();
@@ -1966,7 +2483,7 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       ),
       'found_synonyms' => array(),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on 2 fields with 2 values each searching for one of those values');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on 2 fields with 2 values each searching for one of those values');
 
     $meta_data = array();
     $synonym_entity = $this->createNode();
@@ -1978,7 +2495,7 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       ),
       'found_synonyms' => array(entity_label('node', $synonym_entity)),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity), 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity), 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
 
     $meta_data = array();
     $tag = $this->randomName();
@@ -1996,7 +2513,7 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
         entity_label('node', $synonym_entity2),
       ),
     );
-    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
+    $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
 
     $meta_data = array();
     $synonym_entity1 = $this->createNode();
@@ -2014,8 +2531,8 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       ),
     );
     $condition = db_or()
-      ->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity1))
-      ->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity2));
+      ->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity1))
+      ->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity2));
     $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for value1 or value2');
 
     $meta_data = array();
@@ -2030,8 +2547,8 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       'found_synonyms' => array(entity_label('node', $synonym_entity)),
     );
     $condition = db_and()
-      ->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity))
-      ->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity), 1, -1)) . '%', 'LIKE');
+      ->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity))
+      ->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity), 1, -1)) . '%', 'LIKE');
     $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for value1 and LIKE value1%');
 
     $meta_data = array();
@@ -2050,8 +2567,8 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       ),
     );
     $condition = db_or()
-      ->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity1))
-      ->condition(db_and()->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity2))->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity2), 1, -1)) . '%', 'LIKE'));
+      ->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity1))
+      ->condition(db_and()->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, entity_label('node', $synonym_entity2))->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity2), 1, -1)) . '%', 'LIKE'));
     $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for (value1 or (value2 AND value2%))');
 
     $meta_data = array();
@@ -2070,7 +2587,7 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
       ),
     );
     $condition = db_and()
-      ->where("REPLACE(" . AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :synonym", array(
+      ->where("REPLACE(" . AbstractSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :synonym", array(
         ':synonym' => entity_label('node', $synonym_entity2),
       ));
     $this->assertSynonymsFind($meta_data, $condition, "on a field with 2 values, where 2nd value replaces spaces with dashes in the 1st value, searching for REPLACE(column, ' ', '-') = value2");
@@ -2101,3 +2618,80 @@ class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsBehavio
     return $entity;
   }
 }
+
+/**
+ * Test 'term_synonyms' cTools pargument plugin implementation.
+ */
+class TaxonomyTermArgumentSynonymsWebTestCase extends SynonymsWebTestCase {
+
+  protected $behavior = 'autocomplete';
+
+  protected $behavior_settings = array(
+    'wording' => '@synonym',
+  );
+
+  /**
+   * GetInfo method.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Term synonyms cTools argument plugin',
+      'description' => 'Ensure that synonyms friendly taxonomy terms cTools argument plugin works correctly.',
+      'group' => 'Synonyms',
+    );
+  }
+
+  /**
+   * Test the term synonym argument.
+   */
+  public function testTermSynonymArgument() {
+    $term = (object) array(
+      'name' => 'Term name',
+      'vid' => $this->vocabulary->vid,
+      $this->fields['enabled']['field']['field_name'] => array(LANGUAGE_NONE => array(
+        array('value' => 'Synonym of term'),
+      )),
+    );
+    taxonomy_term_save($term);
+
+    ctools_include('context');
+
+    $argument = array(
+      'name' => 'term_synonyms',
+      'vids' => array(),
+      'transform' => FALSE,
+      'identifier' => 'Just Testing',
+      'keyword' => 'term',
+      'id' => 0,
+    );
+
+    $result = ctools_context_get_context_from_argument($argument, $this->randomName());
+    $this->assertNull($result, 'Term synonym does not look up anything when random string is supplied.');
+
+    $result = ctools_context_get_context_from_argument($argument, drupal_strtolower($term->name));
+    $this->assertEqual($result->data->tid, $term->tid, 'Term synonym argument correctly looks up the term by its name.');
+
+    $result = ctools_context_get_context_from_argument($argument, drupal_strtolower($term->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']));
+    $this->assertEqual($result->data->tid, $term->tid, 'Term synonym argument correctly looks up the term by its synonym.');
+
+    $argument['transform'] = TRUE;
+    $result = ctools_context_get_context_from_argument($argument, str_replace(' ', '-', $term->name));
+    $this->assertEqual($result->data->tid, $term->tid, 'Term synonym argument correctly looks up the term by its name, if the spaces are repaced with dashes.');
+
+    $result = ctools_context_get_context_from_argument($argument, str_replace(' ', '-', $term->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']));
+    $this->assertEqual($result->data->tid, $term->tid, 'Term synonym argument correctly looks up the term by its synonym, if the spaces are repaced with dashes.');
+
+    $argument['transform'] = FALSE;
+    $another_vocabulary = (object) array(
+      'name' => $this->randomName(),
+      'machine_name' => 'another_vocabulary',
+    );
+    taxonomy_vocabulary_save($another_vocabulary);
+    $argument['vids'][$another_vocabulary->vid] = $another_vocabulary->vid;
+    $result = ctools_context_get_context_from_argument($argument, drupal_strtolower($term->name));
+    $this->assertNull($result, 'Term synonym argument does not look up anything when term name is supplied, but the search is limited to another vocabulary.');
+
+    $result = ctools_context_get_context_from_argument($argument, drupal_strtolower($term->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value']));
+    $this->assertNull($result, 'Term synonym argument does not look up anything when term synonym is supplied, but the search is limited to another vocabulary.');
+  }
+}
diff --git a/synonyms_search/includes/SearchSynonymsBehavior.interface.inc b/synonyms_search/includes/SearchSynonymsBehavior.interface.inc
index 63935dd..a30ff60 100644
--- a/synonyms_search/includes/SearchSynonymsBehavior.interface.inc
+++ b/synonyms_search/includes/SearchSynonymsBehavior.interface.inc
@@ -9,6 +9,6 @@
 /**
  * Interface of search integration synonyms behavior.
  */
-interface SearchSynonymsBehavior extends SynonymsSynonymsBehavior {
+interface SearchSynonymsBehavior extends SynonymsBehavior {
 }
 
diff --git a/synonyms_search/plugins/behavior/search.inc b/synonyms_search/plugins/behavior/search.inc
index 83b2e66..e53864f 100644
--- a/synonyms_search/plugins/behavior/search.inc
+++ b/synonyms_search/plugins/behavior/search.inc
@@ -20,8 +20,10 @@ $plugin = array(
  * where the change has taken place.
  */
 function synonyms_search_behavior_search_enabled($behavior_definition, $settings, $instance) {
-  module_load_include('inc', 'synonyms_search', 'synonyms_search.pages');
-  synonyms_search_reindex_nodes_by_vocabulary(taxonomy_vocabulary_machine_name_load($instance['bundle']));
+  if ($instance['entity_type'] == 'taxonomy_term') {
+    module_load_include('inc', 'synonyms_search', 'synonyms_search.pages');
+    synonyms_search_reindex_nodes_by_vocabulary(taxonomy_vocabulary_machine_name_load($instance['bundle']));
+  }
 }
 
 /**
@@ -31,6 +33,8 @@ function synonyms_search_behavior_search_enabled($behavior_definition, $settings
  * where the change has taken place.
  */
 function synonyms_search_behavior_search_disabled($behavior_definition, $behavior_implementation, $instance) {
-  module_load_include('inc', 'synonyms_search', 'synonyms_search.pages');
-  synonyms_search_reindex_nodes_by_vocabulary(taxonomy_vocabulary_machine_name_load($instance['bundle']));
+  if ($instance['entity_type'] == 'taxonomy_term') {
+    module_load_include('inc', 'synonyms_search', 'synonyms_search.pages');
+    synonyms_search_reindex_nodes_by_vocabulary(taxonomy_vocabulary_machine_name_load($instance['bundle']));
+  }
 }
diff --git a/synonyms_search/synonyms_search.module b/synonyms_search/synonyms_search.module
index 835f276..0e7f262 100644
--- a/synonyms_search/synonyms_search.module
+++ b/synonyms_search/synonyms_search.module
@@ -51,11 +51,13 @@ function synonyms_search_taxonomy_term_update($term) {
 function synonyms_search_node_update_index($node) {
   $output = array();
   foreach (field_info_instances('node', $node->type) as $instance) {
-    // We go a field by field looking for taxonomy term reference and if that
-    // vocabulary has enabled search synonyms, we add them to the search index.
+    // We go a field by field looking for taxonomy term reference or entity
+    // reference of taxonomy term type and if that vocabulary has enabled search
+    // synonyms, we add them to the search index.
+    // TODO: implement this through foreign keys information. See
+    // term_merge_fields_with_foreign_key() function.
     $field_info = field_info_field($instance['field_name']);
     if ($field_info['type'] == 'taxonomy_term_reference') {
-      // For each term referenced in this node we have to add synonyms.
       $terms = field_get_items('node', $node, $instance['field_name']);
       if (is_array($terms) && !empty($terms)) {
         foreach ($terms as $v) {
@@ -63,6 +65,14 @@ function synonyms_search_node_update_index($node) {
         }
       }
     }
+    if ($field_info['type'] == 'entityreference' && $field_info['settings']['target_type'] == 'taxonomy_term') {
+      $terms = field_get_items('node', $node, $instance['field_name']);
+      if (is_array($terms) && !empty($terms)) {
+        foreach ($terms as $v) {
+          $output[] = $v['target_id'];
+        }
+      }
+    }
   }
 
   if (!empty($output)) {
diff --git a/synonyms_search/synonyms_search.pages.inc b/synonyms_search/synonyms_search.pages.inc
index b6876f3..3747888 100644
--- a/synonyms_search/synonyms_search.pages.inc
+++ b/synonyms_search/synonyms_search.pages.inc
@@ -21,8 +21,6 @@ function synonyms_search_reindex_nodes_by_terms($tids) {
   $found_nids = array();
   foreach (field_info_field_map() as $field_name => $v) {
     if ($v['type'] == 'taxonomy_term_reference' && isset($v['bundles']['node'])) {
-      // This field is taxonomy term reference and it is attached to nodes, so
-      // we will run EntityFieldQuery on it.
       $query = new EntityFieldQuery();
       $result = $query->entityCondition('entity_type', 'node')
         ->fieldCondition($field_name, 'tid', $tids, 'IN')
@@ -31,6 +29,18 @@ function synonyms_search_reindex_nodes_by_terms($tids) {
         $found_nids = array_merge($found_nids, array_keys($result['node']));
       }
     }
+    if ($v['type'] == 'entityreference' && isset($v['bundles']['node'])) {
+      $field = field_info_field($field_name);
+      if ($field['settings']['target_type'] == 'taxonomy_term') {
+        $query = new EntityFieldQuery();
+        $result = $query->entityCondition('entity_type', 'node')
+          ->fieldCondition($field_name, 'target_id', $tids, 'IN')
+          ->execute();
+        if (isset($result['node'])) {
+          $found_nids = array_merge($found_nids, array_keys($result['node']));
+        }
+      }
+    }
   }
   if (!empty($found_nids)) {
     db_update('search_dataset')
diff --git a/synonyms_search/synonyms_search.test b/synonyms_search/synonyms_search.test
deleted file mode 100644
index 5477d9a..0000000
--- a/synonyms_search/synonyms_search.test
+++ /dev/null
@@ -1,367 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for the Synonyms Search module.
- */
-
-/**
- * Base class for tests of Synonyms Search module.
- */
-abstract class AbstractSearchSynonymsWebTestCase extends SynonymsWebTestCase {
-
-  protected $behavior = 'search';
-
-  /**
-   * What search type is being tested.
-   *
-   * @var string
-   */
-  protected $search_type = 'node';
-
-  /**
-   * Array of terms that will be used for testing.
-   *
-   * @var array
-   */
-  protected $terms = array();
-
-  /**
-   * SetUp method.
-   */
-  public function setUp($modules = array()) {
-    $modules[] = 'synonyms_search';
-    parent::setUp($modules);
-
-    // Create a few terms and synonyms.
-    $term = (object) array(
-      'vid' => $this->vocabulary->vid,
-      'name' => $this->randomName(),
-      $this->fields['disabled']['field']['field_name'] => array(
-        LANGUAGE_NONE => array(
-          array('value' => $this->randomName()),
-        ),
-      ),
-    );
-    taxonomy_term_save($term);
-    $this->terms['no_synonyms'] = $term;
-
-    $term = (object) array(
-      'vid' => $this->vocabulary->vid,
-      'name' => $this->randomName(),
-      $this->fields['enabled']['field']['field_name'] => array(
-        LANGUAGE_NONE => array(
-          array('value' => $this->randomName()),
-        ),
-      ),
-      $this->fields['disabled']['field']['field_name'] => array(
-        LANGUAGE_NONE => array(
-          array('value' => $this->randomName()),
-        ),
-      ),
-    );
-    taxonomy_term_save($term);
-    $this->terms['one_synonym'] = $term;
-
-    $term = (object) array(
-      'vid' => $this->vocabulary->vid,
-      'name' => $this->randomName(),
-      $this->fields['enabled']['field']['field_name'] => array(
-        LANGUAGE_NONE => array(
-          array('value' => $this->randomName()),
-          array('value' => $this->randomName()),
-        ),
-      ),
-      $this->fields['disabled']['field']['field_name'] => array(
-        LANGUAGE_NONE => array(
-          array('value' => $this->randomName()),
-        ),
-      ),
-    );
-    taxonomy_term_save($term);
-    $this->terms['two_synonyms'] = $term;
-  }
-
-  /**
-   * Retrieve search results.
-   *
-   * @param $keyword string
-   *   Keyword to supply to the search mechanism
-   *
-   * @return array
-   *   Array of HTML search results. Each element in this array is a single
-   *   search result represented in HTML code as Drupal search mechanism outputs
-   *   it
-   */
-  protected function getSearchResults($keyword) {
-    $response = $this->drupalGet('search/' . $this->search_type . '/' . $keyword);
-    $matches = array();
-    preg_match_all('#\<li[^>]+class="search-result"[^>]*\>(.*?)\</li\>#si', $response, $matches);
-    return $matches[1];
-  }
-}
-
-/**
- * Test Synonyms module integration with Drupal search functionality for nodes.
- */
-class NodeSearchSynonymsWebTestCase extends AbstractSearchSynonymsWebTestCase {
-
-  /**
-   * GetInfo method.
-   */
-  public static function getInfo() {
-    return array(
-      'name' => 'Synonyms node search integration',
-      'description' => 'Ensure that Synonyms module correctly integrates with the Drupal search functionality.',
-      'group' => 'Synonyms',
-    );
-  }
-
-  /**
-   * SetUp method.
-   */
-  public function setUp($modules = array()) {
-    parent::setUp($modules);
-
-    // Creating a test content type.
-    $this->drupalPost('admin/structure/types/add', array(
-      'name' => 'Synonyms Test Content',
-      'type' => 'synonyms_test_content',
-    ), 'Save content type');
-
-    // Attaching term reference field to the new content type.
-    $field = array(
-      'type' => 'taxonomy_term_reference',
-      'field_name' => 'synonyms_term_enabled',
-      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'settings' => array(
-        'allowed_values' => array(
-          array(
-            'vocabulary' => $this->vocabulary->machine_name,
-            'parent' => 0,
-          ),
-        ),
-      ),
-    );
-    $field = field_create_field($field);
-
-    $instance = array(
-      'field_name' => $field['field_name'],
-      'entity_type' => 'node',
-      'bundle' => 'synonyms_test_content',
-      'label' => 'Synonym Terms',
-      'widget' => array(
-        'type' => 'synonyms_autocomplete',
-      ),
-    );
-
-    field_create_instance($instance);
-  }
-
-  /**
-   * Test searching nodes by a term synonym.
-   *
-   * Since logically term and its synonyms represent the same entity, the idea
-   * is that searching by a term synonym should trigger all content referencing
-   * that term to be included in search results. Additionally we test that when
-   * a synonym is deleted/edited in a term, corresponding content is no longer
-   * encountered when searched by ex-synonym.
-   */
-  public function testSearchTermSynonym() {
-    // Creating a node, which references all the terms we have.
-    $node = (object) array(
-      'type' => 'synonyms_test_content',
-      'title' => $this->randomName(),
-      'synonyms_term_enabled' => array(LANGUAGE_NONE => array(
-        array('tid' => $this->terms['no_synonyms']->tid),
-        array('tid' => $this->terms['one_synonym']->tid),
-        array('tid' => $this->terms['two_synonyms']->tid),
-      )),
-    );
-    node_save($node);
-
-    // Rebuilding Search index.
-    $this->cronRun();
-
-    foreach ($this->terms as $k => $term) {
-      $this->assertSearchResults($term->name, array($node), 'Searching by name of the term ' . $k);
-      $items = field_get_items('taxonomy_term', $term, $this->fields['disabled']['field']['field_name']);
-      if (is_array($items)) {
-        foreach ($items as $delta => $item) {
-          $this->assertSearchResults($item['value'], array(), 'Searching by not enabled search integration field value #' . $delta . ' of term ' . $k);
-        }
-      }
-
-      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
-      if (is_array($items)) {
-        foreach ($items as $delta => $item) {
-          $this->assertSearchResults($item['value'], array($node), 'Searching by synonym #' . $delta . ' of the term ' . $k);
-        }
-      }
-    }
-
-    // Removing a synonym from the term. Then asserting node got re-indexed with
-    // new values of synonyms.
-    $deleted_synonym = array_pop($this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE]);
-    taxonomy_term_save($this->terms['one_synonym']);
-    $this->cronRun();
-    $this->assertSearchResults($deleted_synonym['value'], array(), 'Searching by recently deleted synonym of a taxonomy term yields no results.');
-
-    // Editing a synonym in a term. Then asserting node got re-indexed with new
-    // values of synonyms.
-    $ex_synonym = $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
-    $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'] = $this->randomName();
-    taxonomy_term_save($this->terms['two_synonyms']);
-    $this->cronRun();
-    $this->assertSearchResults($ex_synonym, array(), 'Searching by recently changed synonym of a taxonomy term yields no results.');
-
-    // We disable entire field from search integration and make sure for all
-    // synonyms search results are empty.
-    synonyms_behavior_settings_delete($this->fields['enabled']['instance']['id'], $this->behavior);
-    $this->cronRun();
-    foreach ($this->terms as $k => $term) {
-      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
-      if (is_array($items)) {
-        foreach ($items as $synonym) {
-          $this->assertSearchResults($synonym['value'], array(), 'Searching by ' . $k . ' term synonym, which field was recently disabled from search behavior yields no results.');
-        }
-      }
-    }
-  }
-
-  /**
-   * Assert search results.
-   *
-   * @param $keyword string
-   *   Keyword to supply to the search mechanism
-   * @param $results array
-   *   Array of fully loaded nodes that are expected to be on search results
-   * @param $message string
-   *   Drupal assertion message to display on test results page
-   */
-  protected function assertSearchResults($keyword, $results, $message) {
-    $matches = $this->getSearchResults($keyword);
-    if (count($matches) != count($results)) {
-      $this->fail($message);
-      return;
-    }
-    $matches = implode('', $matches);
-    foreach ($results as $node) {
-      if (strpos($matches, 'node/' . $node->nid) === FALSE) {
-        $this->fail($message);
-        return;
-      }
-    }
-    $this->pass($message);
-  }
-}
-
-/**
- * Test Synonyms module integration with Drupal search for taxonomy terms.
- */
-class TermSearchSynonymsWebTestCase extends AbstractSearchSynonymsWebTestCase {
-
-  protected $search_type = 'term';
-
-  /**
-   * GetInfo method.
-   */
-  public static function getInfo() {
-    return array(
-      'name' => 'Synonyms term search integration',
-      'description' => 'Ensure that Synonyms module correctly integrates with the Term Search module.',
-      'group' => 'Synonyms',
-    );
-  }
-
-  /**
-   * SetUp method.
-   */
-  public function setUp($modules = array()) {
-    $modules[] = 'term_search';
-    parent::setUp($modules);
-    $active_searches = variable_get('search_active_modules', array('node', 'user'));
-    $active_searches[] = 'term_search';
-    variable_set('search_active_modules', $active_searches);
-  }
-
-  /**
-   * Test searching terms by their synonyms.
-   */
-  public function testSearchTermSynonym() {
-    // Rebuilding Search index.
-    $this->cronRun();
-
-    foreach ($this->terms as $k => $term) {
-      $this->assertSearchResults($term->name, array($term), 'Searching by name of the term ' . $k);
-      $items = field_get_items('taxonomy_term', $term, $this->fields['disabled']['field']['field_name']);
-      if (is_array($items)) {
-        foreach ($items as $delta => $item) {
-          $this->assertSearchResults($item['value'], array(), 'Searching by not enabled search integration field value #' . $delta . ' of term ' . $k);
-        }
-      }
-
-      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
-      if (is_array($items)) {
-        foreach ($items as $delta => $item) {
-          $this->assertSearchResults($item['value'], array($term), 'Searching by synonym #' . $delta . ' of the term ' . $k);
-        }
-      }
-    }
-
-    // Removing a synonym from the term. Then asserting it got re-indexed with
-    // new values of synonyms.
-    $deleted_synonym = array_pop($this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE]);
-    taxonomy_term_save($this->terms['one_synonym']);
-    $this->cronRun();
-    $this->assertSearchResults($deleted_synonym['value'], array(), 'Searching by recently deleted synonym of a taxonomy term yields no results.');
-
-    // Editing a synonym in a term. Then asserting it got re-indexed with new
-    // values of synonyms.
-    $ex_synonym = $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
-    $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'] = $this->randomName();
-    taxonomy_term_save($this->terms['two_synonyms']);
-    $this->cronRun();
-    $this->assertSearchResults($ex_synonym, array(), 'Searching by recently changed synonym of a taxonomy term yields no results.');
-
-    // We disable entire field from search integration and make sure for all
-    // synonyms search results are empty.
-    synonyms_behavior_settings_delete($this->fields['enabled']['instance']['id'], $this->behavior);
-    $this->cronRun();
-    foreach ($this->terms as $k => $term) {
-      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
-      if (is_array($items)) {
-        foreach ($items as $synonym) {
-          $this->assertSearchResults($synonym['value'], array(), 'Searching by ' . $k . ' term synonym, which field was recently disabled from search behavior yields no results.');
-        }
-      }
-    }
-  }
-
-  /**
-   * Assert search results.
-   *
-   * @param $keyword string
-   *   Keyword to supply to the search mechanism
-   * @param $results array
-   *   Array of fully loaded terms that are expected to be on search results
-   * @param $message string
-   *   Drupal assertion message to display on test results page
-   */
-  protected function assertSearchResults($keyword, $results, $message) {
-    $matches = $this->getSearchResults($keyword);
-    if (count($matches) != count($results)) {
-      $this->fail($message);
-      return;
-    }
-    $matches = implode('', $matches);
-    foreach ($results as $term) {
-      if (strpos($matches, 'taxonomy/term/' . $term->tid) === FALSE) {
-        $this->fail($message);
-        return;
-      }
-    }
-    $this->pass($message);
-  }
-
-}
diff --git a/synonyms_search/synonyms_search_test/synonyms_search_test.info b/synonyms_search/synonyms_search_test/synonyms_search_test.info
new file mode 100644
index 0000000..9bd6429
--- /dev/null
+++ b/synonyms_search/synonyms_search_test/synonyms_search_test.info
@@ -0,0 +1,11 @@
+name = Synonyms Search Testing
+description = "Tests Synonyms Search module."
+package = Taxonomy
+core = 7.x
+dependencies[] = synonyms_search
+dependencies[] = term_search
+dependencies[] = entityreference
+
+hidden = TRUE
+
+files[] = synonyms_search_test.test
diff --git a/synonyms_search/synonyms_search_test/synonyms_search_test.module b/synonyms_search/synonyms_search_test/synonyms_search_test.module
new file mode 100644
index 0000000..e25b082
--- /dev/null
+++ b/synonyms_search/synonyms_search_test/synonyms_search_test.module
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * Test Synonyms Search module.
+ */
diff --git a/synonyms_search/synonyms_search_test/synonyms_search_test.test b/synonyms_search/synonyms_search_test/synonyms_search_test.test
new file mode 100644
index 0000000..9b9e4b5
--- /dev/null
+++ b/synonyms_search/synonyms_search_test/synonyms_search_test.test
@@ -0,0 +1,461 @@
+<?php
+
+/**
+ * @file
+ * Tests for the Synonyms Search module.
+ */
+
+/**
+ * Base class for tests of Synonyms Search module.
+ */
+abstract class AbstractSearchSynonymsWebTestCase extends SynonymsWebTestCase {
+
+  protected $behavior = 'search';
+
+  /**
+   * What search type is being tested.
+   *
+   * @var string
+   */
+  protected $search_type = 'node';
+
+  /**
+   * Array of terms that will be used for testing.
+   *
+   * @var array
+   */
+  protected $terms = array();
+
+  /**
+   * SetUp method.
+   */
+  public function setUp($modules = array()) {
+    array_unshift($modules, 'synonyms_search_test');
+    parent::setUp($modules);
+
+    // Create a few terms and synonyms.
+    $term = (object) array(
+      'vid' => $this->vocabulary->vid,
+      'name' => $this->randomName(),
+      $this->fields['disabled']['field']['field_name'] => array(
+        LANGUAGE_NONE => array(
+          array('value' => $this->randomName()),
+        ),
+      ),
+    );
+    taxonomy_term_save($term);
+    $this->terms['no_synonyms'] = $term;
+
+    $term = (object) array(
+      'vid' => $this->vocabulary->vid,
+      'name' => $this->randomName(),
+      $this->fields['enabled']['field']['field_name'] => array(
+        LANGUAGE_NONE => array(
+          array('value' => $this->randomName()),
+        ),
+      ),
+      $this->fields['disabled']['field']['field_name'] => array(
+        LANGUAGE_NONE => array(
+          array('value' => $this->randomName()),
+        ),
+      ),
+    );
+    taxonomy_term_save($term);
+    $this->terms['one_synonym'] = $term;
+
+    $term = (object) array(
+      'vid' => $this->vocabulary->vid,
+      'name' => $this->randomName(),
+      $this->fields['enabled']['field']['field_name'] => array(
+        LANGUAGE_NONE => array(
+          array('value' => $this->randomName()),
+          array('value' => $this->randomName()),
+        ),
+      ),
+      $this->fields['disabled']['field']['field_name'] => array(
+        LANGUAGE_NONE => array(
+          array('value' => $this->randomName()),
+        ),
+      ),
+    );
+    taxonomy_term_save($term);
+    $this->terms['two_synonyms'] = $term;
+  }
+
+  /**
+   * Retrieve search results.
+   *
+   * @param $keyword string
+   *   Keyword to supply to the search mechanism
+   *
+   * @return array
+   *   Array of HTML search results. Each element in this array is a single
+   *   search result represented in HTML code as Drupal search mechanism outputs
+   *   it
+   */
+  protected function getSearchResults($keyword) {
+    $response = $this->drupalGet('search/' . $this->search_type . '/' . $keyword);
+    $matches = array();
+    preg_match_all('#\<li[^>]+class="search-result"[^>]*\>(.*?)\</li\>#si', $response, $matches);
+    return $matches[1];
+  }
+}
+
+/**
+ * Test Synonyms module integration with Drupal search functionality for nodes.
+ */
+class NodeSearchSynonymsWebTestCase extends AbstractSearchSynonymsWebTestCase {
+
+  /**
+   * GetInfo method.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Synonyms node search integration',
+      'description' => 'Ensure that Synonyms module correctly integrates with the Drupal search functionality.',
+      'group' => 'Synonyms',
+    );
+  }
+
+  /**
+   * SetUp method.
+   */
+  public function setUp($modules = array()) {
+    parent::setUp($modules);
+debug(module_list());
+    // Creating a test content type.
+    $this->drupalPost('admin/structure/types/add', array(
+      'name' => 'Synonyms Test Content',
+      'type' => 'synonyms_test_content',
+    ), 'Save content type');
+  }
+
+  /**
+   * Test searching nodes by a term synonym.
+   *
+   * Since logically term and its synonyms represent the same entity, the idea
+   * is that searching by a term synonym should trigger all content referencing
+   * that term to be included in search results. Additionally we test that when
+   * a synonym is deleted/edited in a term, corresponding content is no longer
+   * encountered when searched by ex-synonym.
+   */
+  public function testSearchTermSynonym() {
+    // Attaching term reference field to the new content type.
+    $field = array(
+      'type' => 'taxonomy_term_reference',
+      'field_name' => 'synonyms_term_enabled',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'allowed_values' => array(
+          array(
+            'vocabulary' => $this->vocabulary->machine_name,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+    $field = field_create_field($field);
+
+    $instance = array(
+      'field_name' => $field['field_name'],
+      'entity_type' => 'node',
+      'bundle' => 'synonyms_test_content',
+      'label' => 'Synonym Terms',
+      'widget' => array(
+        'type' => 'synonyms_autocomplete',
+      ),
+    );
+
+    field_create_instance($instance);
+
+    // Creating a node, which references all the terms we have.
+    $node = (object) array(
+      'type' => 'synonyms_test_content',
+      'title' => $this->randomName(),
+      'synonyms_term_enabled' => array(LANGUAGE_NONE => array(
+        array('tid' => $this->terms['no_synonyms']->tid),
+        array('tid' => $this->terms['one_synonym']->tid),
+        array('tid' => $this->terms['two_synonyms']->tid),
+      )),
+    );
+    node_save($node);
+
+    // Rebuilding Search index.
+    $this->cronRun();
+
+    foreach ($this->terms as $k => $term) {
+      $this->assertSearchResults($term->name, array($node), 'Searching by name of the term ' . $k);
+      $items = field_get_items('taxonomy_term', $term, $this->fields['disabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $delta => $item) {
+          $this->assertSearchResults($item['value'], array(), 'Searching by not enabled search integration field value #' . $delta . ' of term ' . $k);
+        }
+      }
+
+      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $delta => $item) {
+          $this->assertSearchResults($item['value'], array($node), 'Searching by synonym #' . $delta . ' of the term ' . $k);
+        }
+      }
+    }
+
+    // Removing a synonym from the term. Then asserting node got re-indexed with
+    // new values of synonyms.
+    $deleted_synonym = array_pop($this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE]);
+    taxonomy_term_save($this->terms['one_synonym']);
+    $this->cronRun();
+    $this->assertSearchResults($deleted_synonym['value'], array(), 'Searching by recently deleted synonym of a taxonomy term yields no results.');
+
+    // Editing a synonym in a term. Then asserting node got re-indexed with new
+    // values of synonyms.
+    $ex_synonym = $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
+    $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'] = $this->randomName();
+    taxonomy_term_save($this->terms['two_synonyms']);
+    $this->cronRun();
+    $this->assertSearchResults($ex_synonym, array(), 'Searching by recently changed synonym of a taxonomy term yields no results.');
+
+    // We disable entire field from search integration and make sure for all
+    // synonyms search results are empty.
+    synonyms_behavior_settings_delete($this->fields['enabled']['instance']['id'], $this->behavior);
+    $this->cronRun();
+    foreach ($this->terms as $k => $term) {
+      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $synonym) {
+          $this->assertSearchResults($synonym['value'], array(), 'Searching by ' . $k . ' term synonym, which field was recently disabled from search behavior yields no results.');
+        }
+      }
+    }
+  }
+
+  /**
+   * Test searching nodes by a term synonym when referenced by entity reference.
+   *
+   * This test pretty much does the same thing as the testSearchTermSynonym()
+   * with the only different that the terms are referenced through entity
+   * reference field type.
+   */
+  public function testSearchTermSynonymEntityReference() {
+    // Attaching entity reference field to the new content type.
+    $field = array(
+      'type' => 'entityreference',
+      'field_name' => 'synonyms_term_enabled',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'target_type' => 'taxonomy_term',
+        'handler_settings' => array(
+          'target_bundles' => array($this->vocabulary->machine_name),
+        ),
+      ),
+    );
+    $field = field_create_field($field);
+
+    $instance = array(
+      'field_name' => $field['field_name'],
+      'entity_type' => 'node',
+      'bundle' => 'synonyms_test_content',
+      'label' => 'Synonym Terms',
+      'widget' => array(
+        'type' => 'synonyms_autocomplete',
+      ),
+    );
+
+    field_create_instance($instance);
+
+    // Creating a node, which references all the terms we have.
+    $node = (object) array(
+      'type' => 'synonyms_test_content',
+      'title' => $this->randomName(),
+      'synonyms_term_enabled' => array(LANGUAGE_NONE => array(
+        array('target_id' => $this->terms['no_synonyms']->tid),
+        array('target_id' => $this->terms['one_synonym']->tid),
+        array('target_id' => $this->terms['two_synonyms']->tid),
+      )),
+    );
+    node_save($node);
+
+    // Rebuilding Search index.
+    $this->cronRun();
+
+    foreach ($this->terms as $k => $term) {
+      $this->assertSearchResults($term->name, array($node), 'Searching by name of the term ' . $k);
+      $items = field_get_items('taxonomy_term', $term, $this->fields['disabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $delta => $item) {
+          $this->assertSearchResults($item['value'], array(), 'Searching by not enabled search integration field value #' . $delta . ' of term ' . $k);
+        }
+      }
+
+      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $delta => $item) {
+          $this->assertSearchResults($item['value'], array($node), 'Searching by synonym #' . $delta . ' of the term ' . $k);
+        }
+      }
+    }
+
+    // Removing a synonym from the term. Then asserting node got re-indexed with
+    // new values of synonyms.
+    $deleted_synonym = array_pop($this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE]);
+    taxonomy_term_save($this->terms['one_synonym']);
+    $this->cronRun();
+    $this->assertSearchResults($deleted_synonym['value'], array(), 'Searching by recently deleted synonym of a taxonomy term yields no results.');
+
+    // Editing a synonym in a term. Then asserting node got re-indexed with new
+    // values of synonyms.
+    $ex_synonym = $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
+    $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'] = $this->randomName();
+    taxonomy_term_save($this->terms['two_synonyms']);
+    $this->cronRun();
+    $this->assertSearchResults($ex_synonym, array(), 'Searching by recently changed synonym of a taxonomy term yields no results.');
+
+    // We disable entire field from search integration and make sure for all
+    // synonyms search results are empty.
+    synonyms_behavior_settings_delete($this->fields['enabled']['instance']['id'], $this->behavior);
+    $this->cronRun();
+    foreach ($this->terms as $k => $term) {
+      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $synonym) {
+          $this->assertSearchResults($synonym['value'], array(), 'Searching by ' . $k . ' term synonym, which field was recently disabled from search behavior yields no results.');
+        }
+      }
+    }
+  }
+
+  /**
+   * Assert search results.
+   *
+   * @param $keyword string
+   *   Keyword to supply to the search mechanism
+   * @param $results array
+   *   Array of fully loaded nodes that are expected to be on search results
+   * @param $message string
+   *   Drupal assertion message to display on test results page
+   */
+  protected function assertSearchResults($keyword, $results, $message) {
+    $matches = $this->getSearchResults($keyword);
+    if (count($matches) != count($results)) {
+      $this->fail($message);
+      return;
+    }
+    $matches = implode('', $matches);
+    foreach ($results as $node) {
+      if (strpos($matches, 'node/' . $node->nid) === FALSE) {
+        $this->fail($message);
+        return;
+      }
+    }
+    $this->pass($message);
+  }
+}
+
+/**
+ * Test Synonyms module integration with Drupal search for taxonomy terms.
+ */
+class TermSearchSynonymsWebTestCase extends AbstractSearchSynonymsWebTestCase {
+
+  protected $search_type = 'term';
+
+  /**
+   * GetInfo method.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Synonyms term search integration',
+      'description' => 'Ensure that Synonyms module correctly integrates with the Term Search module.',
+      'group' => 'Synonyms',
+    );
+  }
+
+  /**
+   * SetUp method.
+   */
+  public function setUp($modules = array()) {
+    parent::setUp($modules);
+    $active_searches = variable_get('search_active_modules', array('node', 'user'));
+    $active_searches[] = 'term_search';
+    variable_set('search_active_modules', $active_searches);
+  }
+
+  /**
+   * Test searching terms by their synonyms.
+   */
+  public function testSearchTermSynonym() {
+    // Rebuilding Search index.
+    $this->cronRun();
+
+    foreach ($this->terms as $k => $term) {
+      $this->assertSearchResults($term->name, array($term), 'Searching by name of the term ' . $k);
+      $items = field_get_items('taxonomy_term', $term, $this->fields['disabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $delta => $item) {
+          $this->assertSearchResults($item['value'], array(), 'Searching by not enabled search integration field value #' . $delta . ' of term ' . $k);
+        }
+      }
+
+      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $delta => $item) {
+          $this->assertSearchResults($item['value'], array($term), 'Searching by synonym #' . $delta . ' of the term ' . $k);
+        }
+      }
+    }
+
+    // Removing a synonym from the term. Then asserting it got re-indexed with
+    // new values of synonyms.
+    $deleted_synonym = array_pop($this->terms['one_synonym']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE]);
+    taxonomy_term_save($this->terms['one_synonym']);
+    $this->cronRun();
+    $this->assertSearchResults($deleted_synonym['value'], array(), 'Searching by recently deleted synonym of a taxonomy term yields no results.');
+
+    // Editing a synonym in a term. Then asserting it got re-indexed with new
+    // values of synonyms.
+    $ex_synonym = $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'];
+    $this->terms['two_synonyms']->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE][0]['value'] = $this->randomName();
+    taxonomy_term_save($this->terms['two_synonyms']);
+    $this->cronRun();
+    $this->assertSearchResults($ex_synonym, array(), 'Searching by recently changed synonym of a taxonomy term yields no results.');
+
+    // We disable entire field from search integration and make sure for all
+    // synonyms search results are empty.
+    synonyms_behavior_settings_delete($this->fields['enabled']['instance']['id'], $this->behavior);
+    $this->cronRun();
+    foreach ($this->terms as $k => $term) {
+      $items = field_get_items('taxonomy_term', $term, $this->fields['enabled']['field']['field_name']);
+      if (is_array($items)) {
+        foreach ($items as $synonym) {
+          $this->assertSearchResults($synonym['value'], array(), 'Searching by ' . $k . ' term synonym, which field was recently disabled from search behavior yields no results.');
+        }
+      }
+    }
+  }
+
+  /**
+   * Assert search results.
+   *
+   * @param $keyword string
+   *   Keyword to supply to the search mechanism
+   * @param $results array
+   *   Array of fully loaded terms that are expected to be on search results
+   * @param $message string
+   *   Drupal assertion message to display on test results page
+   */
+  protected function assertSearchResults($keyword, $results, $message) {
+    $matches = $this->getSearchResults($keyword);
+    if (count($matches) != count($results)) {
+      $this->fail($message);
+      return;
+    }
+    $matches = implode('', $matches);
+    foreach ($results as $term) {
+      if (strpos($matches, 'taxonomy/term/' . $term->tid) === FALSE) {
+        $this->fail($message);
+        return;
+      }
+    }
+    $this->pass($message);
+  }
+
+}
diff --git a/views/synonyms_views_handler_filter_term_tid.inc b/views/synonyms_views_handler_filter_term_tid.inc
index 4fafd5d..5d6c20c 100644
--- a/views/synonyms_views_handler_filter_term_tid.inc
+++ b/views/synonyms_views_handler_filter_term_tid.inc
@@ -53,11 +53,11 @@ class synonyms_views_handler_filter_term_tid extends views_handler_filter_term_n
       $bundle = $field['bundles'][$field_entity_type][0];
 
       $instance = field_info_instance($field_entity_type, $field['field_name'], $bundle);
-      if ($instance['widget']['type'] == 'synonyms_autocomplete') {
+      if ($instance['widget']['type'] == 'synonyms_autocomplete_taxonomy_term') {
         $widget = $instance['widget']['settings'];
       }
       else {
-        $widget = field_info_widget_settings('synonyms_autocomplete');
+        $widget = field_info_widget_settings('synonyms_autocomplete_taxonomy_term');
       }
       $autocomplete_path = $widget['synonyms_autocomplete_path'];
       $size = $widget['size'];
@@ -154,7 +154,7 @@ class synonyms_views_handler_filter_term_tid extends views_handler_filter_term_n
       if (!empty($missing)) {
         $condition = db_or();
         foreach ($missing as $tag => $v) {
-          $condition->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $tag);
+          $condition->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $tag);
         }
         $synonyms = synonyms_synonyms_find_behavior($condition, $behavior_implementation);
         foreach ($synonyms as $synonym) {
diff --git a/views/synonyms_views_plugin_argument_validate_taxonomy_term.inc b/views/synonyms_views_plugin_argument_validate_taxonomy_term.inc
index 18fcb79..5f4f900 100644
--- a/views/synonyms_views_plugin_argument_validate_taxonomy_term.inc
+++ b/views/synonyms_views_plugin_argument_validate_taxonomy_term.inc
@@ -63,12 +63,12 @@ class synonyms_views_plugin_argument_validate_taxonomy_term extends views_plugin
         foreach ($bundles as $bundle) {
           $condition = db_and();
           if ($transform) {
-            $condition->where("REPLACE(" . AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :argument", array(
+            $condition->where("REPLACE(" . AbstractSynonymsBehavior::COLUMN_PLACEHOLDER . ", ' ', '-') = :argument", array(
               ':argument' => $argument,
             ));
           }
           else {
-            $condition->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $argument);
+            $condition->condition(AbstractSynonymsBehavior::COLUMN_PLACEHOLDER, $argument);
           }
           $synonyms = synonyms_synonyms_find($condition, 'taxonomy_term', $bundle);
           if (!empty($synonyms)) {
