diff --git a/translators/tmgmt_local/includes/tmgmt_local.pages.inc b/translators/tmgmt_local/includes/tmgmt_local.pages.inc
index 0366bb2..d60f9c0 100644
--- a/translators/tmgmt_local/includes/tmgmt_local.pages.inc
+++ b/translators/tmgmt_local/includes/tmgmt_local.pages.inc
@@ -43,7 +43,7 @@ function tmgmt_local_task_form($form, &$form_state, TMGMTLocalTask $task, $op =
     '#default_value' => $wrapper->status->value(),
   );
 
-  $translators = tmgmt_local_translators();
+  $translators = tmgmt_local_translators($task->getJob()->source_language, $task->getJob()->target_language);
   $form['tuid'] = array(
     '#title' => t('Assigned'),
     '#type' => 'select',
@@ -342,19 +342,22 @@ function tmgmt_local_translation_form_update_state_ajax($form, &$form_state) {
 /**
  * Form for assigning multiple tasks to translator.
  *
- * @param type $form
+ * @param array $form
  * @param array $form_state
  * @param string $tasks
  *  Comma separated tasks ids.
+ *
+ * @return array
+ *   Drupal form definition.
  */
 function tmgmt_local_translation_assign_form($form, &$form_state, $tasks) {
-  $form_state['tasks'] = $tasks;
+  $form_state['tasks'] = explode(',', $tasks);
 
-  $translators = tmgmt_local_translators();
   $form['tuid'] = array(
     '#title' => t('Assign to'),
     '#type' => 'select',
-    '#options' => array('' => t('Select user')) + $translators,
+    '#empty_option' => t('Select user'),
+    '#options' => tmgmt_local_get_translators_for_tasks($form_state['tasks']),
     '#required' => TRUE,
   );
 
@@ -371,12 +374,10 @@ function tmgmt_local_translation_assign_form($form, &$form_state, $tasks) {
  * Submit handler for form for assigning multiple tasks to translator.
  */
 function tmgmt_local_translation_assign_form_submit($form, &$form_state) {
-  $tasks = explode(',', $form_state['tasks']);
-
   $translator = user_load($form_state['values']['tuid']);
 
   $how_many = 0;
-  foreach ($tasks as $task_id) {
+  foreach ($form_state['tasks'] as $task_id) {
     $task = tmgmt_local_task_load($task_id);
     if ($task) {
       $task->assign($translator);
@@ -397,13 +398,13 @@ function tmgmt_local_translation_assign_form_submit($form, &$form_state) {
  * @see tmgmt_local_translation_assign_form().
  */
 function tmgmt_local_translation_reassign_form($form, &$form_state, $tasks) {
-  $form_state['tasks'] = $tasks;
+  $form_state['tasks'] = explode(',', $tasks);
 
-  $translators = tmgmt_local_translators();
   $form['tuid'] = array(
     '#title' => t('Assign to'),
     '#type' => 'select',
-    '#options' => array('' => t('none')) + $translators,
+    '#empty_option' => t('Select user'),
+    '#options' => tmgmt_local_get_translators_for_tasks($form_state['tasks']),
   );
 
   $form['actions']['#type'] = 'actions';
@@ -419,7 +420,6 @@ function tmgmt_local_translation_reassign_form($form, &$form_state, $tasks) {
  * Submit handler for form for reassigning multiple tasks to translator.
  */
 function tmgmt_local_translation_reassign_form_submit($form, &$form_state) {
-  $tasks = explode(',', $form_state['tasks']);
 
   if (!empty($form_state['values']['tuid'])) {
     $translator = user_load($form_state['values']['tuid']);
@@ -429,7 +429,7 @@ function tmgmt_local_translation_reassign_form_submit($form, &$form_state) {
   }
 
   $how_many = 0;
-  foreach ($tasks as $task_id) {
+  foreach ($form_state['tasks'] as $task_id) {
     $task = tmgmt_local_task_load($task_id);
     if ($task) {
       if ($translator->uid) {
diff --git a/translators/tmgmt_local/includes/tmgmt_local.plugin.inc b/translators/tmgmt_local/includes/tmgmt_local.plugin.inc
index 2975108..9aee73a 100644
--- a/translators/tmgmt_local/includes/tmgmt_local.plugin.inc
+++ b/translators/tmgmt_local/includes/tmgmt_local.plugin.inc
@@ -36,8 +36,12 @@ class TMGMTLocalTranslatorPluginController extends TMGMTDefaultTranslatorPluginC
   /**
    * Overrides TMGMTDefaultTranslatorPluginController::getSupportedTargetLanguages().
    */
-  public function getSupportedTargetLanguages(TMGMTTranslator $translator, $language) {
-    return drupal_map_assoc(tmgmt_local_translation_capabilities($language));
+  public function getSupportedTargetLanguages(TMGMTTranslator $translator, $source_language) {
+    $languages = drupal_map_assoc(tmgmt_local_translation_capabilities($source_language));
+    if ($translator->getSetting('allow_all')) {
+      $languages += parent::getSupportedTargetLanguages($translator, $source_language);
+    }
+    return $languages;
   }
 
 }
@@ -51,7 +55,7 @@ class TMGMTLocalTranslatorUIController extends TMGMTDefaultTranslatorUIControlle
    * Overrides TMGMTDefaultTranslatorPluginController::checkoutSettingsForm().
    */
   public function checkoutSettingsForm($form, &$form_state, TMGMTJob $job) {
-    if ($translators = tmgmt_local_translators()) {
+    if ($translators = tmgmt_local_translators($job->source_language, $job->target_language)) {
       $form['translator'] = array(
         '#title' => t('Select translator for this job'),
         '#type' => 'select',
@@ -86,4 +90,13 @@ class TMGMTLocalTranslatorUIController extends TMGMTDefaultTranslatorUIControlle
     return $form;
   }
 
+  public function pluginSettingsForm($form, &$form_state, TMGMTTranslator $translator, $busy = FALSE) {
+    $form['allow_all'] = array(
+      '#title' => t('Allow translations for enabled languages even if no translator has the necessary capabilities'),
+      '#type' => 'checkbox',
+      '#default_value' => $translator->getSetting('allow_all'),
+    );
+    return $form;
+  }
+
 }
diff --git a/translators/tmgmt_local/skills/tmgmt_skills.module b/translators/tmgmt_local/skills/tmgmt_skills.module
index 591b1b0..6389272 100644
--- a/translators/tmgmt_local/skills/tmgmt_skills.module
+++ b/translators/tmgmt_local/skills/tmgmt_skills.module
@@ -251,7 +251,7 @@ function tmgmt_skills_field_access($op, $field, $entity_type, $entity = NULL, $a
  * Implements hook_field_update().
  */
 function tmgmt_skills_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  if ($entity_type != 'user' || array_intersect_key(user_roles(TRUE, 'provide translation services'), $entity->roles)) {
+  if ($entity_type != 'user' || !array_intersect_key(user_roles(TRUE, 'provide translation services'), $entity->roles)) {
     return;
   }
 
@@ -274,7 +274,7 @@ function tmgmt_skills_field_update($entity_type, $entity, $field, $instance, $la
  * Implements hook_field_delete().
  */
 function tmgmt_skills_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  if ($entity_type != 'user' || array_intersect_key(user_roles(TRUE, 'provide translation services'), $entity->roles)) {
+  if ($entity_type != 'user' || !array_intersect_key(user_roles(TRUE, 'provide translation services'), $entity->roles)) {
     return;
   }
   tmgmt_local_clear_languages_cache();
@@ -284,7 +284,7 @@ function tmgmt_skills_field_delete($entity_type, $entity, $field, $instance, $la
  * Implements hook_field_attach_delete().
  */
 function tmgmt_skills_field_attach_delete($entity_type, $entity) {
-  if ($entity_type != 'user' || array_intersect_key(user_roles(TRUE, 'provide translation services'), $entity->roles)) {
+  if ($entity_type != 'user' || !array_intersect_key(user_roles(TRUE, 'provide translation services'), $entity->roles)) {
     return;
   }
   tmgmt_local_clear_languages_cache();
@@ -293,7 +293,7 @@ function tmgmt_skills_field_attach_delete($entity_type, $entity) {
 /**
  * Implements hook_tmgmt_local_translation_capabilities().
  */
-function tmgmt_skills_tmgmt_local_translation_capabilities($source_language = NULL, $account = NULL) {
+function tmgmt_skills_tmgmt_local_translation_capabilities($source_language = NULL, $account = NULL, $target_language = NULL) {
   // Only considers users with the 'provide translation services' permission.
   $roles = user_roles(TRUE, 'provide translation services');
 
@@ -310,6 +310,10 @@ function tmgmt_skills_tmgmt_local_translation_capabilities($source_language = NU
     $query->condition('ts.tmgmt_translation_skills_language_from', $source_language);
   }
 
+  if ($target_language) {
+    $query->condition('ts.tmgmt_translation_skills_language_to', $target_language);
+  }
+
   // Only consider active users.
   $query->innerJoin('users', 'u', 'u.uid = ts.entity_id AND u.status = 1');
 
@@ -347,15 +351,18 @@ function tmgmt_skills_tmgmt_server_language_pairs() {
   $query = db_select('field_data_tmgmt_translation_skills', 'ts');
 
   $query->join('users', 'u', 'u.uid = ts.entity_id AND u.status = 1');
-  $query->join('users_roles', 'ur', 'ur.uid = u.uid AND ur.rid');
 
   $query->addField('ts', 'tmgmt_translation_skills_language_from', 'source_language');
   $query->addField('ts', 'tmgmt_translation_skills_language_to', 'target_language');
 
   $query->condition('ts.deleted', 0);
   $query->condition('ts.entity_type', 'user');
-  $or_conditions = db_or()->condition('ur.rid', array_keys($roles))->condition('u.uid', 1);
-  $query->condition($or_conditions);
+
+  if (!in_array(DRUPAL_AUTHENTICATED_RID, array_keys($roles))) {
+    $query->join('users_roles', 'ur', 'ur.uid = u.uid AND ur.rid');
+    $or_conditions = db_or()->condition('ur.rid', array_keys($roles))->condition('u.uid', 1);
+    $query->condition($or_conditions);
+  }
 
   $capabilities = array();
   foreach ($query->execute()->fetchAll() as $item) {
diff --git a/translators/tmgmt_local/tmgmt_local.module b/translators/tmgmt_local/tmgmt_local.module
index 2840b0c..ef8d41e 100644
--- a/translators/tmgmt_local/tmgmt_local.module
+++ b/translators/tmgmt_local/tmgmt_local.module
@@ -311,8 +311,12 @@ function tmgmt_local_translation_capabilities($source_language = NULL, $account
  * the translation capabilities of an local have changed.
  */
 function tmgmt_local_clear_languages_cache() {
-  foreach (tmgmt_translator_load_multiple(FALSE) as $translator) {
-    if ($translator->plugin == 'local') {
+  $query = new EntityFieldQuery();
+  $query->entityCondition('entity_type', 'tmgmt_translator');
+  $query->propertyCondition('plugin', 'local');
+  $result = $query->execute();
+  if ($result) {
+    foreach (tmgmt_translator_load_multiple(array_keys($result['tmgmt_translator'])) as $translator) {
       cache_clear_all('languages::' . $translator->name, 'cache_tmgmt');
     }
   }
@@ -508,6 +512,33 @@ function tmgmt_local_task_statuses() {
 }
 
 /**
+ * Gets all involved language pairs for given tasks.
+ *
+ * @param array $tasks
+ *   Array of tasks ids.
+ *
+ * @return array
+ *   Array of involved languages.
+ */
+function tmgmt_local_tasks_languages($tasks) {
+  $query = db_select('tmgmt_local_task', 't');
+  $query->condition('tltid', $tasks);
+  $query->join('tmgmt_job', 'j', 't.tjid = j.tjid');
+  $query->fields('j', array('source_language', 'target_language'));
+  $query->groupBy('target_language');
+  $result = $query->execute()->fetchAll();
+  $languages = array();
+
+  foreach ($result as $row) {
+    if (empty($languages[$row->source_language]) || !in_array($row->target_language, $languages[$row->source_language])) {
+      $languages[$row->source_language][] = $row->target_language;
+    }
+  }
+
+  return $languages;
+}
+
+/**
  * Return users that belongs to local translation role.
  *
  * @todo: This does not scale when having many translators.
@@ -516,21 +547,40 @@ function tmgmt_local_task_statuses() {
  *   Array of uid => name translators or empty array if there are no translator
  *   users.
  */
-function tmgmt_local_translators() {
+function tmgmt_local_translators($source_language = NULL, $target_language = NULL) {
   // Get all local user translators.
   $roles = user_roles(TRUE, 'provide translation services');
-  $query = db_select('users_roles', 'ur');
-  $query->join('users', 'u', 'u.uid = ur.uid');
-  $uids = $query->fields('u', array('uid'))
-    ->condition('ur.rid', array_keys($roles))
-    ->condition('u.status', 1)
-    ->distinct()
+  $query = db_select('users', 'u');
+  $query->fields('u', array('uid'));
+  $query->condition('u.status', 1);
+
+  // Add role condition only if authenticated user role does not have perms.
+  if (!in_array(DRUPAL_AUTHENTICATED_RID, array_keys($roles))) {
+    $query->leftJoin('users_roles', 'ur', 'u.uid = ur.uid');
+    $query->condition('ur.rid', array_keys($roles));
+  }
+
+  $uids = $query->distinct()
     ->execute()
     ->fetchCol();
 
+  if (!empty($target_language) && !is_array($target_language)) {
+    $target_language = array($target_language);
+  }
+
   $translators = array();
   if (!empty($uids)) {
     foreach (user_load_multiple($uids) as $user) {
+      // @todo: There is no capabilities API yet for returning users, so
+      //   re-check every user.
+      $capabilities = tmgmt_local_translation_capabilities($source_language, $user);
+      if (empty($capabilities)) {
+        continue;
+      }
+      // In case provided target languages exceed users capabilities exclude.
+      if (!empty($target_language) && count(array_diff($target_language, $capabilities)) > 0) {
+        continue;
+      }
       $translators[$user->uid] = entity_label('user', $user);
     }
   }
@@ -539,5 +589,28 @@ function tmgmt_local_translators() {
 }
 
 /**
+ * Gets translators able to translate all given tasks.
+ *
+ * @param array $tasks
+ *   Array of tasks ids.
+ *
+ * @return array
+ *   List of uid => name values.
+ */
+function tmgmt_local_get_translators_for_tasks($tasks) {
+  $translators = array();
+
+  foreach (tmgmt_local_tasks_languages($tasks) as $source_language => $target_languages) {
+    $translators[] = tmgmt_local_translators($source_language, $target_languages);
+  }
+
+  if (count($translators) > 1) {
+    return call_user_func_array('array_intersect', $translators);
+  }
+
+  return array_shift($translators);
+}
+
+/**
  * @} End of "addtogroup tmgmt_local_task".
  */
diff --git a/translators/tmgmt_local/tmgmt_local.test b/translators/tmgmt_local/tmgmt_local.test
index bb2957d..1066cc7 100644
--- a/translators/tmgmt_local/tmgmt_local.test
+++ b/translators/tmgmt_local/tmgmt_local.test
@@ -46,21 +46,117 @@ class TMGMTLocalTestCase extends TMGMTBaseTestCase {
 
   }
 
-  /**
-   * Tests export and import for the HTML format.
-   */
-  function testHTML() {
-    $translator = tmgmt_translator_load('local');
+  function testTranslatorSkillsForTasks() {
 
-    // @todo: Allow submitting of jobs even when no user exists yet who can
-    //   translate that job.
-    $this->drupalLogin($this->local_translator);
-    // Configure language capabilities.
+    $this->setEnvironment('fr');
+
+    $translator1 = $this->drupalCreateUser($this->local_translator_permissions);
+    $this->drupalLogin($translator1);
     $edit = array(
       'tmgmt_translation_skills[und][0][language_from]' => 'en',
       'tmgmt_translation_skills[und][0][language_to]' => 'de',
     );
-    $this->drupalPost('user/' . $this->local_translator->uid . '/edit', $edit, t('Save'));
+    $this->drupalPost('user/' . $translator1->uid . '/edit', $edit, t('Save'));
+
+    $translator2 = $this->drupalCreateUser($this->local_translator_permissions);
+    $this->drupalLogin($translator2);
+    $edit = array(
+      'tmgmt_translation_skills[und][0][language_from]' => 'en',
+      'tmgmt_translation_skills[und][0][language_to]' => 'de',
+    );
+    $this->drupalPost('user/' . $translator2->uid . '/edit', $edit, t('Save'));
+    $edit = array(
+      'tmgmt_translation_skills[und][1][language_from]' => 'de',
+      'tmgmt_translation_skills[und][1][language_to]' => 'en',
+    );
+    $this->drupalPost('user/' . $translator2->uid . '/edit', $edit, t('Save'));
+
+    $translator3 = $this->drupalCreateUser($this->local_translator_permissions);
+    $this->drupalLogin($translator3);
+    $edit = array(
+      'tmgmt_translation_skills[und][0][language_from]' => 'en',
+      'tmgmt_translation_skills[und][0][language_to]' => 'de',
+    );
+    $this->drupalPost('user/' . $translator3->uid . '/edit', $edit, t('Save'));
+    $edit = array(
+      'tmgmt_translation_skills[und][1][language_from]' => 'de',
+      'tmgmt_translation_skills[und][1][language_to]' => 'en',
+    );
+    $this->drupalPost('user/' . $translator3->uid . '/edit', $edit, t('Save'));
+    $edit = array(
+      'tmgmt_translation_skills[und][2][language_from]' => 'en',
+      'tmgmt_translation_skills[und][2][language_to]' => 'fr',
+    );
+    $this->drupalPost('user/' . $translator3->uid . '/edit', $edit, t('Save'));
+
+
+    $job1 = $this->createJob('en', 'de');
+    $job2 = $this->createJob('de', 'en');
+    $job3 = $this->createJob('en', 'fr');
+
+    $local_task1 = tmgmt_local_task_create(array(
+      'uid' => $job1->uid,
+      'tjid' => $job1->tjid,
+      'title' => 'Task 1',
+    ));
+    $local_task1->save();
+
+    $local_task2 = tmgmt_local_task_create(array(
+      'uid' => $job2->uid,
+      'tjid' => $job2->tjid,
+      'title' => 'Task 2',
+    ));
+    $local_task2->save();
+
+    $local_task3 = tmgmt_local_task_create(array(
+      'uid' => $job3->uid,
+      'tjid' => $job3->tjid,
+      'title' => 'Task 3',
+    ));
+    $local_task3->save();
+
+    // Test languages involved in tasks.
+    $this->assertEqual(
+      tmgmt_local_tasks_languages(array($local_task1->tltid, $local_task2->tltid, $local_task3->tltid)),
+      array(
+        'en' => array('de', 'fr'),
+        'de' => array('en'),
+      )
+    );
+
+    // Test available translators for task en - de.
+    $this->assertEqual(
+      tmgmt_local_get_translators_for_tasks(array($local_task1->tltid)),
+      array(
+        $translator1->uid => entity_label('user', $translator1),
+        $translator2->uid => entity_label('user', $translator2),
+        $translator3->uid => entity_label('user', $translator3),
+      )
+    );
+
+    // Test available translators for tasks en - de, de - en.
+    $this->assertEqual(
+      tmgmt_local_get_translators_for_tasks(array($local_task1->tltid, $local_task2->tltid)),
+      array(
+        $translator2->uid => entity_label('user', $translator2),
+        $translator3->uid => entity_label('user', $translator3),
+      )
+    );
+
+    // Test available translators for tasks en - de, de - en, en - fr.
+    $this->assertEqual(
+      tmgmt_local_get_translators_for_tasks(array($local_task1->tltid, $local_task2->tltid, $local_task3->tltid)),
+      array(
+        $translator3->uid => entity_label('user', $translator3),
+      )
+    );
+  }
+
+  /**
+   * Test the basic translation workflow
+   */
+  function testBasicWorkflow() {
+    $translator = tmgmt_translator_load('local');
 
     // Create a job and request a local translation.
     $this->loginAsTranslator();
@@ -69,8 +165,41 @@ class TMGMTLocalTestCase extends TMGMTBaseTestCase {
     $job->addItem('test_source', 'test', '1');
     $job->addItem('test_source', 'test', '2');
 
+    // Create another local translator with the required capabilities.
+    $other_translator_same = $this->drupalCreateUser($this->local_translator_permissions);
+    $this->drupalLogin($other_translator_same);
+    // Configure language capabilities.
+    $edit = array(
+      'tmgmt_translation_skills[und][0][language_from]' => 'en',
+      'tmgmt_translation_skills[und][0][language_to]' => 'de',
+    );
+    $this->drupalPost('user/' . $other_translator_same->uid . '/edit', $edit, t('Save'));
+
+    // Check that the user is not listed in the translator selection form.
+    $uri = $job->uri();
+    $this->loginAsAdmin();
+    $this->drupalGet($uri['path']);
+    $this->assertText(t('Select translator for this job'));
+    $this->assertText($other_translator_same->name);
+    $this->assertNoText($this->local_translator->name);
+
+    $this->drupalLogin($this->local_translator);
+    // Configure language capabilities.
+    $edit = array(
+      'tmgmt_translation_skills[und][0][language_from]' => 'en',
+      'tmgmt_translation_skills[und][0][language_to]' => 'de',
+    );
+    $this->drupalPost('user/' . $this->local_translator->uid . '/edit', $edit, t('Save'));
+
+    // Check that the translator is now listed.
+    $this->loginAsAdmin();
+    $this->drupalGet($uri['path']);
+    $this->assertText($this->local_translator->name);
+
     $job->requestTranslation();
 
+    $this->drupalLogin($this->local_translator);
+
     // Create a second local translator with different language capabilities,
     // make sure that he does not see the task.
     $other_translator = $this->drupalCreateUser($this->local_translator_permissions);
@@ -85,7 +214,6 @@ class TMGMTLocalTestCase extends TMGMTBaseTestCase {
     $this->assertNoText(t('Task for @job', array('@job' => $job->label())));
 
     $this->drupalLogin($this->local_translator);
-    $this->drupalGet('user');
 
     // Check the translate overview.
     $this->drupalGet('translate');
@@ -94,6 +222,14 @@ class TMGMTLocalTestCase extends TMGMTBaseTestCase {
     //$this->assertText(t('@from => @to', array('@from' => 'en', '@to' => 'de')));
     $this->clickLink(t('assign'));
 
+    // Log in with the translator with the same capabilities, make sure that he
+    // does not see the assigned task.
+    $this->drupalLogin($other_translator_same);
+    $this->drupalGet('translate');
+    $this->assertNoText(t('Task for @job', array('@job' => $job->label())));
+
+    $this->drupalLogin($this->local_translator);
+
     // @todo: Assign bulk action missing, permission problem?
     /*$edit = array(
       'views_bulk_operations[0]' => $job->tjid,
@@ -101,6 +237,7 @@ class TMGMTLocalTestCase extends TMGMTBaseTestCase {
     $this->drupalPost(NULL, $edit, t('Assign to me'));*/
 
     // Translate the task.
+    $this->drupalGet('translate');
     $this->clickLink(t('translate'));
     $this->assertText(t('Translation for @source', array('@source' => 'test_source:test:1')));
     $this->assertText(t('Translation for @source', array('@source' => 'test_source:test:2')));
@@ -165,4 +302,26 @@ class TMGMTLocalTestCase extends TMGMTBaseTestCase {
     $this->assertEqual($item2->getData(array('dummy', 'deep_nesting', '#translation', '#text')), $translation2);
   }
 
+  /**
+   * Test the allow all setting.
+   */
+  function testAllowAll() {
+    $translator = tmgmt_translator_load('local');
+
+    // Create a job and request a local translation.
+    $this->loginAsTranslator();
+    $job = $this->createJob();
+    $job->translator = $translator->name;
+    $job->addItem('test_source', 'test', '1');
+    $job->addItem('test_source', 'test', '2');
+
+    $this->assertFalse($job->requestTranslation(), 'Translation request was denied.');
+
+    // Now enable the setting.
+    $translator->settings['allow_all'] = TRUE;
+    $translator->save();
+
+    $this->assertIdentical(NULL, $job->requestTranslation(), 'Translation request was successfull');
+    $this->assertTrue($job->isActive());
+  }
 }
