diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationTest.php
index f6ff9c3..b5ddd4f 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\locale\Tests;
 
 use Drupal\simpletest\WebTestBase;
+use Drupal\Core\Language\Language;
 
 /**
  * Functional test for string translation and validation.
@@ -467,4 +468,65 @@ function testStringSearch() {
     $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
     $this->assertText(t('No strings available.'), t("Search didn't find the invalid string."));
   }
+
+  /**
+   * Test that strings are only saved and marked as customized when they are
+   * actually changed.
+   */
+  function testUICustomizedStrings(){
+    $user = $this->drupalCreateUser(array('translate interface', 'administer languages', 'access administration pages'));
+    $this->drupalLogin($user);
+    $language = new Language(array('langcode' => 'de'));
+    language_save($language);
+
+    // Create test source string
+    $string = locale_storage()->createString(array(
+      'source' => $this->randomName(100),
+      'context' => $this->randomName(20),
+    ))->save();
+
+    // Create translation for new string and save it as non-customized.
+    $translation = locale_storage()->createTranslation(array(
+      'lid' => $string->lid,
+      'language' => 'de',
+      'translation' => $this->randomName(100),
+      'customized' => 0,
+    ))->save();
+
+    // Reset locale cache.
+    locale_reset();
+
+    // Queries strings with showing only non-customized strings.
+    $search = array(
+      'string' => $string->getString(),
+      'langcode' => 'de',
+      'translation' => 'translated',
+      'customized' => '0',
+    );
+    $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+
+    $source = $this->assertText($translation->getString(), 'Translation is found in search result.');
+
+    // Submitting the translations withouth changing the translation, so the
+    // translation should not be saved and still be returned as non-customized.
+    $textarea = current($this->xpath('//textarea'));
+    $lid = (string) $textarea[0]['name'];
+    $edit = array(
+      $lid => $translation->getString(),
+    );
+    $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+
+    $source = $this->assertText($translation->getString(), 'Translation still marked as non-customized.');
+
+    // Submitting the translations with a new the translation, so the
+    // translation will be saved as customized and no result will be returned.
+    $textarea = current($this->xpath('//textarea'));
+    $lid = (string) $textarea[0]['name'];
+    $edit = array(
+      $lid => $this->randomName(100),
+    );
+    $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+
+    $this->assertText(t('No strings available.'), "No result anymore, so the string has been saved as customized.");
+  }
 }
diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc
index 8ea8780..9de09a5 100644
--- a/core/modules/locale/locale.pages.inc
+++ b/core/modules/locale/locale.pages.inc
@@ -402,31 +402,45 @@ function locale_translate_edit_form_submit($form, &$form_state) {
 
   // Preload all translations for strings in the form.
   $lids = array_keys($form_state['values']['strings']);
-  $strings = array();
-  foreach (locale_storage()->getTranslations(array('lid' => $lids, 'language' => $langcode, 'translated' => TRUE)) as $string) {
-    $strings[$string->lid] = $string;
+  $existing_translation_objects = array();
+  foreach (locale_storage()->getTranslations(array('lid' => $lids, 'language' => $langcode, 'translated' => TRUE)) as $existing_translation_object) {
+    $existing_translation_objects[$existing_translation_object->lid] = $existing_translation_object;
   }
 
-  foreach ($form_state['values']['strings'] as $lid => $translations) {
-    // No translation when all strings are empty.
-    $has_translation = FALSE;
-    foreach ($translations['translations'] as $string) {
-      if (!empty($string)) {
-        $has_translation = TRUE;
-        break;
-      }
+  foreach ($form_state['values']['strings'] as $lid => $new_translation) {
+    $existing_translation = isset($existing_translation_objects[$lid]);
+
+    // Plural translations are saved in a delimited string. To be able to
+    // compare the new strings with the existing strings the same strings
+    // are created.
+    $new_translation_string_delimited = implode(LOCALE_PLURAL_DELIMITER, $new_translation['translations']);
+
+    // Generate an imploded string without delimiter, to be able to run
+    // empty() on it.
+    $new_translation_string = implode('', $new_translation['translations']);
+
+    $is_changed = FALSE;
+
+    if ($existing_translation && $existing_translation_objects[$lid]->translation != $new_translation_string_delimited) {
+      // If there is an existing translation in the DB and the new translation
+      // is not the same as the existing one.
+      $is_changed = TRUE;
     }
-    if ($has_translation) {
+    elseif (!$existing_translation && !empty($new_translation_string)) {
+      $is_changed = TRUE;
+    }
+
+    if ($is_changed) {
       // Only update or insert if we have a value to use.
-      $target = isset($strings[$lid]) ? $strings[$lid] : locale_storage()->createTranslation(array('lid' => $lid, 'language' => $langcode));
-      $target->setPlurals($translations['translations'])
+      $target = isset($existing_translation_objects[$lid]) ? $existing_translation_objects[$lid] : locale_storage()->createTranslation(array('lid' => $lid, 'language' => $langcode));
+      $target->setPlurals($new_translation['translations'])
         ->setCustomized()
         ->save();
       $updated[] = $target->getId();
     }
-    elseif (isset($strings[$lid])) {
-      // Empty translation entered: remove existing entry from database.
-      $strings[$lid]->delete();
+    if (empty($new_translation_string) && isset($existing_translation_objects[$lid])) {
+      // Empty new translation entered: remove existing entry from database.
+      $existing_translation_objects[$lid]->delete();
       $updated[] = $lid;
     }
   }
