diff --git a/entity_clone.info.yml b/entity_clone.info.yml
index cafcab7..b624edd 100644
--- a/entity_clone.info.yml
+++ b/entity_clone.info.yml
@@ -2,3 +2,4 @@ name: Entity Clone
 description: Add a clone action for all entities
 core:  "8.x"
 type: module
+configure: entity_clone.settings
diff --git a/entity_clone.links.menu.yml b/entity_clone.links.menu.yml
new file mode 100644
index 0000000..f013a12
--- /dev/null
+++ b/entity_clone.links.menu.yml
@@ -0,0 +1,5 @@
+entity_clone.settings:
+  title: 'Entity clone settings'
+  description: 'Entity clone settings.'
+  route_name: entity_clone.settings
+  parent: 'system.admin_config_content'
diff --git a/entity_clone.links.task.yml b/entity_clone.links.task.yml
index dbb40ee..427f575 100644
--- a/entity_clone.links.task.yml
+++ b/entity_clone.links.task.yml
@@ -1,3 +1,8 @@
 entity_clone.clone:
   deriver: 'Drupal\entity_clone\Plugin\Derivative\DynamicLocalTasks'
-  weight: 100
\ No newline at end of file
+  weight: 100
+entity_clone.settings:
+  title: 'Entity clone settings'
+  route_name: entity_clone.settings
+  base_route: entity_clone.settings
+  weight: 0
diff --git a/entity_clone.module b/entity_clone.module
index 81faab0..eb699cb 100644
--- a/entity_clone.module
+++ b/entity_clone.module
@@ -9,6 +9,15 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
+use Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneBase;
+use Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneFormBase;
+use Drupal\entity_clone\EntityClone\Config\ConfigWithFieldEntityClone;
+use Drupal\entity_clone\EntityClone\Config\FieldConfigEntityClone;
+use Drupal\entity_clone\EntityClone\Content\ContentEntityCloneBase;
+use Drupal\entity_clone\EntityClone\Content\ContentEntityCloneFormBase;
+use Drupal\entity_clone\EntityClone\Content\FileEntityClone;
+use Drupal\entity_clone\EntityClone\Content\TaxonomyTermEntityClone;
+use Drupal\entity_clone\EntityClone\Content\UserEntityClone;
 
 /**
  * Implements hook_help().
@@ -29,35 +38,41 @@ function entity_clone_help($route_name, RouteMatchInterface $route_match) {
 }
 
 /**
- * Implements hook_entity_info_alter().
+ * Implements hook_entity_type_build().
  */
 function entity_clone_entity_type_build(array &$entity_types) {
   $specific_handler = [
     'file' => [
-      'entity_clone' => '\Drupal\entity_clone\EntityClone\Content\FileEntityClone',
+      'entity_clone' => FileEntityClone::class,
+      'entity_clone_form' => ContentEntityCloneFormBase::class,
     ],
     'user' => [
-      'entity_clone' => '\Drupal\entity_clone\EntityClone\Content\UserEntityClone',
+      'entity_clone' => UserEntityClone::class,
+      'entity_clone_form' => ContentEntityCloneFormBase::class,
     ],
     'field_config' => [
-      'entity_clone' => '\Drupal\entity_clone\EntityClone\Config\FieldConfigEntityClone',
-      'entity_clone_form' => '\Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneFormBase',
+      'entity_clone' => FieldConfigEntityClone::class,
+      'entity_clone_form' => ConfigEntityCloneFormBase::class,
     ],
     'node_type' => [
-      'entity_clone' => '\Drupal\entity_clone\EntityClone\Config\ConfigWithFieldEntityClone',
-      'entity_clone_form' => '\Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneFormBase',
+      'entity_clone' => ConfigWithFieldEntityClone::class,
+      'entity_clone_form' => ConfigEntityCloneFormBase::class,
     ],
     'comment_type' => [
-      'entity_clone' => '\Drupal\entity_clone\EntityClone\Config\ConfigWithFieldEntityClone',
-      'entity_clone_form' => '\Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneFormBase',
+      'entity_clone' => ConfigWithFieldEntityClone::class,
+      'entity_clone_form' => ConfigEntityCloneFormBase::class,
     ],
     'block_content_type' => [
-      'entity_clone' => '\Drupal\entity_clone\EntityClone\Config\ConfigWithFieldEntityClone',
-      'entity_clone_form' => '\Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneFormBase',
+      'entity_clone' => ConfigWithFieldEntityClone::class,
+      'entity_clone_form' => ConfigEntityCloneFormBase::class,
     ],
     'contact_form' => [
-      'entity_clone' => '\Drupal\entity_clone\EntityClone\Config\ConfigWithFieldEntityClone',
-      'entity_clone_form' => '\Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneFormBase',
+      'entity_clone' => ConfigWithFieldEntityClone::class,
+      'entity_clone_form' => ConfigEntityCloneFormBase::class,
+    ],
+    'taxonomy_term' => [
+      'entity_clone' => TaxonomyTermEntityClone::class,
+      'entity_clone_form' => ContentEntityCloneFormBase::class,
     ],
   ];
 
@@ -70,11 +85,12 @@ function entity_clone_entity_type_build(array &$entity_types) {
       }
     }
     elseif (!$entity_type->getHandlerClass('entity_clone') && $entity_type instanceof ContentEntityTypeInterface) {
-      $entity_type->setHandlerClass('entity_clone', '\Drupal\entity_clone\EntityClone\Content\ContentEntityCloneBase');
+      $entity_type->setHandlerClass('entity_clone', ContentEntityCloneBase::class);
+      $entity_type->setHandlerClass('entity_clone_form', ContentEntityCloneFormBase::class);
     }
     elseif (!$entity_type->getHandlerClass('entity_clone') && $entity_type instanceof ConfigEntityTypeInterface) {
-      $entity_type->setHandlerClass('entity_clone', '\Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneBase');
-      $entity_type->setHandlerClass('entity_clone_form', '\Drupal\entity_clone\EntityClone\Config\ConfigEntityCloneFormBase');
+      $entity_type->setHandlerClass('entity_clone', ConfigEntityCloneBase::class);
+      $entity_type->setHandlerClass('entity_clone_form', ConfigEntityCloneFormBase::class);
     }
   }
 }
