diff --git a/modules/locale/locale.admin.inc b/modules/locale/locale.admin.inc
index f2da1e5c18b5acaeee8131c356250beba69feb16..7cdf1900e63999a1214082b484e30bc61e2710bf 100644
--- a/modules/locale/locale.admin.inc
+++ b/modules/locale/locale.admin.inc
@@ -272,18 +272,6 @@ function _locale_languages_common_controls(&$form, $language = NULL) {
     '#required' => TRUE,
     '#description' => t('Name of the language in the language being added.'),
   );
-  $form['prefix'] = array('#type' => 'textfield',
-    '#title' => t('Path prefix language code'),
-    '#maxlength' => 64,
-    '#default_value' => @$language->prefix,
-    '#description' => t('Language code or other custom text to use as a path prefix for URL language detection, if your <em>Detection and selection</em> settings use URL path prefixes. For the default language, this value may be left blank. <strong>Modifying this value may break existing URLs. Use with caution in a production environment.</strong> Example: Specifying "deutsch" as the path prefix code for German results in URLs like "example.com/deutsch/contact".')
-  );
-  $form['domain'] = array('#type' => 'textfield',
-    '#title' => t('Language domain'),
-    '#maxlength' => 128,
-    '#default_value' => @$language->domain,
-    '#description' => t('The domain name to use for this language if URL domains are used for <em>Detection and selection</em>. Leave blank for the default language. <strong>Changing this value may break existing URLs.</strong> Example: Specifying "de.example.com" as language domain for German will result in an URL like "http://de.example.com/contact".'),
-  );
   $form['direction'] = array('#type' => 'radios',
     '#title' => t('Direction'),
     '#required' => TRUE,
@@ -330,8 +318,6 @@ function locale_languages_predefined_form_submit($form, &$form_state) {
       'name' => $form_state['values']['name'],
       'native' => $form_state['values']['native'],
       'direction' => $form_state['values']['direction'],
-      'domain' => $form_state['values']['domain'],
-      'prefix' => $form_state['values']['prefix'],
     );
     locale_language_save($language);
     drupal_set_message(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => t($form_state['values']['name']), '@locale-help' => url('admin/help/locale'))));
