diff --git a/metatag.module b/metatag.module
index 0ffe268..b1ac275 100644
--- a/metatag.module
+++ b/metatag.module
@@ -498,79 +498,74 @@ function metatag_metatags_save($entity_type, $entity_id, $revision_id, $metatags
     $revision_id = 0;
   }
 
-  // Ensure the data saves during node_save().
-  if (isset($metatags[$langcode]) && count(array_diff_key($metatags, $languages)) > 0) {
-    // There are certain occasions when the old data and the new data are
-    // *both* added to the $metatags array, in this case throw away the language
-    // data.
-    $lang_data = $metatags[$langcode];
-    unset($metatags[$langcode]);
-    if (empty($metatags)) {
-      $metatags = $lang_data;
+  // Update each of the per-language metatag configurations in turn.
+  foreach($metatags as $langcode => $new_metatags) {
+    // Allow other modules to alter the meta tags prior to saving using
+    // hook_metatag_presave().
+    foreach (module_implements('metatag_presave') as $module) {
+      $function = "{$module}_metatag_presave";
+      $function($new_metatags, $entity_type, $entity_id, $revision_id, $langcode);
     }
-  }
 
-  // Allow other modules to alter the meta tags prior to saving using
-  // hook_metatag_presave().
-  foreach (module_implements('metatag_presave') as $module) {
-    $function = "{$module}_metatag_presave";
-    $function($metatags, $entity_type, $entity_id, $revision_id, $langcode);
-  }
-
-  // We need to ensure that when we have multiple languages enabled that those
-  // languages get the incremented revision_id as well so that they can be
-  // loaded properly.
-  if (isset($old_vid) && drupal_multilingual()) {
-    // Get all translations of tag data for this entity.
-    $results = db_query("SELECT language, data FROM {metatag} WHERE (entity_type = :type) AND (entity_id = :id) AND (revision_id = :revision) AND language != :langcode",
-      array(
-        ':type'     => $entity_type,
-        ':id'       => $entity_id,
-        ':revision' => $old_vid,
-        ':langcode' => $langcode
-      ))->fetchAllKeyed();
-    foreach ($results as $lang => $data) {
-      $old_metatags = unserialize($data);
-      // Save the record.
-      if (!empty($old_metatags)) {
-        db_merge('metatag')
-          ->key(array(
-            'entity_type' => $entity_type,
-            'entity_id'   => $entity_id,
-            'language'    => $lang,
-            'revision_id' => $revision_id,
-          ))
-          ->fields(array(
-            'data' => serialize($old_metatags),
-          ))
-          ->execute();
+    // We need to ensure that when we have multiple languages enabled that those
+    // languages get the incremented revision_id as well so that they can be
+    // loaded properly.
+    if (isset($old_vid) && drupal_multilingual()) {
+      // Get all translations of tag data for this entity.
+      $results = db_query("SELECT language, data FROM {metatag} WHERE (entity_type = :type) AND (entity_id = :id) AND (revision_id = :revision) AND language != :langcode",
+        array(
+          ':type'     => $entity_type,
+          ':id'       => $entity_id,
+          ':revision' => $old_vid,
+          ':langcode' => $langcode
+        ))->fetchAllKeyed();
+      foreach ($results as $lang => $data) {
+        // If the other records are not going to be saved during this submission
+        // then manually update them.
+        if (!isset($metatags[$lang])) {
+          $old_metatags = unserialize($data);
+          // Save the record.
+          if (!empty($old_metatags)) {
+            db_merge('metatag')
+              ->key(array(
+                'entity_type' => $entity_type,
+                'entity_id'   => $entity_id,
+                'language'    => $lang,
+                'revision_id' => $revision_id,
+              ))
+              ->fields(array(
+                'data' => serialize($old_metatags),
+              ))
+              ->execute();
+          }
+        }
       }
     }
-  }
 
-  // If the data array is empty, there is no data to actually save, so just
-  // delete the record from the database.
-  if (empty($metatags)) {
-    db_delete('metatag')
-      ->condition('entity_type', $entity_type)
-      ->condition('entity_id', $entity_id)
-      ->condition('revision_id', $revision_id)
-      ->condition('language', $langcode)
-      ->execute();
-  }
-  else {
+    // If the data array is empty, there is no data to actually save, so just
+    // delete the record from the database.
+    if (empty($new_metatags)) {
+      db_delete('metatag')
+        ->condition('entity_type', $entity_type)
+        ->condition('entity_id', $entity_id)
+        ->condition('revision_id', $revision_id)
+        ->condition('language', $langcode)
+        ->execute();
+    }
     // Otherwise save the data for this entity.
-    db_merge('metatag')
-      ->key(array(
-        'entity_type' => $entity_type,
-        'entity_id' => $entity_id,
-        'language' => $langcode,
-        'revision_id' => $revision_id,
-      ))
-      ->fields(array(
-        'data' => serialize($metatags),
-      ))
-      ->execute();
+    else {
+      db_merge('metatag')
+        ->key(array(
+          'entity_type' => $entity_type,
+          'entity_id' => $entity_id,
+          'language' => $langcode,
+          'revision_id' => $revision_id,
+        ))
+        ->fields(array(
+          'data' => serialize($new_metatags),
+        ))
+        ->execute();
+    }
   }
 
   // Clear cached data.
@@ -1076,6 +1071,16 @@ function metatag_metatags_form(array &$form, $instance, array $metatags = array(
     return;
   }
 
+  // Work out the language code to use, default to NONE.
+  $langcode = LANGUAGE_NONE;
+  if (isset($form['#entity_type'])) {
+    $entity_info = entity_get_info();
+    if (!empty($entity_info[$form['#entity_type']]['translation']['locale'])) {
+      // The language to use for this form.
+      $langcode = $GLOBALS['language_content']->language;
+    }
+  }
+
   // Merge in the default options.
   $options += array(
     'token types' => array(),
@@ -1086,26 +1091,32 @@ function metatag_metatags_form(array &$form, $instance, array $metatags = array(
   $form['metatags'] = array(
     '#type' => 'fieldset',
     '#title' => t('Meta tags'),
-    '#multilingual' => TRUE,
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
+    '#multilingual' => TRUE,
     '#tree' => TRUE,
     '#access' => user_access('edit meta tags') || user_access('administer meta tags'),
     '#weight' => 40,
+    '#language' => $langcode,
     '#attributes' => array(
       'class' => array('metatags-form'),
     ),
+  );
+  $form['metatags'][$langcode] = array(
     '#metatag_defaults' => $options['defaults'],
+    '#type' => 'container',
+    '#multilingual' => TRUE,
+    '#tree' => TRUE,
   );
   // Show a different intro message for entity pages vs config pages.
   if (isset($form['#entity'])) {
-    $form['metatags']['intro_text'] = array(
+    $form['metatags'][$langcode]['intro_text'] = array(
       '#markup' => '<p>' . t('Configure the meta tags below. Tokens, e.g. "[node:summary]", automatically insert the corresponding information from that field or value, which helps to avoid redundant meta data and possible search engine penalization; see the "Browse available tokens" popup for more details.') . '</p>',
       '#weight' => -10,
     );
   }
   else {
-    $form['metatags']['intro_text'] = array(
+    $form['metatags'][$langcode]['intro_text'] = array(
       '#markup' => '<p>' . t('Configure the meta tags below. Use tokens (see the "Browse available tokens" popup) to avoid redundant meta data and search engine penalization. For example, a \'keyword\' value of "example" will be shown on all content using this configuration, whereas using the [node:field_keywords] automatically inserts the "keywords" values from the current entity (node, term, etc).') . '</p>',
       '#weight' => -10,
     );
@@ -1161,9 +1172,9 @@ function metatag_metatags_form(array &$form, $instance, array $metatags = array(
 
     if (!empty($metatag_info['group'])) {
       $group_key = $metatag_info['group'];
-      if (isset($info['groups'][$group_key]['label']) && !isset($form['metatags'][$group_key])) {
+      if (isset($info['groups'][$group_key]['label']) && !isset($form['metatags'][$langcode][$group_key])) {
         $group = $info['groups'][$group_key] + array('form' => array(), 'description' => NULL);
-        $form['metatags'][$group_key] = $group['form'] + array(
+        $form['metatags'][$langcode][$group_key] = $group['form'] + array(
           '#type' => 'fieldset',
           '#title' => check_plain($group['label']),
           '#description' => filter_xss($group['description']),
@@ -1171,22 +1182,22 @@ function metatag_metatags_form(array &$form, $instance, array $metatags = array(
           '#collapsed' => TRUE,
         );
       }
-      $form['metatags'][$group_key][$metatag] = $metatag_form + array('#parents' => array('metatags', $metatag));
+      $form['metatags'][$langcode][$group_key][$metatag] = $metatag_form + array('#parents' => array('metatags', $langcode, $metatag));
 
       // Hide the fieldset itself if there is not at least one of the meta tag
       // fields visible.
       if (variable_get('metatag_extended_permissions', FALSE)) {
-        $form['metatags'][$group_key]['#access'] = count(element_get_visible_children($form['metatags'][$group_key])) > 0;
+        $form['metatags'][$langcode][$group_key]['#access'] = count(element_get_visible_children($form['metatags'][$langcode][$group_key])) > 0;
       }
       else {
-        $form['metatags'][$group_key]['#access'] = $form['metatags']['#access'];
+        $form['metatags'][$langcode][$group_key]['#access'] = $form['metatags']['#access'];
       }
       // Structure the access parameter into this array, and make use of it
       // later when we move on. Besides, this foreach is getting heavy.
-      $group_metatag_access[$group_key] = $form['metatags'][$group_key]['#access'];
+      $group_metatag_access[$group_key] = $form['metatags'][$langcode][$group_key]['#access'];
     }
     else {
-      $form['metatags'][$metatag] = $metatag_form;
+      $form['metatags'][$langcode][$metatag] = $metatag_form;
     }
   }
 
@@ -1194,7 +1205,7 @@ function metatag_metatags_form(array &$form, $instance, array $metatags = array(
   // fields visible; only bother checking this if the user had edit access in
   // the first place.
   if ($form['metatags']['#access'] && variable_get('metatag_extended_permissions', FALSE)) {
-    $form['metatags']['#access'] = count(element_get_visible_children($form['metatags'])) > 0;
+    $form['metatags']['#access'] = count(element_get_visible_children($form['metatags'][$langcode])) > 0;
   }
 
   // Check the #access of each group. If it passed, we display options for
@@ -1204,20 +1215,20 @@ function metatag_metatags_form(array &$form, $instance, array $metatags = array(
     $token_listing_link = theme('token_tree', array('token_types' => $options['token types'], 'dialog' => TRUE));
 
     // Add the token list to the top of the fieldset.
-    $form['metatags']['#description'] = $token_listing_link;
+    $form['metatags'][$langcode]['#description'] = $token_listing_link;
 
     // Check if each meta tag group is being displayed.
     if (!empty($group_metatag_access)) {
       foreach ($group_metatag_access as $group_key => $token_access) {
         if ($token_access) {
           // Update the description.
-          if (isset($form['metatags'][$group_key]['#description'])) {
-            $form['metatags'][$group_key]['#description'] .= '<br />';
+          if (isset($form['metatags'][$langcode][$group_key]['#description'])) {
+            $form['metatags'][$langcode][$group_key]['#description'] .= '<br />';
           }
           else {
-            $form['metatags'][$group_key]['#description'] = '';
+            $form['metatags'][$langcode][$group_key]['#description'] = '';
           }
-          $form['metatags'][$group_key]['#description'] .= $token_listing_link;
+          $form['metatags'][$langcode][$group_key]['#description'] .= $token_listing_link;
         }
       }
     }
@@ -1233,8 +1244,22 @@ function metatag_metatags_form(array &$form, $instance, array $metatags = array(
  * Form submit handler; unset meta tag values that equal their default values.
  */
 function metatag_metatags_form_submit($form, &$form_state) {
-  if (!empty($form_state['values']['metatags']) && !empty($form['metatags']['#metatag_defaults'])) {
-    metatag_filter_values_from_defaults($form_state['values']['metatags'], $form['metatags']['#metatag_defaults']);
+  // Work out the language to use, default to NONE.
+  $langcode = LANGUAGE_NONE;
+  if (isset($form['#entity_type'])) {
+    $entity_info = entity_get_info();
+    if (!empty($entity_info[$form['#entity_type']]['translation']['locale'])) {
+      // The language to use for this form.
+      $langcode = $GLOBALS['language_content']->language;
+    }
+  }
+
+  if (!empty($form_state['values']['metatags'])) {
+    foreach ($form_state['values']['metatags'] as $langcode => $values) {
+      if (!empty($form['metatags'][$langcode]['#metatag_defaults'])) {
+        metatag_filter_values_from_defaults($form_state['values']['metatags'][$langcode], $form['metatags'][$langcode]['#metatag_defaults']);
+      }
+    }
   }
 }
 
diff --git a/metatag_context/metatag_context.admin.inc b/metatag_context/metatag_context.admin.inc
index becb101..f57bafb 100644
--- a/metatag_context/metatag_context.admin.inc
+++ b/metatag_context/metatag_context.admin.inc
@@ -101,8 +101,13 @@ function metatag_context_config_edit_form($form, &$form_state, $context) {
   $instance = "";
   $options = array();
 
+  $metatags = $context->reactions['metatag_context_reaction']['metatags'];
+  if (isset($metatags[LANGUAGE_NONE])) {
+    $metatags = $metatags[LANGUAGE_NONE];
+  }
+
   // Load the METATAG form.
-  metatag_metatags_form($form, $instance, $context->reactions['metatag_context_reaction']['metatags'], $options);
+  metatag_metatags_form($form, $instance, $metatags, $options);
 
   $form['paths'] = array(
     '#title' => 'Path',
diff --git a/metatag_context/metatag_context.context.inc b/metatag_context/metatag_context.context.inc
index 4c270f7..c922a50 100644
--- a/metatag_context/metatag_context.context.inc
+++ b/metatag_context/metatag_context.context.inc
@@ -99,6 +99,9 @@ class metatag_context_reaction extends context_reaction {
       foreach ($contexts as $context) {
         if (!empty($context->reactions['metatag_context_reaction']['metatags'])) {
           $metadata_array = $context->reactions['metatag_context_reaction']['metatags'];
+          if (isset($metadata_array[LANGUAGE_NONE])) {
+            $metadata_array = $metadata_array[LANGUAGE_NONE];
+          }
           foreach ($metadata_array as $key => $data) {
             if (!empty($data['value'])) {
               $metatags[$key] = $data;//t(check_plain($data['value']));
diff --git a/metatag_context/metatag_context.test b/metatag_context/metatag_context.test
index a0036b9..e6fd746 100644
--- a/metatag_context/metatag_context.test
+++ b/metatag_context/metatag_context.test
@@ -112,10 +112,10 @@ class MetatagContextTestCase extends DrupalWebTestCase {
   function editMetatag($metatag_object) {
     $edit_metatag = array(
       'paths' => $metatag_object->path,
-      'metatags[title][value]' => $metatag_object->title,
-      'metatags[description][value]' => $metatag_object->description,
-      'metatags[abstract][value]' => $metatag_object->abstract,
-      'metatags[keywords][value]' => $metatag_object->keywords,
+      'metatags[und][title][value]' => $metatag_object->title,
+      'metatags[und][description][value]' => $metatag_object->description,
+      'metatags[und][abstract][value]' => $metatag_object->abstract,
+      'metatags[und][keywords][value]' => $metatag_object->keywords,
     );
     $this->drupalPost('admin/config/search/metatags/context/' . $metatag_object->name, $edit_metatag, t('Save'));
   }
