diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php
index 167f169..47aab46 100644
--- a/core/modules/views/src/Entity/View.php
+++ b/core/modules/views/src/Entity/View.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\views\Entity;
 
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\views\Views;
@@ -242,6 +243,40 @@ public function &getDisplay($display_id) {
   /**
    * {@inheritdoc}
    */
+  public function duplicateDisplayAsType($old_display_id, $new_display_type) {
+    $executable = $this->getExecutable();
+    $display = $executable->newDisplay($new_display_type);
+    $new_display_id = $display->display['id'];
+    $displays = $this->get('display');
+
+    // Let the display title be generated by the addDisplay method and set the
+    // right display plugin, but keep the rest from the original display.
+    $display_duplicate = $displays[$old_display_id];
+    unset($display_duplicate['display_title']);
+    unset($display_duplicate['display_plugin']);
+
+    $displays[$new_display_id] = NestedArray::mergeDeep($displays[$new_display_id], $display_duplicate);
+    $displays[$new_display_id]['id'] = $new_display_id;
+
+    // First set the displays.
+    $this->set('display', $displays);
+
+    // Ensure that we just copy display options, which are provided by the new
+    // display plugin.
+    $executable = $this->getExecutable();
+    $executable->setDisplay($new_display_id);
+
+    $defined_options = $executable->display_handler->getDefinedOptions();
+    $executable->display_handler->filterByDefinedOptions($displays[$new_display_id]['display_options'], $defined_options);
+    // Update the display settings.
+    $this->set('display', $displays);
+
+    return $new_display_id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function calculateDependencies() {
     parent::calculateDependencies();
 
diff --git a/core/modules/views/src/Plugin/views/PluginBase.php b/core/modules/views/src/Plugin/views/PluginBase.php
index 7992378..3904113 100644
--- a/core/modules/views/src/Plugin/views/PluginBase.php
+++ b/core/modules/views/src/Plugin/views/PluginBase.php
@@ -177,6 +177,27 @@ protected function setOptionDefaults(array &$storage, array $options) {
   }
 
   /**
+   * Filter out stored options depending on the defined options
+   *
+   * @param array $storage
+   *   The stored options.
+   *
+   * @param array $options
+   *   The defined options.
+   */
+  public function filterByDefinedOptions(array &$storage, array $options) {
+    foreach ($storage as $key => $sub_storage) {
+      if (!isset($options[$key])) {
+        unset($storage[$key]);
+      }
+
+      if (isset($options[$key]['contains'])) {
+        $this->filterByDefinedOptions($storage[$key], $options[$key]['contains']);
+      }
+    }
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function unpackOptions(&$storage, $options, $definition = NULL, $all = TRUE, $check = TRUE) {
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index e471d8a..bf316a4 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -505,6 +505,17 @@ public function defaultableSections($section = NULL) {
     }
   }
 
+  /**
+   * Gets the defined options.
+   *
+   * @see ::defineOptions()
+   *
+   * @return array
+   */
+  public function getDefinedOptions() {
+    return $this->defineOptions();
+  }
+
   protected function defineOptions() {
     $options = array(
       'defaults' => array(
diff --git a/core/modules/views/src/ViewStorageInterface.php b/core/modules/views/src/ViewStorageInterface.php
index 31b9f7b..d894452 100644
--- a/core/modules/views/src/ViewStorageInterface.php
+++ b/core/modules/views/src/ViewStorageInterface.php
@@ -15,6 +15,14 @@
 interface ViewStorageInterface extends ConfigEntityInterface {
 
   /**
+   * Gets an executable instance for this view.
+   *
+   * @return \Drupal\views\ViewExecutable
+   *   A view executable instance.
+   */
+  public function getExecutable();
+
+  /**
    * Retrieves a specific display's configuration by reference.
    *
    * @param string $display_id
@@ -30,4 +38,19 @@ public function &getDisplay($display_id);
    */
   public function mergeDefaultDisplaysOptions();
 
+  /**
+   * Duplicates an existing display into a new display type.
+   *
+   * For example clone to display a page display as a block display.
+   *
+   * @param string $old_display_id
+   *   The origin of the duplicated display.
+   * @param string $new_display_type
+   *   The display type of the new display.
+   *
+   * @return string
+   *   The display ID of the new display.
+   */
+  public function duplicateDisplayAsType($old_display_id, $new_display_type);
+
 }
diff --git a/core/modules/views/tests/src/Unit/PluginBaseTest.php b/core/modules/views/tests/src/Unit/PluginBaseTest.php
index 4b57bd5..c514727 100644
--- a/core/modules/views/tests/src/Unit/PluginBaseTest.php
+++ b/core/modules/views/tests/src/Unit/PluginBaseTest.php
@@ -285,4 +285,38 @@ public function providerTestSetOptionDefault() {
     return $test_parameters;
   }
 
+  /**
+   * Tests filterByDefinedOptions().
+   *
+   * @dataProvider providerTestFilterByDefinedOptions
+   */
+  public function testFilterByDefinedOptions($storage, $options, $expected_storage) {
+    $this->testHelperPlugin->filterByDefinedOptions($storage, $options);
+    $this->assertEquals($expected_storage, $storage);
+  }
+
+  public function providerTestFilterByDefinedOptions() {
+    $data = [];
+
+    // A simple defined option.
+    $values_1 = ['key1' => 'value1'];
+    $options_1 = ['key1' => ['default' => '']];
+    $data[] = [$values_1, $options_1, $values_1];
+    // Multiple defined options .
+    $values_2 = ['key1' => 'value1', 'key2' => 'value2'];
+    $options_2 = ['key1' => ['default' => ''], 'key2' => ['default' => '']];
+    $data[] = [$values_2, $options_2, $values_2];
+
+    // Multiple options, just one defined.
+    $data[] = [$values_2, $options_1, $values_1];
+
+    // Nested options, all properly defined.
+    $data[] = [['sub1' => $values_2, 'sub2' => $values_2], ['sub1' => ['contains' => $options_2], 'sub2' => ['contains' => $options_2]], ['sub1' => $values_2, 'sub2' => $values_2]];
+
+    // Nested options, not all properly defined.
+    $data[] = [['sub1' => $values_2, 'sub2' => $values_2], ['sub1' => ['contains' => $options_2], 'sub2' => ['contains' => $options_1]], ['sub1' => $values_2, 'sub2' => $values_1]];
+
+    return $data;
+  }
+
 }
diff --git a/core/modules/views_ui/src/Tests/DisplayCRUDTest.php b/core/modules/views_ui/src/Tests/DisplayCRUDTest.php
index c2dfd84..4f1d2e2 100644
--- a/core/modules/views_ui/src/Tests/DisplayCRUDTest.php
+++ b/core/modules/views_ui/src/Tests/DisplayCRUDTest.php
@@ -17,17 +17,6 @@
 class DisplayCRUDTest extends UITestBase {
 
   /**
-   * Set to TRUE to strict check all configuration saved.
-   *
-   * @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
-   *
-   * @todo https://www.drupal.org/node/2387157
-   *
-   * @var bool
-   */
-  protected $strictConfigSchema = FALSE;
-
-  /**
    * Views used by this test.
    *
    * @var array
@@ -114,6 +103,7 @@ public function testDefaultDisplay() {
   public function testDuplicateDisplay() {
     $view = $this->randomView();
     $path_prefix = 'admin/structure/views/view/' . $view['id'] .'/edit';
+    $path = $view['page[path]'];
 
     $this->drupalGet($path_prefix);
     $this->drupalPostForm(NULL, array(), 'Duplicate Page');
@@ -140,10 +130,12 @@ public function testDuplicateDisplay() {
     $page_2 = $view->displayHandlers->get('page_2');
     $this->assertTrue($page_2, 'The new page display got saved.');
     $this->assertEqual($page_2->display['display_title'], 'Page');
+    $this->assertEqual($page_2->display['display_options']['path'], $path);
     $block_1 = $view->displayHandlers->get('block_1');
     $this->assertTrue($block_1, 'The new block display got saved.');
     $this->assertEqual($block_1->display['display_plugin'], 'block');
     $this->assertEqual($block_1->display['display_title'], 'Block', 'The new display title got generated as expected.');
+    $this->assertFalse(isset($block_1->display['display_options']['path']));
     $this->assertEqual($block_1->getOption('title'), $random_title, 'The overridden title option from the display got copied into the duplicate');
     $this->assertEqual($block_1->getOption('css_class'), $random_css, 'The overridden css_class option from the display got copied into the duplicate');
   }
diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php
index 7800580..c9d8955 100644
--- a/core/modules/views_ui/src/ViewEditForm.php
+++ b/core/modules/views_ui/src/ViewEditForm.php
@@ -855,25 +855,15 @@ public function submitDisplayAdd($form, FormStateInterface $form_state) {
    * Submit handler to Duplicate a display as another display type.
    */
   public function submitDuplicateDisplayAsType($form, FormStateInterface $form_state) {
+    /** @var \Drupal\views\ViewStorageInterface $view */
     $view = $this->entity;
     $display_id = $this->displayID;
 
     // Create the new display.
     $parents = $form_state->getTriggeringElement()['#parents'];
     $display_type = array_pop($parents);
-    $display = $view->getExecutable()->newDisplay($display_type);
-    $new_display_id = $display->display['id'];
-    $displays = $view->get('display');
 
-    // Let the display title be generated by the addDisplay method and set the
-    // right display plugin, but keep the rest from the original display.
-    $display_duplicate = $displays[$display_id];
-    unset($display_duplicate['display_title']);
-    unset($display_duplicate['display_plugin']);
-
-    $displays[$new_display_id] = NestedArray::mergeDeep($displays[$new_display_id], $display_duplicate);
-    $displays[$new_display_id]['id'] = $new_display_id;
-    $view->set('display', $displays);
+    $new_display_id = $view->duplicateDisplayAsType($display_id, $display_type);
 
     // By setting the current display the changed marker will appear on the new
     // display.
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 9716499..4a08788 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -1074,6 +1074,20 @@ public static function postLoad(EntityStorageInterface $storage, array &$entitie
   /**
    * {@inheritdoc}
    */
+  public function getExecutable() {
+    return $this->storage->getExecutable();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function duplicateDisplayAsType($old_display_id, $new_display_type) {
+    return $this->storage->duplicateDisplayAsType($old_display_id, $new_display_type);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function mergeDefaultDisplaysOptions() {
     $this->storage->mergeDefaultDisplaysOptions();
   }
