diff --git a/paragraphs.module b/paragraphs.module
index 7d73bfd..9c279c7 100644
--- a/paragraphs.module
+++ b/paragraphs.module
@@ -105,48 +105,6 @@ function paragraphs_form_field_storage_config_edit_form_alter(&$form, \Drupal\Co
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
- *
- * Indicate unsupported multilingual paragraphs field configuration.
- */
-function paragraphs_form_field_config_edit_form_alter(&$form,  \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
-  $field = $form_state->getFormObject()->getEntity();
-
-  if (!\Drupal::hasService('content_translation.manager')) {
-    return;
-  }
-
-  $bundle_is_translatable = \Drupal::service('content_translation.manager')
-    ->isEnabled($field->getTargetEntityTypeId(), $field->getTargetBundle());
-
-  if (!$bundle_is_translatable
-    || $field->getType() != 'entity_reference_revisions'
-    || $field->getSetting('target_type') != 'paragraph') {
-    return;
-  }
-
-  // This is a translatable ERR field pointing to a paragraph.
-  $message_display = 'warning';
-  $message_text = t('Paragraphs fields do not support translation. See the <a href=":documentation">online documentation</a>.', [
-    ':documentation' => Url::fromUri('https://www.drupal.org/node/2735121')
-      ->toString()
-  ]);
-
-  if ($form['translatable']['#default_value'] == TRUE) {
-    $message_display = 'error';
-  }
-
-  $form['paragraphs_message'] = array(
-    '#type' => 'container',
-    '#markup' => $message_text,
-    '#attributes' => array(
-      'class' => array('messages messages--' . $message_display),
-    ),
-    '#weight' => 0,
-  );
-}
-
-/**
  * Implements hook_module_implements_alter().
  *
  * Our paragraphs_form_field_config_edit_form_alter() needs to be run after
@@ -165,56 +123,6 @@ function paragraphs_module_implements_alter(&$implementations, $hook) {
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
- *
- * Indicate unsupported multilingual paragraphs field configuration.
- *
- * Add a warning that paragraph fields can not be translated.
- * Switch to error if a paragraph field is marked as translatable.
- */
-function paragraphs_form_language_content_settings_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
-  // Without it Paragraphs message are meaningless.
-  if (!\Drupal::hasService('content_translation.manager')) {
-    return;
-  }
-
-  $content_translation_manager = \Drupal::service('content_translation.manager');
-  $message_display = 'warning';
-  $message_text = t('(* unsupported) Paragraphs fields do not support translation. See the <a href=":documentation">online documentation</a>.', [
-    ':documentation' => Url::fromUri('https://www.drupal.org/node/2735121')
-      ->toString()]);
-  $map = \Drupal::service('entity_field.manager')->getFieldMapByFieldType('entity_reference_revisions');
-  foreach ($map as $entity_type_id => $info) {
-    if (!$content_translation_manager->isEnabled($entity_type_id)) {
-      continue;
-    }
-    $field_storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type_id);
-    foreach ($field_storage_definitions as $name => $data) {
-      if ($data->getSetting('target_type') && $data->getSetting('target_type') == 'paragraph') {
-        foreach($data->getBundles() as $bundle) {
-          if (!$content_translation_manager->isEnabled($entity_type_id, $bundle)) {
-            continue;
-          }
-          $form['settings'][$entity_type_id][$bundle]['fields'][$name]['#label'] .= ' (* unsupported)';
-          if ($form['settings'][$entity_type_id][$bundle]['fields'][$name]['#default_value']) {
-            $message_display = 'error';
-          }
-        }
-      }
-    }
-  }
-  $form['settings']['paragraphs_message'] = array(
-    '#type' => 'container',
-    '#markup' => $message_text,
-    '#attributes' => array(
-      'class' => array('messages messages--' . $message_display),
-    ),
-    '#weight' => 0,
-  );
-  return $form;
-}
-
-/**
  * Prepares variables for paragraph templates.
  *
  * Default template: paragraph.html.twig.
diff --git a/src/Plugin/Field/FieldWidget/InlineParagraphsWidget.php b/src/Plugin/Field/FieldWidget/InlineParagraphsWidget.php
index 0f756ef..758b6f2 100644
--- a/src/Plugin/Field/FieldWidget/InlineParagraphsWidget.php
+++ b/src/Plugin/Field/FieldWidget/InlineParagraphsWidget.php
@@ -4,6 +4,7 @@ namespace Drupal\paragraphs\Plugin\Field\FieldWidget;
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Component\Utility\Html;
+use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\RevisionableInterface;
@@ -14,9 +15,11 @@ use Drupal\Core\Field\WidgetBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Render\Element;
+use Drupal\field\Entity\FieldConfig;
 use Drupal\node\Entity\Node;
 use Drupal\paragraphs;
 use Drupal\paragraphs\ParagraphInterface;
+use Drupal\paragraphs\Entity\Paragraph;
 use Symfony\Component\Validator\ConstraintViolationInterface;
 
 
@@ -229,7 +232,6 @@ class InlineParagraphsWidget extends WidgetBase {
     $info = [];
 
     $paragraphs_entity = NULL;
-    $host = $items->getEntity();
     $widget_state = static::getWidgetState($parents, $field_name, $form_state);
 
     $entity_manager = \Drupal::entityTypeManager();
@@ -296,48 +298,7 @@ class InlineParagraphsWidget extends WidgetBase {
     }
 
     if ($paragraphs_entity) {
-      // Detect if we are translating.
-      $this->initIsTranslating($form_state, $host);
-      $langcode = $form_state->get('langcode');
-
-      if (!$this->isTranslating) {
-        // Set the langcode if we are not translating.
-        $langcode_key = $paragraphs_entity->getEntityType()->getKey('langcode');
-        if ($paragraphs_entity->get($langcode_key)->value != $langcode) {
-          // If a translation in the given language already exists, switch to
-          // that. If there is none yet, update the language.
-          if ($paragraphs_entity->hasTranslation($langcode)) {
-            $paragraphs_entity = $paragraphs_entity->getTranslation($langcode);
-          }
-          else {
-            $paragraphs_entity->set($langcode_key, $langcode);
-          }
-        }
-      }
-      else {
-        // Add translation if missing for the target language.
-        if (!$paragraphs_entity->hasTranslation($langcode)) {
-          // Get the selected translation of the paragraph entity.
-          $entity_langcode = $paragraphs_entity->language()->getId();
-          $source = $form_state->get(['content_translation', 'source']);
-          $source_langcode = $source ? $source->getId() : $entity_langcode;
-          $paragraphs_entity = $paragraphs_entity->getTranslation($source_langcode);
-          // The paragraphs entity has no content translation source field if
-          // no paragraph entity field is translatable, even if the host is.
-          if ($paragraphs_entity->hasField('content_translation_source')) {
-            // Initialise the translation with source language values.
-            $paragraphs_entity->addTranslation($langcode, $paragraphs_entity->toArray());
-            $translation = $paragraphs_entity->getTranslation($langcode);
-            $manager = \Drupal::service('content_translation.manager');
-            $manager->getTranslationMetadata($translation)->setSource($paragraphs_entity->language()->getId());
-          }
-        }
-        // If any paragraphs type is translatable do not switch.
-        if ($paragraphs_entity->hasField('content_translation_source')) {
-          // Switch the paragraph to the translation.
-          $paragraphs_entity = $paragraphs_entity->getTranslation($langcode);
-        }
-      }
+      $paragraphs_entity = $this->prepareEntity($paragraphs_entity, $items, $form_state);
 
       $element_parents = $parents;
       $element_parents[] = $field_name;
@@ -391,7 +352,8 @@ class InlineParagraphsWidget extends WidgetBase {
         $links = array();
 
         // Hide the button when translating.
-        $button_access = $paragraphs_entity->access('delete') && !$this->isTranslating;
+        $button_access = $paragraphs_entity->access('delete') && (!$this->isTranslating || $items->getFieldDefinition()
+              ->isTranslatable());
         if ($item_mode != 'remove') {
           $links['remove_button'] = [
             '#type' => 'submit',
@@ -901,7 +863,7 @@ class InlineParagraphsWidget extends WidgetBase {
     $host = $items->getEntity();
     $this->initIsTranslating($form_state, $host);
 
-    if (($this->realItemCount < $cardinality || $cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) && !$form_state->isProgrammed() && !$this->isTranslating) {
+    if (($this->realItemCount < $cardinality || $cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) && !$form_state->isProgrammed() && (!$this->isTranslating || $this->fieldDefinition->isTranslatable())) {
       $elements['add_more'] = $this->buildAddActions();
     }
 
@@ -1293,6 +1255,86 @@ class InlineParagraphsWidget extends WidgetBase {
   }
 
   /**
+   * Prepares the paragraph entity for translation.
+   *
+   * @param \Drupal\paragraphs\Entity\Paragraph $entity
+   *   The paragraph entity.
+   * @param \Drupal\Core\Field\FieldItemListInterface $items
+   *   The field items list that hosts this paragraph.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state.
+   *
+   * @return \Drupal\paragraphs\Entity\Paragraph
+   *   The prepared paragraph.
+   *
+   * @see \Drupal\Core\Entity\ContentEntityForm::initFormLangcodes().
+   */
+  protected function prepareEntity(Paragraph $entity, FieldItemListInterface $items, FormStateInterface $form_state) {
+    // Detect if we are translating.
+    $this->initIsTranslating($form_state, $items->getEntity());
+    $langcode = $form_state->get('langcode');
+
+    if (!$this->isTranslating) {
+      // Set the langcode if we are not translating.
+      $langcode_key = $entity->getEntityType()->getKey('langcode');
+      if ($entity->get($langcode_key)->value != $langcode) {
+        // If a translation in the given language already exists, switch to
+        // that. If there is none yet, update the language.
+        if ($entity->hasTranslation($langcode)) {
+          $entity = $entity->getTranslation($langcode);
+        }
+        else {
+          $entity->set($langcode_key, $langcode);
+        }
+      }
+    }
+
+    // Localised Paragraphs.
+    //  If the parent field is marked as translatable, assume paragraphs
+    //  to be localized (host entity expects different paragraphs for
+    //  different languages)
+    elseif ($items->getFieldDefinition()->isTranslatable()) {
+      if (!empty($form_state->get('content_translation'))) {
+        $entity = $this->cloneReferencedEntity($entity, $langcode);
+      }
+      $entity = $entity->getTranslation($langcode);
+    }
+
+    // Translated Paragraphs
+    //  If the parent field is not translatable, assume the paragraph
+    //  entity itself (rather the fields within it) are marked as
+    //  translatable. (host entity expects same paragraphs in different
+    //  languages).
+    else {
+      // Add translation if missing for the target language.
+      if (!$entity->hasTranslation($langcode)) {
+        // Get the selected translation of the paragraph entity.
+        $entity_langcode = $entity->language()->getId();
+        $source = $form_state->get(['content_translation', 'source']);
+        $source_langcode = $source ? $source->getId() : $entity_langcode;
+        $entity = $entity->getTranslation($source_langcode);
+        // The paragraphs entity has no content translation source field if
+        // no paragraph entity field is translatable, even if the host is.
+        if ($entity->hasField('content_translation_source')) {
+          // Initialise the translation with source language values.
+          $entity->addTranslation($langcode, $entity->toArray());
+          $translation = $entity->getTranslation($langcode);
+          $manager = \Drupal::service('content_translation.manager');
+          $manager->getTranslationMetadata($translation)
+            ->setSource($entity->language()->getId());
+        }
+      }
+      // If any paragraphs type is translatable do not switch.
+      if ($entity->hasField('content_translation_source')) {
+        // Switch the paragraph to the translation.
+        $entity = $entity->getTranslation($langcode);
+      }
+    }
+
+    return $entity;
+  }
+
+  /**
    * Initializes the translation form state.
    *
    * @param \Drupal\Core\Form\FormStateInterface $form_state
@@ -1325,6 +1367,64 @@ class InlineParagraphsWidget extends WidgetBase {
   }
 
   /**
+   * Clones Paragraphs (and field_collections) recursively, preparing them to be
+   * passed to the translated paragraph widget.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity_to_clone The Entity
+   * to clone
+   * @param string $langcode language code for all the clone entities created.
+   * @return \Drupal\Core\Entity\ContentEntityInterface New entity object which
+   * has the same data as the original $entity_to_clone, Note this entity is not
+   * saved.
+   */
+  protected function cloneReferencedEntity(ContentEntityInterface $entity_to_clone, $langcode) {
+    $entity_manager = \Drupal::entityTypeManager();
+    // Get the paragraph item as an array of values.
+    $paragraph_array = $entity_to_clone->toArray();
+    $target_type = $entity_to_clone->getEntityTypeId();
+    $entity_type = $entity_manager->getDefinition($target_type);
+    $bundle_key = $entity_type->getKey('bundle');
+
+    // Create a new entity for this language.
+    $new_entity = array(
+      $bundle_key => $entity_to_clone->bundle(),
+      'langcode' => $langcode
+    );
+
+    // Loop through all fields in the paragraph and add to new entity.
+    foreach ($entity_to_clone->getFieldDefinitions() as $field_name => $field_definition) {
+      // Check that the value is a field config and not empty.
+      if ($field_definition instanceof FieldConfig && !empty($paragraph_array[$field_name])) {
+        if ($this->checkEntityTypeCloneable($field_definition->getSetting('target_type'))) {
+          /** @var [EntityInterface] $entities */
+          $entities = $entity_to_clone->get($field_name)->referencedEntities();
+          $cloned_entites = [];
+          foreach ($entities as $entity) {
+            $cloned_entites[] = $this->cloneReferencedEntity($entity, $langcode);
+          }
+          $new_entity[$field_name] = $cloned_entites;
+        }
+        else {
+          $new_entity[$field_name] = $paragraph_array[$field_name];
+        }
+      }
+    }
+    return $entity_manager->getStorage($target_type)->create($new_entity);
+  }
+
+  /**
+   * Checks whether we support cloning a certain entity type or not.
+   *
+   * @param string $entity_type_id the entity type ID to check whether it's cloneable
+   * @return bool
+   */
+  protected function checkEntityTypeCloneable($entity_type_id) {
+    // @todo: maybe this list should be moved to widget configs with some sensible
+    // default?
+    return in_array($entity_type_id, ['field_collection_item', 'paragraph']);
+  }
+
+  /**
    * After-build callback for removing the translatability clue from the widget.
    *
    * If the fields on the paragraph type are translatable,
diff --git a/src/Tests/Classic/ParagraphsAsymmetricTranslationTest.php b/src/Tests/Classic/ParagraphsAsymmetricTranslationTest.php
new file mode 100644
index 0000000..38aff2a
--- /dev/null
+++ b/src/Tests/Classic/ParagraphsAsymmetricTranslationTest.php
@@ -0,0 +1,522 @@
+<?php
+
+namespace Drupal\paragraphs\Tests\Classic;
+
+
+/**
+ * Tests asymmetric translation of paragraphs.
+ *
+ * @group paragraphs
+ */
+class ParagraphsAsymmetricTranslationTest extends ParagraphsTestBase {
+
+  public static $modules = [
+    'node',
+    'paragraphs_demo',
+    'content_translation',
+    'block',
+  ];
+
+  /**
+   * A user with admin permissions.
+   *
+   * @var \Drupal\user\UserInterface $entity
+   */
+  protected $admin_user;
+
+  protected function setUp() {
+    parent::setUp();
+    $this->drupalPlaceBlock('local_tasks_block');
+    $this->drupalPlaceBlock('page_title_block');
+
+    $this->admin_user = $this->drupalCreateUser(
+      [
+        'administer site configuration',
+        'administer nodes',
+        'create paragraphed_content_demo content',
+        'edit any paragraphed_content_demo content',
+        'delete any paragraphed_content_demo content',
+        'administer paragraph form display',
+        'administer node form display',
+        'administer paragraph fields',
+        'administer content translation',
+        'translate any entity',
+        'create content translations',
+        'administer languages',
+        'administer content types',
+      ]
+    );
+
+    $this->drupalLogin($this->admin_user);
+
+    // Mark the paragraph entities as untranslatable and the paragraph field
+    // as translatable.
+    $edit = [
+      'entity_types[paragraph]' => TRUE,
+      'settings[node][paragraphed_content_demo][fields][field_paragraphs_demo]' => TRUE,
+//      'settings[paragraph][images][translatable]' => FALSE,
+//      'settings[paragraph][images][settings][language][language_alterable]' => FALSE,
+//      'settings[paragraph][image_text][translatable]' => FALSE,
+//      'settings[paragraph][image_text][settings][language][language_alterable]' => FALSE,
+      'settings[paragraph][nested_paragraph][translatable]' => TRUE,
+      'settings[paragraph][nested_paragraph][settings][language][language_alterable]' => FALSE,
+      'settings[paragraph][text][translatable]' => TRUE,
+      'settings[paragraph][text][settings][language][language_alterable]' => FALSE,
+
+      'settings[paragraph][nested_paragraph][fields][field_paragraphs_demo]' => TRUE,
+
+
+//      'settings[paragraph][text_image][translatable]' => FALSE,
+//      'settings[paragraph][text_image][settings][language][language_alterable]' => FALSE,
+//      'settings[paragraph][user][translatable]' => FALSE,
+//      'settings[paragraph][user][settings][language][language_alterable]' => FALSE,
+    ];
+    $this->drupalPostForm(
+      'admin/config/regional/content-language',
+      $edit,
+      t('Save configuration')
+    );
+  }
+
+  /**
+   * Test asymmetric translation.
+   *
+   * 1. Translate node and create different paragraphs.
+   * 2. Update the paragraphs on each translation.
+   * 3. Add different number of paragraphs on each translation.
+   * 4. Remove paragraphs from each translation.
+   * 5. Reorder the paragraphs on each translation.
+   */
+  public function testParagraphsMultilingualFieldTranslation() {
+    // Edit widget to classic.
+    $this->drupalGet('/admin/structure/types/manage/paragraphed_content_demo/form-display');
+    $this->drupalPostForm(NULL, array('fields[field_paragraphs_demo][type]' => 'entity_reference_paragraphs'), t('Save'));
+
+    // 1. Translate node and create different paragraphs.
+
+    // Add an English node.
+    $this->drupalGet('node/add/paragraphed_content_demo');
+    $this->drupalPostForm(NULL, NULL, t('Add Text'));
+
+    $edit = [
+      'title[0][value]' => 'Title in english',
+      'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'Text in english',
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+
+    // Translate the node to French.
+    $node = $this->drupalGetNodeByTitle('Title in english');
+    $this->drupalGet('node/' . $node->id() . '/translations/add/en/fr');
+
+    $edit = [
+      'title[0][value]' => 'Title in french',
+      'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'Text in french',
+      'revision' => TRUE,
+      'revision_log[0][value]' => 'french 1',
+    ];
+    $this->drupalPostForm(
+      NULL,
+      $edit,
+      t('Save and keep published (this translation)')
+    );
+
+    // Check the english translation.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('Title in english');
+    $this->assertText('Text in english');
+    $this->assertNoText('Title in french');
+    $this->assertNoText('Text in french');
+
+    // Check the french translation.
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('Title in french');
+    $this->assertText('Text in french');
+    $this->assertNoText('Title in english');
+    $this->assertNoText('Text in english');
+
+    // Check the db
+    $select = \Drupal::database()->select('node__field_paragraphs_demo', 'n');
+    $select->innerJoin('paragraphs_item', 'p', 'p.id = n.field_paragraphs_demo_target_id');
+    $select->addField('p', 'langcode');
+    $select->condition('n.entity_id', $node->id());
+    $paragraph_langcodes = $select->execute()->fetchCol();
+
+    $this->assertEqual(
+      $paragraph_langcodes,
+      ['en', 'fr'],
+      'Translated paragraphs are separate entities'
+    );
+
+    // 2. Update the paragraphs on each translation.
+
+    // Try to edit the paragraphs, to see if the correct translation gets
+    // updated. Start with the english.
+    $this->drupalGet('node/' . $node->id() . '/edit');
+    $edit = [
+      'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'The updated english text',
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+    // Check if only the english node had its paragraph text updated, and that
+    // there has been no mixing-up of the paragraph entities.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('The updated english text');
+    $this->assertNoText('Text in english');
+    $this->assertNoText('Text in french');
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('Text in french');
+    $this->assertNoText('Text in english');
+    $this->assertNoText('The updated english text');
+
+    // Now repeat for the french.
+    $this->drupalGet('fr/node/' . $node->id() . '/edit');
+    $edit = [
+      'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'The updated french text',
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+    // Check if only the french node had its paragraph text updated, and that
+    // there has been no mixing-up of the paragraph entities.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('The updated english text');
+    $this->assertNoText('Text in french');
+    $this->assertNoText('The updated french text');
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('The updated french text');
+    $this->assertNoText('Text in french');
+    $this->assertNoText('The updated english text');
+
+
+    // 3. Add different number of paragraphs on each translation.
+
+    // Add 2 more paragraphs on the english node.
+    $this->drupalGet('node/' . $node->id() . '/edit');
+    $this->drupalPostForm(NULL, NULL, t('Add Text'));
+    $this->drupalPostForm(NULL, NULL, t('Add Text'));
+    $edit = [
+      'field_paragraphs_demo[1][subform][field_text_demo][0][value]' => 'Second text in english',
+      'field_paragraphs_demo[2][subform][field_text_demo][0][value]' => 'Third text in english',
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+
+    // Confirm that the english node has the new paragraphs, and the french
+    // node is intact.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('The updated english text');
+    $this->assertText('Second text in english');
+    $this->assertText('Third text in english');
+    $this->assertNoText('The updated french text');
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('The updated french text');
+    $this->assertNoText('The updated english text');
+    $this->assertNoText('Second text in english');
+    $this->assertNoText('Third text in english');
+
+    // Repeat the same, this time adding 3 new paragraphs on the french node.
+    $this->drupalGet('fr/node/' . $node->id() . '/edit');
+    $this->drupalPostForm(NULL, NULL, t('Add Text'));
+    $this->drupalPostForm(NULL, NULL, t('Add Text'));
+    $this->drupalPostForm(NULL, NULL, t('Add Text'));
+    $edit = [
+      'field_paragraphs_demo[1][subform][field_text_demo][0][value]' => 'Second text in french',
+      'field_paragraphs_demo[2][subform][field_text_demo][0][value]' => 'Third text in french',
+      'field_paragraphs_demo[3][subform][field_text_demo][0][value]' => 'Fourth text in french',
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+
+    // Confirm that the french node has the new paragraphs, and the english
+    // node is intact.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('The updated english text');
+    $this->assertText('Second text in english');
+    $this->assertText('Third text in english');
+    $this->assertNoText('The updated french text');
+    $this->assertNoText('Second text in french');
+    $this->assertNoText('Third text in french');
+    $this->assertNoText('Fourth text in french');
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('The updated french text');
+    $this->assertText('Second text in french');
+    $this->assertText('Third text in french');
+    $this->assertText('Fourth text in french');
+    $this->assertNoText('The updated english text');
+    $this->assertNoText('Second text in english');
+    $this->assertNoText('Third text in english');
+
+
+
+    // 4. Remove paragraphs from each translation.
+
+    // Delete one of the paragraphs on the english node, and confirm that the
+    // rest are intact, and also that the french node is intact.
+    $this->drupalGet('node/' . $node->id() . '/edit');
+
+    $this->assertNotNull($this->xpath('//*[@name="field_paragraphs_demo_1_remove"]'));
+    $this->drupalPostAjaxForm(NULL, [], 'field_paragraphs_demo_1_remove');
+    $this->assertNotNull($this->xpath('//*[@name="field_paragraphs_demo_1_confirm_remove"]'));
+    $this->drupalPostAjaxForm(NULL, [], 'field_paragraphs_demo_1_confirm_remove');
+    $this->drupalPostForm(NULL, NULL, t('Save and keep published (this translation)'));
+
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('The updated english text');
+    $this->assertNoText('Second text in english'); // The deleted paragraph
+    $this->assertText('Third text in english');
+    $this->assertNoText('The updated french text');
+    $this->assertNoText('Second text in french');
+    $this->assertNoText('Third text in french');
+    $this->assertNoText('Fourth text in french');
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertNoText('The updated english text');
+    $this->assertNoText('Second text in english');
+    $this->assertNoText('Third text in english');
+    $this->assertText('The updated french text');
+    $this->assertText('Second text in french');
+    $this->assertText('Third text in french');
+    $this->assertText('Fourth text in french');
+
+    // Repeat the same for the french node, deleting 2 paragraphs now.
+    $this->drupalGet('fr/node/' . $node->id() . '/edit');
+
+    $this->assertNotNull($this->xpath('//*[@name="field_paragraphs_demo_1_remove"]'));
+    $this->drupalPostAjaxForm(NULL, [], 'field_paragraphs_demo_1_remove');
+    $this->assertNotNull($this->xpath('//*[@name="field_paragraphs_demo_1_confirm_remove"]'));
+    $this->drupalPostAjaxForm(NULL, [], 'field_paragraphs_demo_1_confirm_remove');
+    $this->assertNotNull($this->xpath('//*[@name="field_paragraphs_demo_3_remove"]'));
+    $this->drupalPostAjaxForm(NULL, [], 'field_paragraphs_demo_3_remove');
+    $this->assertNotNull($this->xpath('//*[@name="field_paragraphs_demo_3_confirm_remove"]'));
+    $this->drupalPostAjaxForm(NULL, [], 'field_paragraphs_demo_3_confirm_remove');
+    $this->drupalPostForm(NULL, NULL, t('Save and keep published (this translation)'));
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertNoText('The updated english text');
+    $this->assertNoText('Second text in english');
+    $this->assertNoText('Third text in english');
+    $this->assertText('The updated french text');
+    $this->assertNoText('Second text in french'); // The deleted paragraph
+    $this->assertText('Third text in french');
+    $this->assertNoText('Fourth text in french'); // The other deleted paragraph
+
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('The updated english text');
+    $this->assertNoText('Second text in english'); // The previously deleted paragraph
+    $this->assertText('Third text in english');
+    $this->assertNoText('The updated french text');
+    $this->assertNoText('Second text in french');
+    $this->assertNoText('Third text in french');
+    $this->assertNoText('Fourth text in french');
+
+
+    // 5. Reorder the paragraphs on each translation.
+
+    // Reminder: This is our current content
+    //
+    // - English node
+    // -- The updated english text
+    // -- Third text in english
+    //
+    // - French node
+    // -- The updated french text
+    // -- Third text in french
+
+
+    // First check the english node, that "The updated english text" is indeed
+    // before the "Third text in english", as it has been set on the previous
+    // steps.
+    $this->drupalGet('node/' . $node->id());
+    $regex = '/The updated english text.*Third text in english/s';
+    $this->assertPattern($regex);
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $regex = '/The updated french text.*Third text in french/s';
+    $this->assertPattern($regex);
+
+    // Reorder the paragraphs in the english node, and check if it applied
+    // correctly. Check also that the french node is intact.
+    $this->drupalGet('node/' . $node->id() . '/edit');
+    $edit = [
+      'field_paragraphs_demo[0][_weight]' => 2,
+      'field_paragraphs_demo[1][_weight]' => -2,
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+
+    $this->drupalGet('node/' . $node->id());
+    $regex = '/Third text in english.*The updated english text/s';
+    $this->assertPattern($regex);
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $regex = '/The updated french text.*Third text in french/s';
+    $this->assertPattern($regex);
+
+    // And now reorder the french node, and then confirm that the new order
+    // applied correctly, and that the english node is intact.
+    $this->drupalGet('fr/node/' . $node->id() . '/edit');
+    $edit = [
+      'field_paragraphs_demo[0][_weight]' => 2,
+      'field_paragraphs_demo[1][_weight]' => -2,
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $regex = '/Third text in french.*The updated french text/s';
+    $this->assertPattern($regex);
+
+    $this->drupalGet('node/' . $node->id());
+    $regex = '/Third text in english.*The updated english text/s';
+    $this->assertPattern($regex);
+  }
+
+  public function testParagraphsMultilingualFieldTranslationNested() {
+    // Edit widget to classic.
+    $this->drupalGet('/admin/structure/types/manage/paragraphed_content_demo/form-display');
+    $this->drupalPostForm(NULL, array('fields[field_paragraphs_demo][type]' => 'entity_reference_paragraphs'), t('Save'));
+
+    // 1. Translate node and create different paragraphs.
+
+    // Add an English node.
+    $this->drupalGet('node/add/paragraphed_content_demo');
+    $this->drupalPostForm(NULL, NULL, t('Add Nested Paragraph'), array(), array(), ''); // Add a "nested paragraph"
+    $this->drupalPostAjaxForm(NULL, NULL, 'field_paragraphs_demo_0_subform_field_paragraphs_demo_text_add_more'); // Add a "text paragraph" within the nested
+    $edit = [
+      'title[0][value]' => 'Title in english',
+      'field_paragraphs_demo[0][subform][field_paragraphs_demo][0][subform][field_text_demo][0][value]' => 'Text in english',
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+
+    // Translate the node to French.
+    $node = $this->drupalGetNodeByTitle('Title in english');
+    $this->drupalGet('node/' . $node->id() . '/translations/add/en/fr');
+
+    $edit = [
+      'title[0][value]' => 'Title in french',
+      'field_paragraphs_demo[0][subform][field_paragraphs_demo][0][subform][field_text_demo][0][value]' => 'Text in french',
+    ];
+    $this->drupalPostForm(
+      NULL,
+      $edit,
+      t('Save and keep published (this translation)')
+    );
+
+    // Check the english translation.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('Title in english');
+    $this->assertText('Text in english');
+    $this->assertNoText('Title in french');
+    $this->assertNoText('Text in french');
+
+    // Check the french translation.
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('Title in french');
+    $this->assertText('Text in french');
+    $this->assertNoText('Title in english');
+    $this->assertNoText('Text in english');
+
+
+    // 2. Update the paragraphs.
+
+    // Try to edit the paragraphs, to see if the correct translation gets
+    // updated. Start with the english.
+    $this->drupalGet('node/' . $node->id() . '/edit');
+    $edit = [
+      'field_paragraphs_demo[0][subform][field_paragraphs_demo][0][subform][field_text_demo][0][value]' => 'The updated english text',
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+    // Check if only the english node had its paragraph text updated, and that
+    // there has been no mixing-up of the paragraph entities.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('The updated english text');
+    $this->assertNoText('Text in english');
+    $this->assertNoText('Text in french');
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('Text in french');
+    $this->assertNoText('Text in english');
+    $this->assertNoText('The updated english text');
+
+    // 3. Add different number of paragraphs on one translation.
+
+    // Add one more paragraph on the english node.
+    $this->drupalGet('node/' . $node->id() . '/edit');
+    $this->drupalPostAjaxForm(NULL, NULL, 'field_paragraphs_demo_0_subform_field_paragraphs_demo_text_add_more'); // Add one more "text paragraph" within the nested
+    $edit = [
+      'field_paragraphs_demo[0][subform][field_paragraphs_demo][1][subform][field_text_demo][0][value]' => 'New english text',
+    ];
+    $this->drupalPostForm(
+      NULL,
+      $edit,
+      t('Save and keep published (this translation)')
+    );
+
+    // Confirm that the english node has the new paragraphs, and the french
+    // node is intact.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('The updated english text');
+    $this->assertText('New english text');
+    $this->assertNoText('Text in french');
+
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('Text in french');
+    $this->assertNoText('The updated english text');
+    $this->assertNoText('New english text');
+  }
+
+  public function testParagraphsMultilingualFieldDeleteTranslation() {
+    // Edit widget to classic.
+    $this->drupalGet('/admin/structure/types/manage/paragraphed_content_demo/form-display');
+    $this->drupalPostForm(NULL, array('fields[field_paragraphs_demo][type]' => 'entity_reference_paragraphs'), t('Save'));
+
+    // 1. Translate node and create different paragraphs. Delete the translation
+    // and check if the original is intact.
+
+    // Add an English node.
+    $this->drupalGet('node/add/paragraphed_content_demo');
+    $this->drupalPostForm(NULL, NULL, t('Add Nested Paragraph'), array(), array(), ''); // Add a "nested paragraph"
+    $this->drupalPostAjaxForm(NULL, NULL, 'field_paragraphs_demo_0_subform_field_paragraphs_demo_text_add_more'); // Add a "text paragraph" within the nested
+    $edit = [
+      'title[0][value]' => 'Title in english',
+      'field_paragraphs_demo[0][subform][field_paragraphs_demo][0][subform][field_text_demo][0][value]' => 'Text in english',
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+
+    // Translate the node to French.
+    $node = $this->drupalGetNodeByTitle('Title in english');
+    $this->drupalGet('node/' . $node->id() . '/translations/add/en/fr');
+
+    $edit = [
+      'title[0][value]' => 'Title in french',
+      'field_paragraphs_demo[0][subform][field_paragraphs_demo][0][subform][field_text_demo][0][value]' => 'Text in french',
+    ];
+    $this->drupalPostForm(
+      NULL,
+      $edit,
+      t('Save and keep published (this translation)')
+    );
+
+    // Check the english translation.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('Title in english');
+    $this->assertText('Text in english');
+    $this->assertNoText('Title in french');
+    $this->assertNoText('Text in french');
+
+    // Check the french translation.
+    $this->drupalGet('fr/node/' . $node->id());
+    $this->assertText('Title in french');
+    $this->assertText('Text in french');
+    $this->assertNoText('Title in english');
+    $this->assertNoText('Text in english');
+
+    // Now delete the french translation.
+    $this->drupalGet('fr/node/' . $node->id() . '/delete');
+    $this->drupalPostForm(NULL, NULL, t('Delete French translation'));
+
+    // Check the english translation.
+    $this->drupalGet('node/' . $node->id());
+    $this->assertText('Title in english');
+    $this->assertText('Text in english');
+    $this->assertNoText('Title in french');
+    $this->assertNoText('Text in french');
+  }
+}
diff --git a/src/Tests/Classic/ParagraphsConfigTest.php b/src/Tests/Classic/ParagraphsConfigTest.php
index 8d2d79c..f94a09a 100644
--- a/src/Tests/Classic/ParagraphsConfigTest.php
+++ b/src/Tests/Classic/ParagraphsConfigTest.php
@@ -64,74 +64,6 @@ class ParagraphsConfigTest extends ParagraphsTestBase {
   }
 
   /**
-   * Tests content translation form translatability constraints messages.
-   */
-  public function testContentTranslationForm() {
-    $this->loginAsAdmin([
-      'administer languages',
-      'administer content translation',
-      'create content translations',
-      'translate any entity',
-    ]);
-
-    // Check warning message is displayed.
-    $this->drupalGet('admin/config/regional/content-language');
-    $this->assertText('(* unsupported) Paragraphs fields do not support translation.');
-
-    $this->addParagraphedContentType('paragraphed_test', 'paragraphs_field');
-
-    // Check error message is not displayed.
-    $this->drupalGet('admin/config/regional/content-language');
-    $this->assertText('(* unsupported) Paragraphs fields do not support translation.');
-    $this->assertNoRaw('<div class="messages messages--error');
-
-    // Add a second language.
-    ConfigurableLanguage::create(['id' => 'de'])->save();
-
-    // Enable translation for paragraphed content type.
-    $edit = [
-      'entity_types[node]' => TRUE,
-      'settings[node][paragraphed_test][translatable]' => TRUE,
-      'settings[node][paragraphed_test][fields][paragraphs_field]' => FALSE,
-    ];
-    $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
-
-    // Check error message is still not displayed.
-    $this->drupalGet('admin/config/regional/content-language');
-    $this->assertText('(* unsupported) Paragraphs fields do not support translation.');
-    $this->assertNoRaw('<div class="messages messages--error');
-
-    // Check content type field management warning.
-    $this->drupalGet('admin/structure/types/manage/paragraphed_test/fields/node.paragraphed_test.paragraphs_field');
-    $this->assertText('Paragraphs fields do not support translation.');
-
-    // Make the paragraphs field translatable.
-    $edit = [
-      'entity_types[node]' => TRUE,
-      'settings[node][paragraphed_test][translatable]' => TRUE,
-      'settings[node][paragraphed_test][fields][paragraphs_field]' => TRUE,
-    ];
-    $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
-
-    // Check content type field management error.
-    $this->drupalGet('admin/structure/types/manage/paragraphed_test/fields/node.paragraphed_test.paragraphs_field');
-    $this->assertText('Paragraphs fields do not support translation.');
-    $this->assertRaw('<div class="messages messages--error');
-
-    // Check a not paragraphs translatable field does not display the message.
-    $this->drupalGet('admin/structure/types/manage/paragraphed_test/fields/add-field');
-    $edit = [
-      'new_storage_type' => 'field_ui:entity_reference:node',
-      'label' => 'new_no_paragraphs_field',
-      'field_name' => 'new_no_paragraphs_field',
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Save and continue'));
-    $this->drupalPostForm(NULL, [], t('Save field settings'));
-    $this->assertNoText('Paragraphs fields do not support translation.');
-    $this->assertNoRaw('<div class="messages messages--warning');
-  }
-
-  /**
    * Tests required Paragraphs field.
    */
   public function testRequiredParagraphsField() {
@@ -163,31 +95,4 @@ class ParagraphsConfigTest extends ParagraphsTestBase {
     $this->assertText('paragraphed_test test_title has been created.');
   }
 
-  /**
-   * Tests that we can use paragraphs widget only for paragraphs.
-   */
-  public function testAvoidUsingParagraphsWithWrongEntity() {
-    $node_type = NodeType::create([
-      'type' => 'article',
-      'name' => 'article',
-    ]);
-    $node_type->save();
-    $this->loginAsAdmin([
-      'edit any article content',
-    ]);
-    $this->addParagraphsType('paragraphed_type');
-
-    // Create reference to node.
-    $this->fieldUIAddNewField('admin/structure/types/manage/article', 'node_reference', 'NodeReference', 'entity_reference_revisions', [
-      'cardinality' => 'number',
-      'cardinality_number' => 1,
-      'settings[target_type]' => 'node',
-    ], [
-      'settings[handler_settings][target_bundles][article]' => 'article',
-    ]);
-    $this->drupalGet('admin/structure/types/manage/article/form-display');
-    $this->assertNoOption('edit-fields-field-node-reference-type', 'entity_reference_paragraphs');
-    $this->assertNoOption('edit-fields-field-node-reference-type', 'paragraphs');
-  }
-
 }
diff --git a/src/Tests/Experimental/ParagraphsExperimentalConfigTest.php b/src/Tests/Experimental/ParagraphsExperimentalConfigTest.php
index 6e99405..dee0cd7 100644
--- a/src/Tests/Experimental/ParagraphsExperimentalConfigTest.php
+++ b/src/Tests/Experimental/ParagraphsExperimentalConfigTest.php
@@ -64,98 +64,4 @@ class ParagraphsExperimentalConfigTest extends ParagraphsExperimentalTestBase {
     $this->assertText('paragraphed_test paragraphed_title has been updated.');
   }
 
-  /**
-   * Tests content translation form translatability constraints messages.
-   */
-  public function testContentTranslationForm() {
-    $this->loginAsAdmin([
-      'administer languages',
-      'administer content translation',
-      'create content translations',
-      'translate any entity',
-    ]);
-
-    // Check warning message is displayed.
-    $this->drupalGet('admin/config/regional/content-language');
-    $this->assertText('(* unsupported) Paragraphs fields do not support translation.');
-
-    $this->addParagraphedContentType('paragraphed_test', 'paragraphs_field');
-    // Check error message is not displayed.
-    $this->drupalGet('admin/config/regional/content-language');
-    $this->assertText('(* unsupported) Paragraphs fields do not support translation.');
-    $this->assertNoRaw('<div class="messages messages--error');
-
-    // Add a second language.
-    ConfigurableLanguage::create(['id' => 'de'])->save();
-
-    // Enable translation for paragraphed content type.
-    $edit = [
-      'entity_types[node]' => TRUE,
-      'settings[node][paragraphed_test][translatable]' => TRUE,
-      'settings[node][paragraphed_test][fields][paragraphs_field]' => FALSE,
-    ];
-    $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
-
-    // Check error message is still not displayed.
-    $this->drupalGet('admin/config/regional/content-language');
-    $this->assertText('(* unsupported) Paragraphs fields do not support translation.');
-    $this->assertNoRaw('<div class="messages messages--error');
-
-    // Check content type field management warning.
-    $this->drupalGet('admin/structure/types/manage/paragraphed_test/fields/node.paragraphed_test.paragraphs_field');
-    $this->assertText('Paragraphs fields do not support translation.');
-
-    // Make the paragraphs field translatable.
-    $edit = [
-      'entity_types[node]' => TRUE,
-      'settings[node][paragraphed_test][translatable]' => TRUE,
-      'settings[node][paragraphed_test][fields][paragraphs_field]' => TRUE,
-    ];
-    $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
-
-    // Check content type field management error.
-    $this->drupalGet('admin/structure/types/manage/paragraphed_test/fields/node.paragraphed_test.paragraphs_field');
-    $this->assertText('Paragraphs fields do not support translation.');
-    $this->assertRaw('<div class="messages messages--error');
-
-    // Check a not paragraphs translatable field does not display the message.
-    $this->drupalGet('admin/structure/types/manage/paragraphed_test/fields/add-field');
-    $edit = [
-      'new_storage_type' => 'field_ui:entity_reference:node',
-      'label' => 'new_no_paragraphs_field',
-      'field_name' => 'new_no_paragraphs_field',
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Save and continue'));
-    $this->drupalPostForm(NULL, [], t('Save field settings'));
-    $this->assertNoText('Paragraphs fields do not support translation.');
-    $this->assertNoRaw('<div class="messages messages--warning');
-  }
-
-  /**
-   * Tests that we can use paragraphs widget only for paragraphs.
-   */
-  public function testAvoidUsingParagraphsWithWrongEntity() {
-    $node_type = NodeType::create([
-      'type' => 'article',
-      'name' => 'article',
-    ]);
-    $node_type->save();
-    $this->loginAsAdmin([
-      'edit any article content',
-    ]);
-    $this->addParagraphsType('paragraphed_type');
-
-    // Create reference to node.
-    $this->fieldUIAddNewField('admin/structure/types/manage/article', 'node_reference', 'NodeReference', 'entity_reference_revisions', [
-      'cardinality' => 'number',
-      'cardinality_number' => 1,
-      'settings[target_type]' => 'node',
-    ], [
-      'settings[handler_settings][target_bundles][article]' => 'article',
-    ]);
-    $this->drupalGet('admin/structure/types/manage/article/form-display');
-    $this->assertNoOption('edit-fields-field-node-reference-type', 'entity_reference_paragraphs');
-    $this->assertNoOption('edit-fields-field-node-reference-type', 'paragraphs');
-  }
-
 }