diff --git a/entity_clone.routing.yml b/entity_clone.routing.yml
new file mode 100644
index 0000000..b89a94b
--- /dev/null
+++ b/entity_clone.routing.yml
@@ -0,0 +1,9 @@
+entity_clone.settings:
+  path: '/admin/config/system/entity-clone'
+  defaults:
+    _form: 'Drupal\entity_clone\Form\EntityCloneSettingsForm'
+    _title: 'Entity clone settings'
+  options:
+    _admin_route: TRUE
+  requirements:
+    _permission: 'administer entity clone'
diff --git a/entity_clone.services.yml b/entity_clone.services.yml
index deb11ef..20cf5db 100644
--- a/entity_clone.services.yml
+++ b/entity_clone.services.yml
@@ -1,4 +1,7 @@
 services:
+  entity_clone.settings.manager:
+    class: Drupal\entity_clone\EntityCloneSettingsManager
+    arguments: ['@entity_type.manager', '@entity_type.bundle.info', '@config.factory']
   entity_clone.route_subscriber:
     class: Drupal\entity_clone\Routing\RouteSubscriber
     arguments: ['@entity_type.manager']
diff --git a/src/EntityClone/Config/ConfigEntityCloneBase.php b/src/EntityClone/Config/ConfigEntityCloneBase.php
index ecf5116..c0c3349 100644
--- a/src/EntityClone/Config/ConfigEntityCloneBase.php
+++ b/src/EntityClone/Config/ConfigEntityCloneBase.php
@@ -54,7 +54,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
   /**
    * {@inheritdoc}
    */