@@ -371,19 +357,6 @@ function locale_languages_edit_form_validate($form, &$form_state) {
   if ($form_state['values']['native'] != check_plain($form_state['values']['native'])) {
     form_set_error('native', t('%field cannot contain any markup.', array('%field' => $form['native']['#title'])));
   }
-
-  if (!empty($form_state['values']['domain']) && !empty($form_state['values']['prefix'])) {
-    form_set_error('prefix', t('Domain and path prefix values should not be set at the same time.'));
-  }
-  if (!empty($form_state['values']['domain']) && $duplicate = db_query("SELECT language FROM {languages} WHERE domain = :domain AND language <> :language", array(':domain' => $form_state['values']['domain'], ':language' => $form_state['values']['langcode']))->fetchField()) {
-    form_set_error('domain', t('The domain (%domain) is already tied to a language (%language).', array('%domain' => $form_state['values']['domain'], '%language' => $duplicate->language)));
-  }
-  if (empty($form_state['values']['prefix']) && language_default()->language != $form_state['values']['langcode'] && empty($form_state['values']['domain'])) {
-    form_set_error('prefix', t('Only the default language can have both the domain and prefix empty.'));
-  }
-  if (!empty($form_state['values']['prefix']) && $duplicate = db_query("SELECT language FROM {languages} WHERE prefix = :prefix AND language <> :language", array(':prefix' => $form_state['values']['prefix'], ':language' => $form_state['values']['langcode']))->fetchField()) {
-    form_set_error('prefix', t('The prefix (%prefix) is already tied to a language (%language).', array('%prefix' => $form_state['values']['prefix'], '%language' => $duplicate->language)));
-  }
 }
 
 /**
@@ -397,8 +370,6 @@ function locale_languages_edit_form_submit($form, &$form_state) {
   $language->name = $form_state['values']['name'];
   $language->native = $form_state['values']['native'];
   $language->direction = $form_state['values']['direction'];
-  $language->domain = $form_state['values']['domain'];
-  $language->prefix = $form_state['values']['prefix'];
   locale_language_save($language);
   $form_state['redirect'] = 'admin/config/regional/language';
 }
@@ -672,12 +643,133 @@ function locale_language_providers_url_form($form, &$form_state) {
       LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN => t('Domain'),
     ),
     '#default_value' => variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX),
-    '#description' => t('<em>Path prefix</em>: URLs like http://example.com/de/contact set language to German (de). <em>Domain</em>: URLs like http://de.example.com/contact set the language to German. <strong>Warning: Changing this setting may break incoming URLs. Use with caution on a production site.</strong>'),
   );
 
+  $form['prefix'] = array(
+    '#type' => 'fieldset',
+    '#tree' => TRUE,
+    '#title' => t('Path prefix configuration'),
+    '#description' => t('Language codes or other custom text to use as a path prefix for URL language detection. For the default language, this value may be left blank. <strong>Modifying this value may break existing URLs. Use with caution in a production environment.</strong> Example: Specifying "deutsch" as the path prefix code for German results in URLs like "example.com/deutsch/contact".'),
+    '#states' => array(
+      'visible' => array(
+        ':input[name="locale_language_negotiation_url_part"]' => array(
+          'value' => (string) LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX,
+        ),
+      ),
+    ),
+  );
+  $form['domain'] = array(
+    '#type' => 'fieldset',
+    '#tree' => TRUE,
+    '#title' => t('Domain configuration'),
+    '#description' => t('The domain names to use for these languages. Leave blank for the default language. Use with caution in a production environment.<strong>Modifying this value may break existing URLs. Use with caution in a production environment.</strong> Example: Specifying "de.example.com" as language domain for German will result in an URL like "http://de.example.com/contact".'),
+    '#states' => array(
+      'visible' => array(
+        ':input[name="locale_language_negotiation_url_part"]' => array(
+          'value' => (string) LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN,
+        ),
+      ),
+    ),
+  );
+
+  $languages = language_list('enabled');
+  foreach ($languages[1] as $langcode => $language) {
+    $form['prefix'][$langcode] = array(
+      '#type' => 'textfield',
+      '#title' => t('%language (%langcode) path prefix', array('%language' => $language->name, '%langcode' => $language->language)),
+      '#maxlength' => 64,
+      '#default_value' => $language->prefix,
+      '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q=')
+
+    );
+    $form['domain'][$langcode] = array(
+      '#type' => 'textfield',
+      '#title' => t('%language (%langcode) domain', array('%language' => $language->name, '%langcode' => $language->language)),
+      '#maxlength' => 128,
+      '#default_value' => $language->domain,
+    );
+  }
+
   $form_state['redirect'] = 'admin/config/regional/language/configure';
 
-  return system_settings_form($form);
+  $form['actions']['#type'] = 'actions';
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save configuration'),
+  );
+  return $form;
+}
+
+/**
+ * Validation handler for url provider configuration.
+ *
+ * Validate that the prefixes and domains are unique, and make sure that
+ * the prefix and domain are only blank for the default.
+ */
+function locale_language_providers_url_form_validate($form, &$form_state) {
+  $languages = locale_language_list();
+  $default = language_default();
+
+  // Count repeated values for uniqueness check.
+  $count = array_count_values($form_state['values']['prefix']);
+  foreach ($languages as $langcode => $name) {
+    $value = $form_state['values']['prefix'][$langcode];
+
+    if ($value === '') {
+      if ($default->language != $langcode && $form_state['values']['locale_language_negotiation_url_part'] == LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX) {
+        // Validation error if the prefix is blank for a non-default language, and value is for selected negotiation type.
+        form_error($form['prefix'][$langcode], t('The prefix may only be left blank for the default language.'));
+      }
+    }
+    else if (isset($count[$value]) && $count[$value] > 1) {
+      // Validation error if there are two languages with the same domain/prefix.
+      form_error($form['prefix'][$langcode], t('The prefix for %language, %value, is not unique.', array( '%language' => $name, '%value' => $value )));
+    }
+  }
+
+  // Count repeated values for uniqueness check.
+  $count = array_count_values($form_state['values']['domain']);
+  foreach ($languages as $langcode => $name) {
+    $value = $form_state['values']['domain'][$langcode];
+
+    if ($value === '') {
+      if ($default->language != $langcode && $form_state['values']['locale_language_negotiation_url_part'] == LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN) {
+        // Validation error if the domain is blank for a non-default language, and value is for selected negotiation type.
+        form_error($form['domain'][$langcode], t('The domain may only be left blank for the default language.'));
+      }
+    }
+    else if (isset($count[$value]) && $count[$value] > 1) {
+      // Validation error if there are two languages with the same domain/domain.
+      form_error($form['domain'][$langcode], t('The domain for %language, %value, is not unique.', array( '%language' => $name, '%value' => $value )));
+    }
+  }
+}
+
+/**
+ * Save URL negotiation provider settings.
+ */
+function locale_language_providers_url_form_submit($form, &$form_state) {
+
+  // Save selected format (prefix or domain).
+  variable_set('locale_language_negotiation_url_part', $form_state['values']['locale_language_negotiation_url_part']);
+
+  $languages = language_list('enabled');
+  $default = language_default();
+
+  foreach ($languages[1] as $langcode => $language) {
+
+    // Add new prefix and domain settings to the language object.
+    foreach (array('prefix', 'domain') as $type) {
+      if (isset($form_state['values'][$type][$langcode])) {
+        $language->$type = $form_state['values'][$type][$langcode];
+      }
+    }
+
+    // Save the prefix and domain settings for each language.
+    locale_language_save($language);
+  }
+
+  drupal_set_message(t('Configuration saved.'));
 }
 
 /**
diff --git a/modules/locale/locale.test b/modules/locale/locale.test
index 31556cbeb0c48d643b34949f2164080b981f38f4..854bd246ebfc7243a2d3d33649362ad6a5a03382 100644
--- a/modules/locale/locale.test
+++ b/modules/locale/locale.test
@@ -62,13 +62,10 @@ class LocaleConfigurationTest extends DrupalWebTestCase {
     $name = $this->randomName(16);
     // The native name for the language.
     $native = $this->randomName(16);
-    // The domain prefix.
-    $prefix = $langcode;
     $edit = array(
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -90,10 +87,10 @@ class LocaleConfigurationTest extends DrupalWebTestCase {
     $this->assertNoFieldChecked('edit-site-default-en', t('Default language updated.'));
     $this->assertEqual($this->getUrl(), url('admin/config/regional/language', array('absolute' => TRUE)), t('Correct page redirection.'));
 
-    // Check if a valid language prefix is added after changing the default
+    // Check if a valid language prefix is added afrer changing the default
     // language.
-    $this->drupalGet('admin/config/regional/language/edit/en');
-    $this->assertFieldByXPath('//input[@name="prefix"]', 'en', t('A valid path prefix has been added to the previous default language.'));
+    $this->drupalGet('admin/config/regional/language/configure/url');
+    $this->assertFieldByXPath('//input[@name="prefix[en]"]', 'en', t('A valid path prefix has been added to the previous default language.'));
 
     // Ensure we can't delete the default language.
     $this->drupalGet('admin/config/regional/language/delete/' . $langcode);
@@ -211,8 +208,6 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
     $name = $this->randomName(16);
     // The native name for the language.
     $native = $this->randomName(16);
-    // The domain prefix.
-    $prefix = $langcode;
     // This is the language indicator on the translation search screen for
     // untranslated strings. Copied straight from locale.inc.
     $language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
@@ -225,7 +220,6 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -333,15 +327,12 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
     $name = $this->randomName(16);
     // The native name for the language.
     $native = $this->randomName(16);
-    // The domain prefix.
-    $prefix = $langcode;
 
     // Add custom language.
     $edit = array(
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -395,8 +386,6 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
     $name = $this->randomName(16);
     // The native name for the language.
     $native = $this->randomName(16);
-    // The domain prefix.
-    $prefix = $langcode;
     // This is the language indicator on the translation search screen for
     // untranslated strings. Copied straight from locale.inc.
     $language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
@@ -415,7 +404,6 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -461,8 +449,6 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
     $name = $this->randomName(16);
     // The native name for the language.
     $native = $this->randomName(16);
-    // The domain prefix.
-    $prefix = $langcode;
     // This is the language indicator on the translation search screen for
     // untranslated strings. Copied straight from locale.inc.
     $language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
@@ -475,7 +461,6 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -710,15 +695,12 @@ class LocaleImportFunctionalTest extends DrupalWebTestCase {
     $name = $this->randomName(16);
     // The native name for the language.
     $native = $this->randomName(16);
-    // The domain prefix.
-    $prefix = $langcode;
 
     // Create a custom language.
     $edit = array(
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -1331,13 +1313,10 @@ class LocaleUserLanguageFunctionalTest extends DrupalWebTestCase {
     $name = $this->randomName(16);
     // The native name for the language.
     $native = $this->randomName(16);
-    // The domain prefix.
-    $prefix = 'xx';
     $edit = array(
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -1349,13 +1328,10 @@ class LocaleUserLanguageFunctionalTest extends DrupalWebTestCase {
     $name_disabled = $this->randomName(16);
     // The native name for the language.
     $native_disabled = $this->randomName(16);
-    // The domain prefix.
-    $prefix_disabled = $langcode_disabled;
     $edit = array(
       'langcode' => $langcode_disabled,
       'name' => $name_disabled,
       'native' => $native_disabled,
-      'prefix' => $prefix_disabled,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -1532,11 +1508,14 @@ class LocalePathFunctionalTest extends DrupalWebTestCase {
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
 
+    // Set path prefix.
+    $edit = array( "prefix[$langcode]" => $prefix );
+    $this->drupalPost('admin/config/regional/language/configure/url', $edit, t('Save configuration'));
+
     // Check that the "xx" front page is not available when path prefixes are
     // not enabled yet.
     $this->drupalPost('admin/config/regional/language/configure', array(), t('Save settings'));
@@ -1629,6 +1608,7 @@ class LocalePathFunctionalTest extends DrupalWebTestCase {
     // Confirm that the custom path with prefix leads to the second node.
     $this->drupalGet($prefix . '/' . $custom_path);
     $this->assertText($second_node->title, t('Custom alias with prefix returns second node.'));
+
   }
 }
 
@@ -1668,13 +1648,10 @@ class LocaleContentFunctionalTest extends DrupalWebTestCase {
     $name = $this->randomName(16);
     // The native name for the language.
     $native = $this->randomName(16);
-    // The domain prefix.
-    $prefix = $langcode;
     $edit = array(
       'langcode' => $langcode,
       'name' => $name,
       'native' => $native,
-      'prefix' => $prefix,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -1686,13 +1663,10 @@ class LocaleContentFunctionalTest extends DrupalWebTestCase {
     $name_disabled = $this->randomName(16);
     // The native name for the language.
     $native_disabled = $this->randomName(16);
-    // The domain prefix.
-    $prefix_disabled = $langcode_disabled;
     $edit = array(
       'langcode' => $langcode_disabled,
       'name' => $name_disabled,
       'native' => $native_disabled,
-      'prefix' => $prefix_disabled,
       'direction' => '0',
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
@@ -1912,8 +1886,8 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
 
     // Setup for domain negotiation, first configure the language to have domain
     // URL. We use https and a port to make sure that only the domain name is used.
-    $edit = array('prefix' => '', 'domain' => "https://$language_domain:99");
-    $this->drupalPost("admin/config/regional/language/edit/$langcode", $edit, t('Save language'));
+    $edit = array("domain[$langcode]" => "https://$language_domain:99");
+    $this->drupalPost("admin/config/regional/language/configure/url", $edit, t('Save configuration'));
     // Set the site to use domain language negotiation.
 
     $tests = array(
@@ -1973,8 +1947,9 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
 
     // Enable the path prefix for the default language: this way any unprefixed
     // URL must have a valid fallback value.
-    $edit = array('prefix' => 'en');
-    $this->drupalPost('admin/config/regional/language/edit/en', $edit, t('Save language'));
+    $edit = array('prefix[en]' => 'en');
+    $this->drupalPost('admin/config/regional/language/configure/url', $edit, t('Save configuration'));
+
 
     // Enable browser and URL language detection.
     $edit = array(
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index c54bf1b8118e3bdfd00e2ca845e9d2c9fa7e5974..435811c9434c7ac7c7f593939192a8323dd17e1c 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -2250,10 +2250,13 @@ class FormatDateUnitTest extends DrupalWebTestCase {
       'name' => self::LANGCODE,
       'native' => self::LANGCODE,
       'direction' => LANGUAGE_LTR,
-      'prefix' => self::LANGCODE,
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
 
+    // Set language prefix.
+    $edit = array('prefix[' . self::LANGCODE . ']' => self::LANGCODE);
+    $this->drupalPost('admin/config/regional/language/configure/url', $edit, t('Save configuration'));
+
     // Create a test user to carry out the tests.
     $test_user = $this->drupalCreateUser();
     $this->drupalLogin($test_user);