diff --git a/controller/tmgmt.controller.job_item.inc b/controller/tmgmt.controller.job_item.inc
index 02f4ffb..d0052da 100644
--- a/controller/tmgmt.controller.job_item.inc
+++ b/controller/tmgmt.controller.job_item.inc
@@ -11,7 +11,6 @@
  * @ingroup tmgmt_job
  */
 class TMGMTJobItemController extends EntityAPIController {
-
   /**
    * Overrides EntityAPIController::save().
    *
@@ -19,75 +18,11 @@ class TMGMTJobItemController extends EntityAPIController {
    */
   public function save($entity, DatabaseTransaction $transaction = NULL) {
     $entity->changed = REQUEST_TIME;
-
-    // Consider everything accepted when the job item is accepted.
-    if ($entity->isAccepted()) {
-      $entity->count_pending = 0;
-      $entity->count_translated = 0;
-      $entity->count_reviewed = 0;
-      $entity->count_accepted = count(array_filter(tmgmt_flatten_data($entity->data), '_tmgmt_filter_data'));
-    }
-    // Count the data item states.
-    else {
-      // Reset counter values.
-      $entity->count_pending = 0;
-      $entity->count_translated = 0;
-      $entity->count_reviewed = 0;
-      $entity->count_accepted = 0;
-      $entity->word_count = 0;
-      $this->count($entity->data, $entity);
-    }
+    $entity->recalculateWords();
     return parent::save($entity, $transaction);
   }
 
   /**
-   * Parse all data items recursively and sums up the counters for
-   * accepted, translated and pending items.
-   *
-   * @param $item
-   *   The current data item.
-   * @param $entity
-   *   The job item the count should be calculated.
-   */
-  protected function count(&$item, $entity) {
-    if (!empty($item['#text'])) {
-      if (_tmgmt_filter_data($item)) {
-
-        // Count words of the data item.
-        $entity->word_count += tmgmt_word_count($item['#text']);
-
-        // Set default states if no state is set.
-        if (!isset($item['#status'])) {
-          // Translation is present.
-          if (!empty($item['#translation'])) {
-            $item['#status'] = TMGMT_DATA_ITEM_STATE_TRANSLATED;
-          }
-          // No translation present.
-          else {
-            $item['#status'] = TMGMT_DATA_ITEM_STATE_PENDING;
-          }
-        }
-        switch ($item['#status']) {
-          case TMGMT_DATA_ITEM_STATE_REVIEWED:
-            $entity->count_reviewed++;
-            break;
-          case TMGMT_DATA_ITEM_STATE_TRANSLATED:
-            $entity->count_translated++;
-            break;
-          default:
-            $entity->count_pending++;
-            break;
-        }
-      }
-    }
-    else {
-      foreach (element_children($item) as $key) {
-        $this->count($item[$key], $entity);
-      }
-    }
-  }
-
-  /**
    * Overrides EntityAPIController::delete().
    */
   public function delete($ids, $transaction = NULL) {
diff --git a/entity/tmgmt.entity.job.inc b/entity/tmgmt.entity.job.inc
index 86411d2..a685bba 100644
--- a/entity/tmgmt.entity.job.inc
+++ b/entity/tmgmt.entity.job.inc
@@ -197,6 +197,17 @@ class TMGMTJob extends Entity {
   }
 
   /**
+   * Add a given TMGMTJobItem to this job.
+   *
+   * @param TMGMTJobItem $job
+   *   The job item to add.
+   */
+  function addJobItem(TMGMTJobItem &$item) {
+    $item->tjid = $this->tjid;
+    $item->save();
+  }
+
+  /**
    * Add a log message for this job.
    *
    * @param $message
@@ -638,7 +649,7 @@ class TMGMTJob extends Entity {
    *   A nested array with the source data where the most upper key is the job
    *   item id.
    */
-  public function getData(array $key = array(), $index = null) {
+  public function getData(array $key = array(), $index = NULL) {
     $data = array();
     if (!empty($key)) {
       $tjiid = array_shift($key);
@@ -767,4 +778,64 @@ class TMGMTJob extends Entity {
     return array();
   }
 
+  /**
+   * Invoke the hook 'hook_tmgmt_source_suggestions' to get all suggestions.
+   *
+   * @param arary $conditions
+   *   Conditions to pass only some and not all items to the hook.
+   *
+   * @return array
+   *   List with all translation suggestions.
+   */
+  public function getSuggestions(array $conditions = array()) {
+    $suggestions = module_invoke_all('tmgmt_source_suggestions', $this->getItems($conditions), $this);
+
+    // Each TMGMTJob needs a job id to be able to count the words, because the
+    // source-language is stored in the job and not the item.
+    foreach ($suggestions as &$job) {
+      $jobItem = &$job['job_item'];
+      if (!isset($jobItem->tjid)) {
+        $jobItem->tjid = $this->tjid;
+        $jobItem->recalculateWords();
+      }
+    }
+    return $suggestions;
+  }
+
+  /**
+   * Removes all suggestions from the given list which should not be processed.
+   *
+   * This function removes all suggestions from the given list which are already
+   * assigned to a translation job or which should not be processed because
+   * there are no words, no translation is needed, ...
+   *
+   * @param array &$suggestions
+   *   Associative array of translation suggestions. It must contain at least:
+   *   - tmgmt_job: An instance of a TMGMTJobItem.
+   */
+  public function cleanSuggestionsList(array &$suggestions) {
+    foreach ($suggestions as $k => &$suggestion) {
+      if (is_array($suggestion) && isset($suggestion['job_item']) && ($suggestion['job_item'] instanceof TMGMTJobItem)) {
+        $jobItem = $suggestion['job_item'];
+
+        // Items with no words to translate should not be presented.
+        if ($jobItem->getWordCount() <= 0) {
+          unset($suggestions[$k]);
+          continue;
+        }
+
+        // Check if there already exists a translation job for this item in the
+        // current language.
+        $items = tmgmt_job_item_load_all_latest($jobItem->plugin, $jobItem->item_type, $jobItem->item_id, $this->source_language);
+        if ($items && isset($items[$this->target_language])) {
+          unset($suggestions[$k]);
+          continue;
+        }
+      } else {
+        unset($suggestions[$k]);
+        continue;
+      }
+    }
+  }
+
 }
diff --git a/entity/tmgmt.entity.job_item.inc b/entity/tmgmt.entity.job_item.inc
index 4eeb014..8b6c705 100644
--- a/entity/tmgmt.entity.job_item.inc
+++ b/entity/tmgmt.entity.job_item.inc
@@ -737,4 +737,78 @@ class TMGMTJobItem extends Entity {
 
     return array();
   }
+
+  /**
+   * Recount all translatable words.
+   */
+  public function recalculateWords() {
+    // Set translatable data from the current entity to calculate words.
+    if (empty($this->data)) {
+      $this->data = $this->getSourceData();
+    }
+
+    // Consider everything accepted when the job item is accepted.
+    if ($this->isAccepted()) {
+      $this->count_pending = 0;
+      $this->count_translated = 0;
+      $this->count_reviewed = 0;
+      $this->count_accepted = count(array_filter(tmgmt_flatten_data($this->data), '_tmgmt_filter_data'));
+    }
+    // Count the data item states.
+    else {
+      // Reset counter values.
+      $this->count_pending = 0;
+      $this->count_translated = 0;
+      $this->count_reviewed = 0;
+      $this->count_accepted = 0;
+      $this->word_count = 0;
+      $this->count($this->data);
+    }
+  }
+
+  /**
+   * Parse all data items recursively and sums up the counters for
+   * accepted, translated and pending items.
+   *
+   * @param $item
+   *   The current data item.
+   */
+  protected function count(&$item) {
+    if (!empty($item['#text'])) {
+      if (_tmgmt_filter_data($item)) {
+
+        // Count words of the data item.
+        $this->word_count += tmgmt_word_count($item['#text']);
+
+        // Set default states if no state is set.
+        if (!isset($item['#status'])) {
+          // Translation is present.
+          if (!empty($item['#translation'])) {
+            $item['#status'] = TMGMT_DATA_ITEM_STATE_TRANSLATED;
+          }
+          // No translation present.
+          else {
+            $item['#status'] = TMGMT_DATA_ITEM_STATE_PENDING;
+          }
+        }
+        switch ($item['#status']) {
+          case TMGMT_DATA_ITEM_STATE_REVIEWED:
+            $this->count_reviewed++;
+            break;
+          case TMGMT_DATA_ITEM_STATE_TRANSLATED:
+            $this->count_translated++;
+            break;
+          default:
+            $this->count_pending++;
+            break;
+        }
+      }
+    }
+    else {
+      foreach (element_children($item) as $key) {
+        $this->count($item[$key]);
+      }
+    }
+  }
+
 }
diff --git a/sources/entity/tmgmt_entity.module b/sources/entity/tmgmt_entity.module
index 0725931..77b3cb1 100644
--- a/sources/entity/tmgmt_entity.module
+++ b/sources/entity/tmgmt_entity.module
@@ -202,3 +202,67 @@ function tmgmt_entity_get_translatable_entities($entity_type, $property_conditio
 
   return $entities;
 }
+
+/**
+ * Implements hook_tmgmt_source_suggestions()
+ */
+function tmgmt_entity_tmgmt_source_suggestions(array $items, TMGMTJob $job) {
+  $suggestions = array();
+
+  foreach ($items as $item) {
+    if (($item instanceof TMGMTJobItem) && ($item->plugin == 'entity') || ($item->plugin == 'node')) {
+      // Load the entity and extract the bundle name to get all fields from the
+      // current entity.
+      $entity = entity_load_single($item->item_type, $item->item_id);
+      list(, , $bundle) = entity_extract_ids($item->item_type, $entity);
+      $field_instances = field_info_instances($item->item_type, $bundle);
+
+      // Get all translatable entity types.
+      $entity_types = array_filter(variable_get('entity_translation_entity_types', array()));
+
+      // Loop over all fields, check if they are NOT translatable. Only if a
+      // field is not translatable we may suggest a referenced entity. If so,
+      // check for a supported field type (image and file currently here).
+      foreach ($field_instances as $instance) {
+        $field = field_info_field($instance['field_name']);
+        if (isset($field['translatable']) && !$field['translatable']) {
+          $field_type = $field['type'];
+          switch ($field_type) {
+            case 'file':
+            case 'image':
+              // 'File' (and images) must be translatable entity types.
+              // Other files we not suggest here. Get all field items from the
+              // current entity and suggest them as translatable.
+              $field_name = $field['field_name'];
+              if (isset($entity_types['file']) && ($field_items = field_get_items($item->item_type, $entity, $field_name))) {
+                // Add all files as a suggestion.
+                foreach ($field_items as $field_item) {
+                  $file_entity = entity_load_single('file', $field_item['fid']);
+
+                  // Check if there is already a translation available for this
+                  // file. If so, just continue with the next file.
+                  $handler = entity_translation_get_handler('file', $file_entity);
+                  if ($handler instanceof EntityTranslationHandlerInterface) {
+                    $translations = $handler->getTranslations();
+                    if (isset($translations->data[$job->target_language])) {
+                      continue;
+                    }
+                  }
+
+                  // Add the translation as a suggestion.
+                  $suggestions[] = array(
+                    'job_item' => tmgmt_job_item_create('entity', 'file', $file_entity->fid),
+                    'suggested' => t('Suggested @type entity', array('@type' => $field_type)),
+                    'from_job' => $item->tjid,
+                  );
+                }
+              }
+              break;
+          }
+        }
+      }
+    }
+  }
+
+  return $suggestions;
+}
diff --git a/tests/tmgmt.suggestions.test b/tests/tmgmt.suggestions.test
new file mode 100644
index 0000000..3200889
--- /dev/null
+++ b/tests/tmgmt.suggestions.test
@@ -0,0 +1,168 @@
+<?php
+/*
+ * @file
+ * Contains tests for Translation management
+ */
+
+/**
+ * Basic Source-Suggestions tests.
+ */
+class TMGMTSuggestionsTestCase extends TMGMTBaseTestCase {
+
+  public function setUp() {
+    parent::setUp(array('file_entity', 'tmgmt_entity', 'entity_translation'));
+    $this->loginAsAdmin(array('administer entity translation'));
+
+    $this->setEnvironment('de');
+
+    // Enable entity translations for nodes and comments.
+    $edit = array();
+    $edit['entity_translation_entity_types[node]'] = 1;
+    $edit['entity_translation_entity_types[file]'] = 1;
+    $this->drupalPost('admin/config/regional/entity_translation', $edit, t('Save configuration'));
+  }
+
+  /**
+   * Implements getInfo().
+   */
+  static function getInfo() {
+    return array(
+      'name' => t('Suggestions tests'),
+      'description' => t('Basic suggestion operations for jobs and job-items'),
+      'group' => t('Translation Management'),
+      'dependencies' => array('file_entity'),
+    );
+  }
+
+  /**
+   * Test suggested entities from a translation job.
+   */
+  function testSuggestions() {
+    // Create a content type with fields; only the first field is translatable.
+    $type = $this->drupalCreateContentType();
+
+    $field1 = field_create_field(array(
+      'field_name' => 'field1',
+      'type' => 'file',
+      'cardinality' => -1,
+    ));
+    $field2 = field_create_field(array(
+      'field_name' => 'field2',
+      'type' => 'file',
+      'cardinality' => -1,
+      'translatable' => TRUE,
+    ));
+
+    // Create field instances on the content type.
+    field_create_instance(array(
+      'field_name' => $field1['field_name'],
+      'entity_type' => 'node',
+      'bundle' => $type->type,
+      'label' => 'Field 1',
+      'widget' => array('type' => 'file'),
+      'settings' => array(),
+    ));
+    field_create_instance(array(
+      'field_name' => $field2['field_name'],
+      'entity_type' => 'node',
+      'bundle' => $type->type,
+      'label' => 'Field 2',
+      'widget' => array('type' => 'file'),
+      'settings' => array(),
+    ));
+
+    // Make the body field translatable from node.
+    $info = field_info_field('body');
+    $info['translatable'] = TRUE;
+    field_update_field($info);
+
+    // Make the file entity fields translatable.
+    $info = field_info_field('field_file_image_alt_text');
+    $info['translatable'] = TRUE;
+    field_update_field($info);
+
+    $info = field_info_field('field_file_image_title_text');
+    $info['translatable'] = TRUE;
+    field_update_field($info);
+
+    // Create and save files - two with some text and two with no text.
+    list($file1, $file2, $file3, $file4) = $this->drupalGetTestFiles('image');
+    $file2->field_file_image_alt_text['en'][0] = array(
+      'value' => $this->randomName(),
+      'type' => 'plain_text',
+    );
+    $file2->field_file_image_title_text['en'][0] = array(
+      'value' => $this->randomName() . ' ' . $this->randomName(),
+      'type' => 'plain_text',
+    );
+
+    $file4->field_file_image_alt_text['en'][0] = array(
+      'value' => $this->randomName(),
+      'type' => 'plain_text',
+    );
+    $file4->field_file_image_title_text['en'][0] = array(
+      'value' => $this->randomName() . ' ' . $this->randomName(),
+      'type' => 'plain_text',
+    );
+
+    file_save($file1);
+    file_save($file2);
+    file_save($file3);
+    file_save($file4);
+
+    // Create a node with two translatable and two non-translatable files.
+    $node = $this->drupalCreateNode(array(
+      'type' => $type->type,
+      'language' => 'en',
+      'body' => array('en' => array(
+        array(
+          'value' => $this->randomName(),
+        ),
+      )),
+      'field1' => array(LANGUAGE_NONE => array(
+        array(
+          'fid' => $file1->fid,
+          'display' => 1,
+          'description' => '',
+        ),
+        array(
+          'fid' => $file2->fid,
+          'display' => 1,
+          'description' => '',
+        ),
+      )),
+      'field2' => array('en' => array(
+        array(
+          'fid' => $file3->fid,
+          'display' => 1,
+          'description' => '',
+        ),
+        array(
+          'fid' => $file4->fid,
+          'display' => 1,
+          'description' => '',
+        ),
+      )),
+    ));
+
+
+    // Create a job and get all suggestions.
+    $job = $this->createJob();
+    $item = $job->addItem('entity', 'node', $node->nid);
+    $suggestions = $job->getSuggestions();
+    $job->cleanSuggestionsList($suggestions);
+
+    // Check for one suggestion.
+    $this->assertEqual(count($suggestions), 1, t('Found one suggestion.'));
+
+    // Add the suggestion to the job and re-get all suggestions.
+    $suggestion = reset($suggestions);
+    $job->addJobItem($suggestion['job_item']);
+    $suggestions = $job->getSuggestions();
+    $job->cleanSuggestionsList($suggestions);
+
+    // Check for no more suggestions.
+    $this->assertEqual(count($suggestions), 0, t('Found no more suggestion.'));
+  }
+
+}
diff --git a/tmgmt.api.php b/tmgmt.api.php
index 7e0c193..1390658 100644
--- a/tmgmt.api.php
+++ b/tmgmt.api.php
@@ -38,6 +38,35 @@ function hook_tmgmt_source_plugin_info_alter(&$info) {
 }
 
 /**
+ * Return a list with TMGMTJobItem, title and a description.
+ *
+ * @param array $items
+ *   An array with TMGMTJobItems which must be checked for suggested
+ *   translations.
+ *   - 0: TMGMTJobItem A JobItem to check for suggestions.
+ *   - ...
+ * @param TMGMTJob $job
+ *   The current translation job to check for additional translation items.
+ *
+ * @return array
+ *   An array with all additional translation suggestions.
+ *   - job_item: A TMGMTJobItem instance.
+ *   - suggested: A string which indicates where this suggestion comes from.
+ *   - reference_link: Link to the entity this suggestions comes from.
+ *   - from_job: The main TMGMTJob-ID which suggests this translation.
+ */
+function hook_tmgmt_source_suggestions(array $items, TMGMTJob $job) {
+  return array(
+    array(
+      'job_item' => tmgmt_job_item_create('entity', 'node', 0),
+      'suggested' => t('Suggested @type entity', array('@type' => 'node')),
+      'entity_uri' => entity_uri('node', 0),
+      'from_job' => $job->tjid,
+    )
+  );
+}
+
+/**
  * @} End of "addtogroup tmgmt_source".
  */
 
diff --git a/tmgmt.info b/tmgmt.info
index f581284..4a99f41 100644
--- a/tmgmt.info
+++ b/tmgmt.info
@@ -7,6 +7,8 @@ dependencies[] = entity
 dependencies[] = locale
 dependencies[] = views
 
+test_dependencies[] = file_entity
+
 files[] = includes/tmgmt.exception.inc
 files[] = controller/tmgmt.controller.job.inc
 files[] = controller/tmgmt.controller.job_item.inc
@@ -35,6 +37,7 @@ files[] = tests/tmgmt.crud.test
 files[] = tests/tmgmt.plugin.test
 files[] = tests/tmgmt.helper.test
 files[] = tests/tmgmt.upgrade.alpha1.test
+files[] = tests/tmgmt.suggestions.test
 
 ; Views integration and handlers
 files[] = views/tmgmt.views.inc
diff --git a/tmgmt.module b/tmgmt.module
index bc26e7f..d6ac828 100644
--- a/tmgmt.module
+++ b/tmgmt.module
@@ -330,7 +330,7 @@ function tmgmt_job_load_multiple(array $tjids = array(), $conditions = array())
 }
 
 /**
- * Loads job entities that have a job item with the identifiers.
+ * Loads active job entities that have a job item with the identifiers.
  *
  * @param $plugin
  *   The source plugin.
@@ -372,6 +372,45 @@ function tmgmt_job_item_load_latest($plugin, $item_type, $item_id, $source_langu
 }
 
 /**
+ * Loads all latest job entities that have a job item with the identifiers.
+ *
+ * @param $plugin
+ *   The source plugin.
+ * @param $item_type
+ *   The source item type.
+ * @param $item_id
+ *   The source item id.
+ * @param string $source_language
+ *   The source language of the item.
+ *
+ * @return array
+ *   An array of job entities.
+ */
+function tmgmt_job_item_load_all_latest($plugin, $item_type, $item_id, $source_language) {
+  $query = db_select('tmgmt_job_item', 'tji');
+  $query->innerJoin('tmgmt_job', 'tj', 'tj.tjid = tji.tjid');
+  $result = $query->condition('tj.source_language', $source_language)
+    ->condition('tji.state', TMGMT_JOB_ITEM_STATE_ACCEPTED, '<>')
+    ->condition('tji.plugin', $plugin)
+    ->condition('tji.item_type', $item_type)
+    ->condition('tji.item_id', $item_id)
+    ->fields('tji', array('tjiid'))
+    ->fields('tj', array('target_language'))
+    ->orderBy('tji.changed', 'DESC')
+    ->groupBy('tj.target_language')
+    ->groupBy('tji.tjiid')
+    ->execute();
+  if ($items = $result->fetchAllKeyed()) {
+    $return = array();
+    foreach (tmgmt_job_item_load_multiple(array_keys($items)) as $key => $item) {
+      $return[$items[$key]] = $item;
+    }
+    return $return;
+  }
+  return FALSE;
+}
+
+/**
  * Returns a job which matches the requested source- and target language by
  * user. If no job exists, a new job object will be created.
  *
diff --git a/ui/css/tmgmt_ui.admin.css b/ui/css/tmgmt_ui.admin.css
index 7bc141b..cf543a4 100644
--- a/ui/css/tmgmt_ui.admin.css
+++ b/ui/css/tmgmt_ui.admin.css
@@ -8,17 +8,21 @@
   margin-right: 80px;
 }
 
-.tmgmt-ui-job-submit.tmgmt-ui-job-items {
-  max-width: 500px;
+.tmgmt-ui-translator-wrapper {
+  width: 500px;
+  margin-right: 20px;
   float: left;
 }
 
-#tmgmt-ui-translator-wrapper {
-  width: 500px;
-  margin-right: 20px;
+.tmgmt-ui-translator-wrapper-right {
+  max-width: 700px;
   float: left;
 }
 
+.tmgmt-ui-job-items-suggestions fieldset {
+  padding-top: 13px;
+}
+
 table.tmgmt-ui-review td {
   vertical-align: top;
 }
diff --git a/ui/includes/tmgmt_ui.pages.inc b/ui/includes/tmgmt_ui.pages.inc
index c57c371..9667890 100644
--- a/ui/includes/tmgmt_ui.pages.inc
+++ b/ui/includes/tmgmt_ui.pages.inc
@@ -373,7 +373,16 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
   }
 
   if ($view = views_get_view('tmgmt_ui_job_items')) {
-    $form['items'] = array(
+    // Wrapper on the right side which holds the jobs and the suggestions.
+    $form['translator_wrapper_right'] = array(
+      '#type' => 'container',
+      '#prefix' => '<div class="tmgmt-ui-translator-wrapper-right">',
+      '#suffix' => '</div>',
+      '#weight' => 25,
+    );
+
+    // Translation jobs.
+    $form['translator_wrapper_right']['items'] = array(
       '#type' => 'item',
       '#title' => $view->get_title(),
       '#prefix' => '<div class="' . 'tmgmt-ui-job-items ' . ($job->isSubmittable() ? 'tmgmt-ui-job-submit' : 'tmgmt-ui-job-manage') . '">',
@@ -382,11 +391,78 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
       '#suffix' => '</div>',
       '#weight' => $job->isSubmittable() ? 30 : 10,
     );
+
+    // A Wrapper for a button and a table with all suggestions.
+    $form['translator_wrapper_right']['suggestions'] = array(
+      '#type' => 'fieldset',
+      '#title' => '',
+      '#prefix' => '<div class="tmgmt-ui-job-items-suggestions ' . ($job->isSubmittable() ? 'tmgmt-ui-job-suggestions-submit' : 'tmgmt-ui-job-suggestions-manage') . '">',
+      '#suffix' => '</div>',
+      '#weight' => $job->isSubmittable() ? 35 : 15,
+    );
+
+    // Button to load all translation suggestions with AJAX.
+    $form['translator_wrapper_right']['suggestions']['load'] = array(
+      '#type' => 'submit',
+      '#value' => t('Load suggestions'),
+      '#submit' => array('tmgmt_ui_ajax_submit_load_suggestions'),
+      '#limit_validation_errors' => array(),
+      '#attributes' => array(
+        'class' => array('tmgmt-ui-job-suggestions-load')
+      ),
+      '#ajax' => array(
+        'callback' => 'tmgmt_ui_ajax_callback_load_suggestions',
+        'wrapper' => 'tmgmt-ui-job-items-suggestions',
+        'method' => 'replace',
+        'effect' => 'fade',
+      ),
+      '#weight' => 10,
+    );
+
+    // Create the suggestions table.
+    $suggestions_table = array(
+      '#type' => 'tableselect',
+      '#header' => array(),
+      '#options' => array(),
+      '#multiple' => TRUE,
+      '#weight' => 20,
+    );
+
+    // If this is an AJAX-Request, load all related nodes and fill the table.
+    if ($form_state['rebuild'] && $form_state['rebuild_suggestions']) {
+      _tmgmt_ui_translation_suggestions($suggestions_table, $form_state);
+
+      // A save button on bottom of the table is needed.
+      $suggestions_table = array(
+        'suggestions_table' => $suggestions_table,
+        'suggestions_save' => array(
+          '#type' => 'submit',
+          '#value' => t('Save suggestions'),
+          '#submit' => array('tmgmt_ui_ajax_submit_save_suggestions'),
+          '#limit_validation_errors' => array(array('suggestions_table')),
+          '#attributes' => array(
+            'class' => array('tmgmt-ui-job-suggestions-save')
+          ),
+          '#ajax' => array(
+            'callback' => 'tmgmt_ui_ajax_callback_load_suggestions',
+            'wrapper' => 'tmgmt-ui-job-items-suggestions',
+            'method' => 'replace',
+            'effect' => 'fade',
+          ),
+          '#weight' => 30,
+        ),
+      );
+    }
+    $form['translator_wrapper_right']['suggestions']['suggestions_list'] = array(
+      '#type' => 'container',
+      '#prefix' => '<div id="tmgmt-ui-job-items-suggestions" class="tmgmt-ui-job-items-suggestions">',
+      '#suffix' => '</div>',
+    ) + $suggestions_table;
   }
 
   $form['translator_wrapper'] = array(
     '#type' => 'container',
-    '#prefix' => '<div id="tmgmt-ui-translator-wrapper">',
+    '#prefix' => '<div class="tmgmt-ui-translator-wrapper">',
     '#suffix' => '</div>',
     '#weight' => 20,
   );
@@ -487,6 +563,109 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
 }
 
 /**
+ * Set a value in form_state to rebuild the form and fill with data.
+ */
+function tmgmt_ui_ajax_submit_load_suggestions(array $form, array &$form_state) {
+  $form_state['rebuild'] = TRUE;
+  $form_state['rebuild_suggestions'] = TRUE;
+}
+
+/**
+ * Saves selected suggestions as jobs and returns the outstanding suggestions.
+ */
+function tmgmt_ui_ajax_submit_save_suggestions($form, &$form_state) {
+  // Save all selected suggestion jobs.
+  if (isset($form_state['values']['suggestions_table']) && is_array($form_state['values']['suggestions_table'])) {
+    foreach ($form_state['values']['suggestions_table'] as $id) {
+      $id = check_plain($id);
+      if (isset($form_state['tmgmt_suggestions'][$id]['job_item'])
+        && isset($form_state['tmgmt_job'])
+        && ($form_state['tmgmt_suggestions'][$id]['job_item'] instanceof TMGMTJobItem)
+        && ($form_state['tmgmt_job'] instanceof TMGMTJob)) {
+        $item = $form_state['tmgmt_suggestions'][$id]['job_item'];
+        $form_state['tmgmt_job']->addJobItem($item);
+        // @todo: Maybe add the new item to the main 'job items table' and
+        //        refresh that too. Or at least print a message to show success.
+      }
+    }
+  }
+
+  // Force a rebuild of the form.
+  $form_state['rebuild'] = TRUE;
+  $form_state['rebuild_suggestions'] = TRUE;
+}
+
+/**
+ * Returns the suggestions table for an AJAX-Call.
+ */
+function tmgmt_ui_ajax_callback_load_suggestions($form, &$form_state) {
+  return $form['translator_wrapper_right']['suggestions']['suggestions_list'];
+}
+
+/**
+ * Fills the tableselect with all translation suggestions.
+ *
+ * Calls hook_tmgmt_source_suggestions(TMGMTJob) and creates the resulting list
+ * based on the results from all modules.
+ *
+ * @param array $suggestions_table
+ *   Tableselect part for a $form array where the #options should be inserted.
+ * @param array $form_state
+ *   The main form_state.
+ */
+function _tmgmt_ui_translation_suggestions(array &$suggestions_table, array &$form_state) {
+  $options = array();
+  $job = $form_state['tmgmt_job'];
+  if ($job instanceof TMGMTJob) {
+    // Get all suggestions from all modules which implements
+    // 'hook_tmgmt_source_suggestions' and cache them in $form_state.
+    if (!isset($form_state['tmgmt_suggestions']) || (count($form_state['tmgmt_suggestions']) <= 0)) {
+      $form_state['tmgmt_suggestions'] = $job->getSuggestions();
+    }
+
+    // Remove suggestions which are already processed, translated, ...
+    $job->cleanSuggestionsList($form_state['tmgmt_suggestions']);
+
+    // Process all valid entries.
+    foreach ($form_state['tmgmt_suggestions'] as $k => &$result) {
+      if (is_array($result) && isset($result['job_item']) && ($result['job_item'] instanceof TMGMTJobItem)) {
+        $entity = $result['job_item'];
+        $suggested = isset($result['suggested']) ? $result['suggested'] : NULL;
+        $options[$k] = _tmgmt_ui_add_suggestion_job($entity, $suggested);
+      }
+    }
+
+    $suggestions_table['#options'] = $options;
+    $suggestions_table['#empty'] = t('No related suggestions available.');
+    $suggestions_table['#header'] = array(
+      'title' => t('Title'),
+      'referenced' => t('Reference'),
+      'words' => t('Word count'),
+    );
+  }
+}
+
+/**
+ * Create a Suggestion-Table entry based on a TMGMTJob and a title.
+ *
+ * @param TMGMTJobItem $entity
+ *   A translation jobitem created by a module which is a suggestion.
+ * @param string $suggested = NULL
+ *   (Optional) Text which indicates what type of translation this is.
+ *
+ * @return array
+ *   Options-Entry for a tableselect array.
+ */
+function _tmgmt_ui_add_suggestion_job(TMGMTJobItem &$entity, $suggested = '') {
+  $uri = $entity->getSourceUri();
+  return array(
+    'title' => $entity->label(),
+    'words' => $entity->getWordCount(),
+    'referenced' => isset($uri) ? l($suggested, $uri['path'], array('attributes' => array('target' => '_blank')) + $uri['options']) : $suggested,
+  );
+}
+
+/**
  * Submit callback for the job checkout form.
  */
 function tmgmt_job_form_submit($form, &$form_state) {