-  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []) {
+  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, array $properties = []) {
     /** @var \Drupal\core\Config\Entity\ConfigEntityInterface $cloned_entity */
     $id_key = $this->entityTypeManager->getDefinition($this->entityTypeId)->getKey('id');
     $label_key = $this->entityTypeManager->getDefinition($this->entityTypeId)->getKey('label');
diff --git a/src/EntityClone/Config/ConfigEntityCloneFormBase.php b/src/EntityClone/Config/ConfigEntityCloneFormBase.php
index d40ddd5..8d2f125 100644
--- a/src/EntityClone/Config/ConfigEntityCloneFormBase.php
+++ b/src/EntityClone/Config/ConfigEntityCloneFormBase.php
@@ -60,20 +60,20 @@ public function formElement(EntityInterface $entity) {
     $form = [];
 
     if ($this->entityTypeManager->getDefinition($entity->getEntityTypeId())->getKey('label')) {
-      $form['label'] = array(
+      $form['label'] = [
         '#type' => 'textfield',
         '#title' => $this->translationManager->translate('New Label'),
         '#maxlength' => 255,
         '#required' => TRUE,
-      );
+      ];
     }
 
-    $form['id'] = array(
+    $form['id'] = [
       '#type' => 'machine_name',
       '#title' => $this->translationManager->translate('New Id'),
       '#maxlength' => 255,
       '#required' => TRUE,
-    );
+    ];
 
     // If entity must have a prefix
     // (e.g. entity_form_mode, entity_view_mode, ...).
@@ -93,7 +93,7 @@ public function formElement(EntityInterface $entity) {
   /**
    * {@inheritdoc}
    */
-  public function getNewValues(FormStateInterface $form_state) {
+  public function getValues(FormStateInterface $form_state) {
     // If entity must have a prefix
     // (e.g. entity_form_mode, entity_view_mode, ...).
     $field_prefix = '';
diff --git a/src/EntityClone/Config/ConfigWithFieldEntityClone.php b/src/EntityClone/Config/ConfigWithFieldEntityClone.php
index 6b66e9a..7cdb093 100644
--- a/src/EntityClone/Config/ConfigWithFieldEntityClone.php
+++ b/src/EntityClone/Config/ConfigWithFieldEntityClone.php
@@ -13,7 +13,7 @@ class ConfigWithFieldEntityClone extends ConfigEntityCloneBase {
   /**
    * {@inheritdoc}
    */
-  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []) {
+  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, array $properties = []) {
     $cloned_entity = parent::cloneEntity($entity, $cloned_entity, $properties);
     $bundle_of = $cloned_entity->getEntityType()->getBundleOf();
     if ($bundle_of) {
@@ -40,16 +40,16 @@ public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_ent
    *
    * @param string $entity_id
    *   The base entity ID.
-   * @param $cloned_entity_id
+   * @param string $cloned_entity_id
    *   The cloned entity ID.
-   * @param $bundle_of
+   * @param string $bundle_of
    *   The bundle of the cloned entity.
    */
   protected function cloneFields($entity_id, $cloned_entity_id, $bundle_of) {
     /** @var \Drupal\Core\Entity\EntityFieldManager $field_manager */
     $field_manager = \Drupal::service('entity_field.manager');
     $fields = $field_manager->getFieldDefinitions($bundle_of, $entity_id);
-    foreach ($fields as $field_id => $field_definition) {
+    foreach ($fields as $field_definition) {
       if ($field_definition instanceof FieldConfigInterface) {
         if ($this->entityTypeManager->hasHandler($this->entityTypeManager->getDefinition($field_definition->getEntityTypeId())
           ->id(), 'entity_clone')
@@ -77,14 +77,14 @@ protected function cloneFields($entity_id, $cloned_entity_id, $bundle_of) {
    *   The type of display (view or form).
    * @param string $entity_id
    *   The base entity ID.
-   * @param $cloned_entity_id
+   * @param string $cloned_entity_id
    *   The cloned entity ID.
    * @param array $view_displays
    *   All view available display for this type.
-   * @param $bundle_of
+   * @param string $bundle_of
    *   The bundle of the cloned entity.
    */
-  protected function cloneDisplays($type, $entity_id, $cloned_entity_id, $view_displays, $bundle_of) {
+  protected function cloneDisplays($type, $entity_id, $cloned_entity_id, array $view_displays, $bundle_of) {
     foreach ($view_displays as $view_display_id => $view_display) {
       /** @var \Drupal\Core\Entity\Display\EntityDisplayInterface $display */
       $display = $this->entityTypeManager->getStorage('entity_' . $type . '_display')->load($bundle_of . '.' . $entity_id . '.' . $view_display_id);
diff --git a/src/EntityClone/Config/FieldConfigEntityClone.php b/src/EntityClone/Config/FieldConfigEntityClone.php
index a4fb270..b16d1ed 100644
--- a/src/EntityClone/Config/FieldConfigEntityClone.php
+++ b/src/EntityClone/Config/FieldConfigEntityClone.php
@@ -12,7 +12,7 @@ class FieldConfigEntityClone extends ConfigEntityCloneBase {
   /**
    * {@inheritdoc}
    */
-  public function cloneEntity(EntityInterface $field_config, EntityInterface $cloned_field_config, $properties = []) {
+  public function cloneEntity(EntityInterface $field_config, EntityInterface $cloned_field_config, array $properties = []) {
     /** @var \Drupal\field\Entity\FieldConfig $field_config */
     /** @var \Drupal\field\Entity\FieldConfig $cloned_field_config */
     /** @var \Drupal\field\Entity\FieldStorageConfig $cloned_field_storage */
diff --git a/src/EntityClone/Content/ContentEntityCloneBase.php b/src/EntityClone/Content/ContentEntityCloneBase.php
index 6712f6b..98c3ba6 100644
--- a/src/EntityClone/Content/ContentEntityCloneBase.php
+++ b/src/EntityClone/Content/ContentEntityCloneBase.php
@@ -6,6 +6,10 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldConfigInterface;
+use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\entity_clone\EntityClone\EntityCloneInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -54,15 +58,136 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
   /**
    * {@inheritdoc}
    */
-  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []) {
-    /** @var \Drupal\core\Entity\ContentEntityInterface $cloned_entity */
-    if ($label_key = $this->entityTypeManager->getDefinition($this->entityTypeId)->getKey('label')) {
-      $cloned_entity->set($label_key, $entity->label() . ' - Cloned');
+  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, array $properties = []) {
+    // Clone referenced entities.
+    if ($cloned_entity instanceof FieldableEntityInterface && $entity instanceof FieldableEntityInterface) {
+      foreach ($cloned_entity->getFieldDefinitions() as $field_id => $field_definition) {
+        if ($this->fieldIsClonable($field_definition)) {
+          $field = $entity->get($field_id);
+          /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $value */
+          if ($field->count() > 0) {
+            $cloned_entity->set($field_id, $this->cloneReferencedEntities($field, $field_definition, $properties));
+          }
+        }
+      }
     }
 
+    $this->setClonedEntityLabel($entity, $cloned_entity);
     $cloned_entity->save();
-
     return $cloned_entity;
   }
 
+  /**
+   * Determines if a field is clonable.
+   *
+   * @param Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The field definition.
+   *
+   * @return bool
+   *   TRUE if th field is clonable; FALSE otherwise.
+   */
+  protected function fieldIsClonable(FieldDefinitionInterface $field_definition) {
+    $clonable_field_types = [
+      'entity_reference',
+      'entity_reference_revisions',
+    ];
+
+    $type_is_clonable = in_array($field_definition->getType(), $clonable_field_types);
+    if (($field_definition instanceof FieldConfigInterface) && $type_is_clonable) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * Sets the cloned entity's label.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $original_entity
+   *   The original entity.
+   * @param \Drupal\Core\Entity\EntityInterface $cloned_entity
+   *   The entity cloned from the original.
+   */
+  protected function setClonedEntityLabel(EntityInterface $original_entity, EntityInterface $cloned_entity) {
+    $label_key = $this->entityTypeManager->getDefinition($this->entityTypeId)->getKey('label');
+    if ($label_key) {
+      $cloned_entity->set($label_key, $original_entity->label() . ' - Cloned');
+    }
+  }
+
+  /**
+   * Clone referenced entities.
+   *
+   * @param \Drupal\Core\Field\FieldItemListInterface $field
+   *   The field item.
+   * @param \Drupal\Core\Field\FieldConfigInterface $field_definition
+   *   The field definition.
+   * @param array $properties
+   *   All new properties to replace old.
+   *
+   * @return array
+   *   Referenced entities.
+   */
+  protected function cloneReferencedEntities(FieldItemListInterface $field, FieldConfigInterface $field_definition, array $properties) {
+    $referenced_entities = [];
+    foreach ($field as $value) {
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $referenced_entity */
+      $referenced_entity = $value->get('entity')->getTarget()->getValue();
+      if (isset($properties['recursive'][$field_definition->id()]['references'][$referenced_entity->id()]['clone'])
+        && $properties['recursive'][$field_definition->id()]['references'][$referenced_entity->id()]['clone']) {
+
+        $cloned_reference = $referenced_entity->createDuplicate();
+        /** @var \Drupal\entity_clone\EntityClone\EntityCloneInterface $entity_clone_handler */
+        $entity_clone_handler = $this->entityTypeManager->getHandler($referenced_entity->getEntityTypeId(), 'entity_clone');
+        $child_properties = $this->getChildProperties($properties, $field_definition, $referenced_entity);
+        $entity_clone_handler->cloneEntity($referenced_entity, $cloned_reference, $child_properties);
+
+        $referenced_entities[] = $this->formatTargetIdsAsArray($cloned_reference->id(), $cloned_reference->getRevisionId());
+      }
+      else {
+        $referenced_entities[] = $this->formatTargetIdsAsArray($referenced_entity->id(), $referenced_entity->getRevisionId());
+      }
+    }
+    return $referenced_entities;
+  }
+
+  /**
+   * Fetches the properties of a child entity.
+   *
+   * @param array $properties
+   *   Properties of the clone operation.
+   * @param \Drupal\Core\Field\FieldConfigInterface $field_definition
+   *   The field definition.
+   * @param \Drupal\Core\Entity\EntityInterface $referenced_entity
+   *   The field's target entity.
+   */
+  protected function getChildProperties(array $properties, FieldConfigInterface $field_definition, EntityInterface $referenced_entity) {
+    $child_properties = [];
+    if (isset($properties['recursive'][$field_definition->id()]['references'][$referenced_entity->id()]['children'])) {
+      $child_properties = $properties['recursive'][$field_definition->id()]['references'][$referenced_entity->id()]['children'];
+    }
+    return $child_properties;
+  }
+
+  /**
+   * Formats the target and revision IDs as an array.
+   *
+   * @param int $target_id
+   *   The target ID.
+   * @param int $target_revision_id
+   *   The target revision ID.
+   *
+   * @return array
+   *   The IDs are returned in this form:
+   *     [
+   *       'target_id' => THE_PROVIDED_TARGET_ID,
+   *       'target_revision_id' => THE_PROVIDED_TARGET_REVISION_ID,
+   *     ]
+   */
+  protected function formatTargetIdsAsArray($target_id, $target_revision_id) {
+    return [
+      'target_id' => $target_id,
+      'target_revision_id' => $target_revision_id,
+    ];
+  }
+
 }
diff --git a/src/EntityClone/Content/ContentEntityCloneFormBase.php b/src/EntityClone/Content/ContentEntityCloneFormBase.php
new file mode 100644
index 0000000..40f62ad
--- /dev/null
+++ b/src/EntityClone/Content/ContentEntityCloneFormBase.php
@@ -0,0 +1,188 @@
+<?php
+
+namespace Drupal\entity_clone\EntityClone\Content;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityHandlerInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\EntityTypeManager;
+use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\Core\Field\FieldConfigInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslationManager;
+use Drupal\entity_clone\EntityClone\EntityCloneFormInterface;
+use Drupal\entity_clone\EntityCloneSettingsManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Class ContentEntityCloneFormBase.
+ */
+class ContentEntityCloneFormBase implements EntityHandlerInterface, EntityCloneFormInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\StringTranslation\TranslationManager
+   */
+  protected $translationManager;
+
+  /**
+   * The entity type manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManager
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The entity clone settings manager service.
+   *
+   * @var \Drupal\entity_clone\EntityCloneSettingsManager
+   */
+  protected $entityCloneSettingsManager;
+
+  /**
+   * Constructs a new ContentEntityCloneFormBase.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\Core\StringTranslation\TranslationManager $translation_manager
+   *   The string translation manager.
+   * @param \Drupal\entity_clone\EntityCloneSettingsManager $entity_clone_settings_manager
+   *   The entity clone settings manager.
+   */
+  public function __construct(EntityTypeManager $entity_type_manager, TranslationManager $translation_manager, EntityCloneSettingsManager $entity_clone_settings_manager) {
+    $this->entityTypeManager = $entity_type_manager;
+    $this->translationManager = $translation_manager;
+    $this->entityCloneSettingsManager = $entity_clone_settings_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+    return new static(
+      $container->get('entity_type.manager'),
+      $container->get('string_translation'),
+      $container->get('entity_clone.settings.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(EntityInterface $entity) {
+    $form = [
+      'recursive' => []
+    ];
+
+    if ($entity instanceof FieldableEntityInterface) {
+      foreach ($entity->getFieldDefinitions() as $field_id => $field_definition) {
+        if ($field_definition instanceof FieldConfigInterface && in_array($field_definition->getType(), ['entity_reference', 'entity_reference_revisions'])) {
+          $field = $entity->get($field_id);
+          /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $value */
+          if ($field->count() > 0) {
+            $form['recursive'] = array_merge($form['recursive'], $this->getRecursiveFormElement($field_definition, $field_id, $field));
+          }
+        }
+      }
+    }
+
+    return $form;
+  }
+
+  /**
+   * Get the recursive form element.
+   *
+   * @param \Drupal\Core\Field\FieldConfigInterface $field_definition
+   *   The field definition.
+   * @param string $field_id
+   *   The field ID.
+   * @param \Drupal\Core\Field\FieldItemListInterface $field
+   *   The field item.
+   *
+   * @return array
+   *   The form element for a recursive clone.
+   */
+  protected function getRecursiveFormElement(FieldConfigInterface $field_definition, $field_id, FieldItemListInterface $field) {
+    $form_element = [
+      '#tree' => TRUE,
+    ];
+
+    $form_element[$field_definition->id()] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Entities referenced by field <em>@label (@field_id)</em>.', [
+        '@label' => $field_definition->label(),
+        '@field_id' => $field_id,
+      ]),
+      '#access' => !$this->entityCloneSettingsManager->getHiddenValue($field_definition->getFieldStorageDefinition()->getSetting('target_type')),
+    ];
+
+    foreach ($field as $value) {
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $referenced_entity */
+      $referenced_entity = $value->get('entity')->getTarget()->getValue();
+
+      $form_element[$field_definition->id()]['references'][$referenced_entity->id()]['clone'] = [
+        '#type' => 'checkbox',
+        '#title' => $this->t('Clone entity <strong>ID:</strong> <em>@entity_id</em>, <strong>Type:</strong> <em>@entity_type - @bundle</em>, <strong>Label:</strong> <em>@entity_label</em>', [
+          '@entity_id' => $referenced_entity->id(),
+          '@entity_type' => $referenced_entity->getEntityTypeId(),
+          '@bundle' => $referenced_entity->bundle(),
+          '@entity_label' => $referenced_entity->label(),
+        ]),
+        '#default_value' => $this->entityCloneSettingsManager->getDefaultValue($referenced_entity->getEntityTypeId()),
+      ];
+
+      if ($this->entityCloneSettingsManager->getDisableValue($referenced_entity->getEntityTypeId())) {
+        $form_element[$field_definition->id()]['references'][$referenced_entity->id()]['clone']['#attributes'] = [
+          'disabled' => TRUE,
+        ];
+        $form_element[$field_definition->id()]['references'][$referenced_entity->id()]['clone']['#value'] = $form_element[$field_definition->id()]['references'][$referenced_entity->id()]['clone']['#default_value'];
+      }
+
+      $form_element[$field_definition->id()]['references'][$referenced_entity->id()]['target_entity_type_id'] = [
+        '#type' => 'hidden',
+        '#value' => $referenced_entity->getEntityTypeId(),
+      ];
+
+      $form_element[$field_definition->id()]['references'][$referenced_entity->id()]['target_bundle'] = [
+        '#type' => 'hidden',
+        '#value' => $referenced_entity->bundle(),
+      ];
+      if ($referenced_entity instanceOf ContentEntityInterface) {
+        $form_element[$field_definition->id()]['references'][$referenced_entity->id()]['children'] = $this->getChildren($referenced_entity);
+      }
+    }
+
+    return $form_element;
+  }
+
+  /**
+   * Fetches clonable children from a field.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $referenced_entity
+   *   The field item list.
+   *
+   * @return array
+   *   The list of children.
+   */
+  protected function getChildren(ContentEntityInterface $referenced_entity) {
+    /** @var \Drupal\entity_clone\EntityClone\EntityCloneFormInterface $entity_clone_handler */
+    if ($this->entityTypeManager->hasHandler($referenced_entity->getEntityTypeId(), 'entity_clone_form')) {
+      $entity_clone_form_handler = $this->entityTypeManager->getHandler($referenced_entity->getEntityTypeId(), 'entity_clone_form');
+      return $entity_clone_form_handler->formElement($referenced_entity);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValues(FormStateInterface $form_state) {
+    return $form_state->getValues();
+  }
+
+}
diff --git a/src/EntityClone/Content/FileEntityClone.php b/src/EntityClone/Content/FileEntityClone.php
index b15924e..fb552c4 100644
--- a/src/EntityClone/Content/FileEntityClone.php
+++ b/src/EntityClone/Content/FileEntityClone.php
@@ -12,7 +12,7 @@ class FileEntityClone extends ContentEntityCloneBase {
   /**
    * {@inheritdoc}
    */
-  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []) {
+  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, array $properties = []) {
     /** @var \Drupal\file\FileInterface $cloned_entity */
     $cloned_file = file_copy($cloned_entity, $cloned_entity->getFileUri(), FILE_EXISTS_RENAME);
     return parent::cloneEntity($entity, $cloned_file, $properties);
diff --git a/src/EntityClone/Content/TaxonomyTermEntityClone.php b/src/EntityClone/Content/TaxonomyTermEntityClone.php
new file mode 100644
index 0000000..15388c6
--- /dev/null
+++ b/src/EntityClone/Content/TaxonomyTermEntityClone.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\entity_clone\EntityClone\Content;
+
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Class TaxonomyTermEntityClone.
+ */
+class TaxonomyTermEntityClone extends ContentEntityCloneBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, array $properties = []) {
+    /** @var \Drupal\core\Entity\ContentEntityInterface $cloned_entity */
+
+    // Enforce a parent if the cloned term doesn't have a parent.
+    // (First level of a taxonomy tree).
+    if (!isset($cloned_entity->parent->target_id)) {
+      $cloned_entity->set('parent', 0);
+    }
+    return parent::cloneEntity($entity, $cloned_entity, $properties);
+  }
+
+}
diff --git a/src/EntityClone/Content/UserEntityClone.php b/src/EntityClone/Content/UserEntityClone.php
index 25c9979..68e64b4 100644
--- a/src/EntityClone/Content/UserEntityClone.php
+++ b/src/EntityClone/Content/UserEntityClone.php
@@ -12,7 +12,7 @@ class UserEntityClone extends ContentEntityCloneBase {
   /**
    * {@inheritdoc}
    */
-  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []) {
+  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, array $properties = []) {
     /** @var \Drupal\user\UserInterface $cloned_entity */
     $cloned_entity->set('name', $cloned_entity->getAccountName() . '_cloned');
     return parent::cloneEntity($entity, $cloned_entity, $properties);
diff --git a/src/EntityClone/EntityCloneFormInterface.php b/src/EntityClone/EntityCloneFormInterface.php
index 2ac5622..a30c217 100644
--- a/src/EntityClone/EntityCloneFormInterface.php
+++ b/src/EntityClone/EntityCloneFormInterface.php
@@ -30,6 +30,6 @@ public function formElement(EntityInterface $entity);
    * @return array
    *   An array containing all new values.
    */
-  public function getNewValues(FormStateInterface $form_state);
+  public function getValues(FormStateInterface $form_state);
 
 }
diff --git a/src/EntityClone/EntityCloneInterface.php b/src/EntityClone/EntityCloneInterface.php
index c8e0949..ed02023 100644
--- a/src/EntityClone/EntityCloneInterface.php
+++ b/src/EntityClone/EntityCloneInterface.php
@@ -19,9 +19,9 @@
    * @param array $properties
    *   All new properties to replace old.
    *
-   * @return \Drupal\Core\Entity\EntityInterface The new saved entity.
-   * The new saved entity.
+   * @return \Drupal\Core\Entity\EntityInterface
+   *   The new saved entity.
    */
-  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []);
+  public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, array $properties = []);
 
 }
diff --git a/src/EntityCloneSettingsManager.php b/src/EntityCloneSettingsManager.php
new file mode 100644
index 0000000..f578ebb
--- /dev/null
+++ b/src/EntityCloneSettingsManager.php
@@ -0,0 +1,149 @@
+<?php
+
+namespace Drupal\entity_clone;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\ContentEntityTypeInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+
+/**
+ * Manage entity clone configuration.
+ */
+class EntityCloneSettingsManager {
+
+  /**
+   * The entity type manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The entity type bundle info service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+   */
+  protected $entityTypeBundleInfo;
+
+  /**
+   * The immutable entity clone settings configuration entity.
+   *
+   * @var \Drupal\Core\Config\ImmutableConfig
+   */
+  protected $config;
+
+  /**
+   * The editable entity clone settings configuration entity.
+   *
+   * @var \Drupal\Core\Config\Config
+   */
+  protected $editableConfig;
+
+  /**
+   * EntityCloneSettingsManager constructor.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager service.
+   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
+   *   The entity type bundle info service.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory service.
+   */
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, ConfigFactoryInterface $config_factory) {
+    $this->entityTypeManager = $entity_type_manager;
+    $this->entityTypeBundleInfo = $entity_type_bundle_info;
+    $this->config = $config_factory->get('entity_clone.settings');
+    $this->editableConfig = $config_factory->getEditable('entity_clone.settings');
+  }
+
+  /**
+   * Get all content entity types.
+   *
+   * @return \Drupal\Core\Entity\ContentEntityTypeInterface[]
+   *   An array containing all content entity types.
+   */
+  public function getContentEntityTypes($allowed_only = FALSE) {
+    $definitions = $this->entityTypeManager->getDefinitions();
+    $ret = [];
+    foreach ($definitions as $machine => $type) {
+      if ($type instanceof ContentEntityTypeInterface) {
+        $ret[$machine] = $type;
+      }
+    }
+
+    return $ret;
+  }
+
+  /**
+   * Set the entity clone settings.
+   *
+   * @param array $settings
+   *   The settings from the form.
+   */
+  public function setFormSettings(array $settings) {
+    if (isset($settings['table'])) {
+      array_walk_recursive($settings['table'], function (&$item) {
+        if ($item == '1') {
+          $item = TRUE;
+        }
+        else {
+          $item = FALSE;
+        }
+      });
+      $this->editableConfig->set('form_settings', $settings['table'])->save();
+    }
+  }
+
+  /**
+   * Get the checkbox default value for a given entity type.
+   *
+   * @param string $entity_type_id
+   *   The entity type ID.
+   *
+   * @return bool
+   *   The default value.
+   */
+  public function getDefaultValue($entity_type_id) {
+    $form_settings = $this->config->get('form_settings');
+    if (isset($form_settings[$entity_type_id]['default_value'])) {
+      return $form_settings[$entity_type_id]['default_value'];
+    }
+    return FALSE;
+  }
+
+  /**
+   * Get the checkbox disable value for a given entity type.
+   *
+   * @param string $entity_type_id
+   *   The entity type ID.
+   *
+   * @return bool
+   *   The disable value.
+   */
+  public function getDisableValue($entity_type_id) {
+    $form_settings = $this->config->get('form_settings');
+    if (isset($form_settings[$entity_type_id]['disable'])) {
+      return $form_settings[$entity_type_id]['disable'];
+    }
+    return FALSE;
+  }
+
+  /**
+   * Get the checkbox hidden value for a given entity type.
+   *
+   * @param string $entity_type_id
+   *   The entity type ID.
+   *
+   * @return bool
+   *   The hidden value.
+   */
+  public function getHiddenValue($entity_type_id) {
+    $form_settings = $this->config->get('form_settings');
+    if (isset($form_settings[$entity_type_id]['hidden'])) {
+      return $form_settings[$entity_type_id]['hidden'];
+    }
+    return FALSE;
+  }
+
+}
diff --git a/src/Form/EntityCloneForm.php b/src/Form/EntityCloneForm.php
index 8ca215f..645506a 100644
--- a/src/Form/EntityCloneForm.php
+++ b/src/Form/EntityCloneForm.php
@@ -102,11 +102,26 @@ public function getFormId() {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
     if ($this->entity && $this->entityTypeDefinition->hasHandlerClass('entity_clone')) {
-      $form['information'] = [
-        '#markup' => $this->stringTranslationManager->translate('<p>Do you want clone the <em>@entity_type</em> entity named <em>@title</em>?</p>', [
-          '@entity_type' => $this->entity->getEntityType()->getLabel(),
-          '@title' => $this->entity->label(),
-        ]),
+
+      $form['description'] = [
+        '#markup' => t("
+          <p>Specify the child entities (the entities referenced by this entity) that should also be cloned as part of
+          the cloning process.  If they're not included, these fields' referenced entities will be the same as in the
+          original.  In other words, fields in both the original entity and the cloned entity will refer to the same
+          referenced entity.  Examples:</p>
+
+          <p>If you have a Paragraph field in your entity, and you choose not to clone it here, deleting the original
+          or cloned entity will also delete the Paragraph field from the other one.  So you probably want to clone
+          Paragraph fields.</p>
+
+          <p>However, if you have a User reference field, you probably don't want to clone it here because a new User
+          will be created for referencing by the clone.</p>
+
+          <p>Some options may be disabled here, preventing you from changing them, as set by your administrator.  Some
+          options may also be missing, hidden by your administrator, forcing you to clone with the default settings.
+          It's possible that there are no options here for you at all, or none need to be set, in which case you may
+          simply hit the <em>Clone</em> button.</p>
+        "),
       ];
 
       /** @var \Drupal\entity_clone\EntityClone\EntityCloneFormInterface $entity_clone_handler */
@@ -147,7 +162,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     $properties = [];
     if (isset($entity_clone_form_handler) && $entity_clone_form_handler) {
-      $properties = $entity_clone_form_handler->getNewValues($form_state);
+      $properties = $entity_clone_form_handler->getValues($form_state);
     }
 
     $duplicate = $this->entity->createDuplicate();
diff --git a/src/Form/EntityCloneSettingsForm.php b/src/Form/EntityCloneSettingsForm.php
new file mode 100644
index 0000000..9dde82b
--- /dev/null
+++ b/src/Form/EntityCloneSettingsForm.php
@@ -0,0 +1,125 @@
+<?php
+
+namespace Drupal\entity_clone\Form;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Form\ConfigFormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\entity_clone\EntityCloneSettingsManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provide the settings form for entity clone.
+ */
+class EntityCloneSettingsForm extends ConfigFormBase implements ContainerInjectionInterface {
+
+  /**
+   * The entity clone settings manager.
+   *
+   * @var \Drupal\entity_clone\EntityCloneSettingsManager
+   */
+  protected $entityCloneSettingsManager;
+
+  /**
+   * {@inheritdoc}
+   *
+   * @var \Drupal\entity_clone\EntityCloneSettingsManager $entity_clone_settings_manager
+   */
+  public function __construct(ConfigFactoryInterface $config_factory, EntityCloneSettingsManager $entity_clone_settings_manager) {
+    parent::__construct($config_factory);
+    $this->entityCloneSettingsManager = $entity_clone_settings_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('config.factory'),
+      $container->get('entity_clone.settings.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getEditableConfigNames() {
+    return ['entity_clone.settings'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'entity_clone_settings_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $form['#tree'] = TRUE;
+
+    $form['form_settings'] = [
+      '#tree' => TRUE,
+      '#type' => 'fieldset',
+      '#title' => $this->t('Clone form settings'),
+      '#description' => $this->t("
+        For each type of child entity (the entity that's referenced by the entity being
+        cloned), please set your cloning preferences. This will affect the clone form presented to users when they
+        clone entities. Default behaviour for whether or not the child entities should be cloned is specified in
+        the left-most column.  To prevent users from altering behaviour for each type when they're actually cloning
+        (but still allowing them to see what will happen), use the middle column. The right-most column can be used
+        to hide the form options from users completely. This will run the clone operation with the defaults set here
+        (in the left-most column). See the clone form (by cloning an entity) for more information.
+      "),
+      '#open' => TRUE,
+      '#collapsible' => FALSE,
+    ];
+
+    $form['form_settings']['table'] = [
+      '#type' => 'table',
+      '#header' => [
+        'label' => $this->t('Label'),
+        'default_value' => $this->t('Checkboxes default value'),
+        'disable'  => $this->t('Disable checkboxes'),
+        'hidden' => $this->t('Hide checkboxes'),
+      ],
+    ];
+
+    foreach ($this->entityCloneSettingsManager->getContentEntityTypes() as $type_id => $type) {
+      $form['form_settings']['table'][$type_id] = [
+        'label' => [
+          '#type' => 'label',
+          '#title' => $this->t('@type', [
+            '@type' => $type->getLabel(),
+          ]),
+        ],
+        'default_value' => [
+          '#type' => 'checkbox',
+          '#default_value' => $this->entityCloneSettingsManager->getDefaultValue($type_id),
+        ],
+        'disable' => [
+          '#type' => 'checkbox',
+          '#default_value' => $this->entityCloneSettingsManager->getDisableValue($type_id),
+        ],
+        'hidden' => [
+          '#type' => 'checkbox',
+          '#default_value' => $this->entityCloneSettingsManager->getHiddenValue($type_id),
+        ],
+      ];
+    }
+
+    return parent::buildForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $this->entityCloneSettingsManager->setFormSettings($form_state->getValue('form_settings'));
+    parent::submitForm($form, $form_state);
+  }
+
+}
diff --git a/src/Tests/EntityCloneContentRecursiveTest.php b/src/Tests/EntityCloneContentRecursiveTest.php
new file mode 100644
index 0000000..df6f88b
--- /dev/null
+++ b/src/Tests/EntityCloneContentRecursiveTest.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Drupal\entity_clone\Tests;
+
+use Drupal\node\Entity\Node;
+use Drupal\node\Tests\NodeTestBase;
+use Drupal\taxonomy\Entity\Term;
+
+/**
+ * Create a content and test a clone.
+ *
+ * @group entity_clone
+ */
+class EntityCloneContentRecursiveTest extends NodeTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['entity_clone', 'block', 'node', 'datetime'];
+
+  /**
+   * Profile to install.
+   *
+   * @var string
+   */
+  protected $profile = 'standard';
+
+  /**
+   * Permissions to grant admin user.
+   *
+   * @var array
+   */
+  protected $permissions = [
+    'bypass node access',
+    'administer nodes',
+    'clone node entity',
+  ];
+
+  /**
+   * A user with permission to bypass content access checks.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $adminUser;
+
+  /**
+   * Sets the test up.
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->adminUser = $this->drupalCreateUser($this->permissions);
+    $this->drupalLogin($this->adminUser);
+  }
+
+  /**
+   * Test clone a content entity with another entities attached.
+   */
+  public function testContentEntityClone() {
+
+    $term_title = $this->randomMachineName(8);
+    $term = Term::create([
+      'vid' => 'tags',
+      'name' => $term_title,
+    ]);
+    $term->save();
+
+    $node_title = $this->randomMachineName(8);
+    $node = Node::create([
+      'type' => 'article',
+      'title' => $node_title,
+      'field_tags' => [
+        'target_id' => $term->id(),
+      ],
+    ]);
+    $node->save();
+
+    $this->drupalPostForm('entity_clone/node/' . $node->id(), [
+      'recursive[node.article.field_tags][references][' . $term->id() . '][clone]' => 1,
+    ], t('Clone'));
+
+    $nodes = \Drupal::entityTypeManager()
+      ->getStorage('node')
+      ->loadByProperties([
+        'title' => $node_title . ' - Cloned',
+      ]);
+    /** @var \Drupal\node\Entity\Node $node */
+    $node = reset($nodes);
+    $this->assertTrue($node, 'Test node cloned found in database.');
+
+    $terms = \Drupal::entityTypeManager()
+      ->getStorage('taxonomy_term')
+      ->loadByProperties([
+        'name' => $term_title . ' - Cloned',
+      ]);
+    /** @var \Drupal\taxonomy\Entity\Term $term */
+    $term = reset($terms);
+    $this->assertTrue($term, 'Test term referenced by node cloned too found in database.');
+
+    $node->delete();
+    $term->delete();
+
+    $nodes = \Drupal::entityTypeManager()
+      ->getStorage('node')
+      ->loadByProperties([
+        'title' => $node_title,
+      ]);
+    $node = reset($nodes);
+    $this->assertTrue($node, 'Test original node found in database.');
+
+    $terms = \Drupal::entityTypeManager()
+      ->getStorage('taxonomy_term')
+      ->loadByProperties([
+        'name' => $term_title,
+      ]);
+    $term = reset($terms);
+    $this->assertTrue($term, 'Test original term found in database.');
+  }
+
+}
