diff --git a/core/modules/locale/lib/Drupal/locale/LocaleLookup.php b/core/modules/locale/lib/Drupal/locale/LocaleLookup.php
index 30d12ec..cd2f9c0 100644
--- a/core/modules/locale/lib/Drupal/locale/LocaleLookup.php
+++ b/core/modules/locale/lib/Drupal/locale/LocaleLookup.php
@@ -55,13 +55,9 @@ public function __construct($langcode, $context, $stringStorage) {
    */
   protected function resolveCacheMiss($offset) {
     $translation = $this->stringStorage->findTranslation(array(
-      // These are the search conditions.
       'language' => $this->langcode,
       'source' => $offset,
       'context' => $this->context
-    ), array(
-      // Search options. We just need this limited set of fields.
-      'fields' => array('lid', 'version', 'translation'),
     ));
 
     if ($translation) {
diff --git a/core/modules/locale/lib/Drupal/locale/StringBase.php b/core/modules/locale/lib/Drupal/locale/StringBase.php
index fdb35e8..184c779 100644
--- a/core/modules/locale/lib/Drupal/locale/StringBase.php
+++ b/core/modules/locale/lib/Drupal/locale/StringBase.php
@@ -9,6 +9,9 @@
 
 /**
  * Defines the locale string base class.
+ *
+ * This is the base class to be used for locale string objects and contains
+ * the common properties and methods for source and translation strings.
  */
 abstract class StringBase implements StringInterface {
   /**
@@ -109,6 +112,13 @@ public function setPlurals($plurals) {
   }
 
   /**
+   * Implements Drupal\locale\StringInterface::getStorage().
+   */
+  public function getStorage() {
+    return isset($this->storage) ? $this->storage : NULL;
+  }
+
+  /**
    * Implements Drupal\locale\StringInterface::setStorage().
    */
   public function setStorage($storage) {
@@ -145,7 +155,14 @@ public function getValues(array $fields) {
    * Implements Drupal\locale\LocaleString::save().
    */
   public function save() {
-    $this->getStorage()->save($this);
+    if ($storage = $this->getStorage()) {
+      $storage->save($this);
+    }
+    else {
+      throw new StringStorageException(format_string('The string cannot be saved because its not bound to an storage: @string', array(
+          '@string' => $string->getString()
+      )));
+    }
     return $this;
   }
 
@@ -154,26 +171,16 @@ public function save() {
    */
   public function delete() {
     if (!$this->isNew()) {
-      $this->getStorage()->delete($this);
-    }
-    return $this;
-  }
-
-  /**
-   * Gets the storage to which this string is bound.
-   *
-   * @throws Drupal\locale\StringStorageException
-   *   In case the string doesn't have an storage set, an exception is thrown.
-   */
-  protected function getStorage() {
-    if (isset($this->storage)) {
-      return $this->storage;
-    }
-    else {
-      throw new StringStorageException(format_string('The string cannot be saved nor deleted because its not bound to an storage: @string', array(
+      if ($storage = $this->getStorage()) {
+        $storage->delete($this);
+      }
+      else {
+        throw new StringStorageException(format_string('The string cannot be deleted because its not bound to an storage: @string', array(
           '@string' => $string->getString()
-      )));
+        )));
+      }
     }
+    return $this;
   }
 
 }
diff --git a/core/modules/locale/lib/Drupal/locale/StringDatabaseStorage.php b/core/modules/locale/lib/Drupal/locale/StringDatabaseStorage.php
index 01927c7..ef820ad 100644
--- a/core/modules/locale/lib/Drupal/locale/StringDatabaseStorage.php
+++ b/core/modules/locale/lib/Drupal/locale/StringDatabaseStorage.php
@@ -49,7 +49,6 @@ public function __construct(Connection $connection, array $options = array()) {
    * Implements Drupal\locale\StringStorageInterface::getStrings().
    */
   public function getStrings(array $conditions = array(), array $options = array()) {
-    $options += array('source' => TRUE);
     return $this->dbStringLoad($conditions, $options, 'Drupal\locale\SourceString');
   }
 
@@ -57,16 +56,14 @@ public function getStrings(array $conditions = array(), array $options = array()
    * Implements Drupal\locale\StringStorageInterface::getTranslations().
    */
   public function getTranslations(array $conditions = array(), array $options = array()) {
-    $options += array('source' => TRUE, 'translation' => TRUE);
-    return $this->dbStringLoad($conditions, $options, 'Drupal\locale\TranslationString');
+    return $this->dbStringLoad($conditions, array('translation' => TRUE) + $options, 'Drupal\locale\TranslationString');
   }
 
   /**
    * Implements Drupal\locale\StringStorageInterface::findString().
    */
-  public function findString(array $conditions, array $options = array()) {
-    $options += array('source' => TRUE);
-    $string = $this->dbStringSelect($conditions, $options)
+  public function findString(array $conditions) {
+    $string = $this->dbStringSelect($conditions)
     ->execute()
     ->fetchObject('Drupal\locale\SourceString');
     if ($string) {
@@ -78,9 +75,8 @@ public function findString(array $conditions, array $options = array()) {
   /**
    * Implements Drupal\locale\StringStorageInterface::findTranslation().
    */
-  public function findTranslation(array $conditions, array $options = array()) {
-    $options += array('source' => TRUE, 'translation' => TRUE);
-    $string = $this->dbStringSelect($conditions, $options)
+  public function findTranslation(array $conditions) {
+    $string = $this->dbStringSelect($conditions, array('translation' => TRUE))
     ->execute()
     ->fetchObject('Drupal\locale\TranslationString');
     if ($string) {
@@ -324,34 +320,15 @@ protected function dbStringLoad(array $conditions, array $options, $class) {
    *   An associative array of additional options. It may contain any of the
    *   options used by Drupal\locale\StringStorageInterface::getStrings() and
    *   these additional ones:
-   *   - 'source', TRUE for selecting all source fields.
-   *   - 'translation', TRUE for selecting all translation fields.
-   *   - 'fields', Optional array of exact fields to get. Overrides the
-   *     previous 'source' and 'translation' options. Defaults to none.
+   *   - 'translation', Whether to include translation fields too. Defaults to
+   *     FALSE.
    * @return SelectQuery
    *   Query object with all the tables, fields and conditions.
    */
   protected function dbStringSelect(array $conditions, array $options = array()) {
-    // Check the fields we are going to select and to which table they belong.
-    $fields = array();
-    if (isset($options['fields'])) {
-      foreach ($options['fields'] as $field) {
-        $fields[$this->dbFieldTable($field)][] = $field;
-      }
-    }
-    else {
-      if (!empty($options['source'])) {
-        $fields['s'] = array();
-      }
-      if (!empty($options['translation'])) {
-        // If we've got translation fields, we leave out the lid field to avoid clashes.
-        $fields['t'] = isset($fields['s']) ? array('language', 'translation', 'customized') : array();
-      }
-    }
-
-    // Start building the query with source table and fields and check whether
-    // we need to join the target table too.
-    $query = $this->connection->select('locales_source', 's');
+    // Start building the query with source table and check whether we need to
+    // join the target table too.
+    $query = $this->connection->select('locales_source', 's', $this->options);
 
     // Figure out how to join and translate some options into conditions.
     if (isset($conditions['translated'])) {
@@ -368,7 +345,7 @@ protected function dbStringSelect(array $conditions, array $options = array()) {
       unset($conditions['translated']);
     }
     else {
-      $join = isset($fields['t']) ? 'leftJoin' : FALSE;
+      $join = !empty($options['translation']) ? 'leftJoin' : FALSE;
     }
 
     if ($join) {
@@ -385,9 +362,20 @@ protected function dbStringSelect(array $conditions, array $options = array()) {
       }
     }
     // Add fields for both tables, it may be a query without fields.
-    foreach ($fields as $table_alias => $table_fields) {
-      $query->fields($table_alias, $table_fields);
+    if (!empty($options['translation'])) {
+      // We need a query with the select fields for the target table first so
+      // in case it is an outer join and we don't have values for it, the 'lid'
+      // is taken from the source table and is not null.
+      // Note how the select fields are ordered will depend on the order the
+      // tables are added but also tables with 'all fields' will go first.
+      $query->fields('t');
+      $query->fields('s', array('lid', 'source', 'context', 'version', 'location'));
     }
+    else {
+      // We have only source fields in the query so we'll be fine doing this.
+      $query->fields('s');
+    }
+
     // Add conditions for both tables.
     foreach ($conditions as $field => $value) {
       $table_alias = $this->dbFieldTable($field);
diff --git a/core/modules/locale/lib/Drupal/locale/StringInterface.php b/core/modules/locale/lib/Drupal/locale/StringInterface.php
index c39ac70..ec04386 100644
--- a/core/modules/locale/lib/Drupal/locale/StringInterface.php
+++ b/core/modules/locale/lib/Drupal/locale/StringInterface.php
@@ -91,6 +91,14 @@ public function getPlurals();
   public function setPlurals($plurals);
 
   /**
+   * Gets the string storage.
+   *
+   * @return Drupal\locale\StringStorageInterface
+   *   The storage used for this string.
+   */
+  public function getStorage();
+
+  /**
    * Sets the string storage.
    *
    * @param Drupal\locale\StringStorageInterface $storage
diff --git a/core/modules/locale/lib/Drupal/locale/StringStorageInterface.php b/core/modules/locale/lib/Drupal/locale/StringStorageInterface.php
index 20dfca3..bdfd5fa 100644
--- a/core/modules/locale/lib/Drupal/locale/StringStorageInterface.php
+++ b/core/modules/locale/lib/Drupal/locale/StringStorageInterface.php
@@ -28,7 +28,6 @@
    *   any of the following optional keys:
    *   - 'filters': Array of string filters indexed by field name.
    *   - 'pager limit': Use pager and set this limit value.
-   *   - 'fields', Array with the exact fields to load. Defaults to all.
    *
    * @return array
    *   Array of Drupal\locale\StringInterface objects matching the conditions.
@@ -61,14 +60,11 @@ public function getTranslations(array $conditions = array(), array $options = ar
    * @param array $conditions
    *   (optional) Array with conditions that will be used to filter the strings
    *   returned and may include all of the conditions defined by getStrings().
-   * @param array $options
-   *   (optional) An associative array of additional options. It may contain
-   *   any of the options defined by getStrings().
    *
    * @return Drupal\locale\SourceString|null
    *   Minimal TranslationString object if found, NULL otherwise.
    */
-  public function findString(array $conditions, array $options = array());
+  public function findString(array $conditions);
 
   /**
    * Loads a string translation object, fast query.
@@ -76,14 +72,11 @@ public function findString(array $conditions, array $options = array());
    * @param array $conditions
    *   (optional) Array with conditions that will be used to filter the strings
    *   returned and may include all of the conditions defined by getStrings().
-   * @param array $options
-   *   (optional) An associative array of additional options. It may contain
-   *   any of the options defined by getStrings().
    *
    * @return Drupal\locale\TranslationString|null
    *   Minimal TranslationString object if found, NULL otherwise.
    */
-  public function findTranslation(array $conditions, array $options = array());
+  public function findTranslation(array $conditions);
 
   /**
    * Checks whether the string version matches a given version, fix it if not.
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleStringTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleStringTest.php
index 4666962..3c9e739 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleStringTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleStringTest.php
@@ -74,7 +74,7 @@ function testStringCRUDAPI() {
     $this->assertEqual($source->version, 'none', 'String originally created without version.');
     $this->storage->checkVersion($source, VERSION);
     $string = $this->storage->findString(array('lid' => $source->lid));
-    $this->assertEqual($source->version, VERSION, 'Checked and updated string version to Drupal version.');
+    $this->assertEqual($string->version, VERSION, 'Checked and updated string version to Drupal version.');
 
     // Create translation and find it by lid and source.
     $langcode = 'es';
@@ -99,7 +99,7 @@ function testStringCRUDAPI() {
     $lid = $source->lid;
     $translations = $this->createAllTranslations($source);
     $search = $this->storage->getTranslations(array('lid' => $source->lid));
-    $this->assertEqual(count($search), 3 , 'Created and retrieved all translations for our source string.');
+    $this->assertEqual(count($search), 3, 'Created and retrieved all translations for our source string.');
 
     $source->delete();
     $string = $this->storage->findString(array('lid' => $lid));
@@ -123,11 +123,11 @@ function testStringSearchAPI() {
     $source3 = $this->buildSourceString()->save();
     // Load all source strings.
     $strings = $this->storage->getStrings(array());
-    $this->assertEqual(count($strings), 3  , 'Found 3 source strings in the database.');
+    $this->assertEqual(count($strings), 3, 'Found 3 source strings in the database.');
     // Load all source strings matching a given string
     $filter_options['filters'] = array('source' => $prefix);
     $strings = $this->storage->getStrings(array(), $filter_options);
-    $this->assertEqual(count($strings), 2  , 'Found 2 strings using some string filter.');
+    $this->assertEqual(count($strings), 2, 'Found 2 strings using some string filter.');
 
     // Not customized translations.
     $translate1 = $this->createAllTranslations($source1);
@@ -144,24 +144,24 @@ function testStringSearchAPI() {
 
     // Load all translations. For next queries we'll be loading only translated strings.    $only_translated = array('untranslated' => FALSE);
     $translations = $this->storage->getTranslations(array('translated' => TRUE));
-    $this->assertEqual(count($translations), 2 * $language_count  , 'Created and retrieved all translations for source strings.');
+    $this->assertEqual(count($translations), 2 * $language_count, 'Created and retrieved all translations for source strings.');
 
     // Load all customized translations.
     $translations = $this->storage->getTranslations(array('customized' => LOCALE_CUSTOMIZED, 'translated' => TRUE));
-    $this->assertEqual(count($translations), $language_count  , 'Retrieved all customized translations for source strings.');
+    $this->assertEqual(count($translations), $language_count, 'Retrieved all customized translations for source strings.');
 
     // Load all Spanish customized translations
     $translations = $this->storage->getTranslations(array('language' => 'es', 'customized' => LOCALE_CUSTOMIZED, 'translated' => TRUE));
-    $this->assertEqual(count($translations), 1  , 'Found only Spanish and customized translations.');
+    $this->assertEqual(count($translations), 1, 'Found only Spanish and customized translations.');
 
     // Load all source strings without translation (1).
     $translations = $this->storage->getStrings(array('translated' => FALSE));
-    $this->assertEqual(count($translations), 1  , 'Found 1 source string without translations.');
+    $this->assertEqual(count($translations), 1, 'Found 1 source string without translations.');
 
     // Load Spanish translations using string filter.
     $filter_options['filters'] = array('source' => $prefix);
     $translations = $this->storage->getTranslations(array('language' => 'es'), $filter_options);
-    $this->assertEqual(count($strings), 2  , 'Found 2 translations using some string filter.');
+    $this->assertEqual(count($strings), 2, 'Found 2 translations using some string filter.');
 
   }
 
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index b2bfa95..a1c6b2a 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -855,7 +855,6 @@ function _locale_rebuild_js($langcode = NULL) {
   // Construct the array for JavaScript translations.
   // Only add strings with a translation to the translations array.
   $options['filters']['location'] = '.js';
-  $options['fields'] = array('lid', 'context', 'source', 'translation');
   $conditions['language'] = $language->langcode;
   $translations = array();
   foreach (locale_storage()->getTranslations($conditions, $options) as $data) {
diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc
index a6fb751..c30e978 100644
--- a/core/modules/locale/locale.pages.inc
+++ b/core/modules/locale/locale.pages.inc
@@ -406,6 +406,7 @@ function locale_translate_edit_form_submit($form, &$form_state) {
   foreach ($form_state['values']['strings'] as $lid => $translations) {
     // Get target string, that may be NULL if there's no translation.
     $target = locale_storage()->findTranslation(array('language' => $langcode, 'lid' => $lid));
+
     // No translation when all strings are empty.
     $has_translation = FALSE;
     foreach ($translations['translations'] as $string) {
