diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index 51ade6c..e10cc91 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -203,22 +203,24 @@ public function clear($key) {
   /**
    * {@inheritdoc}
    */
-  public function save() {
+  public function save($trusted_data = FALSE) {
     // Validate the configuration object name before saving.
     static::validateName($this->name);
 
     // If there is a schema for this configuration object, cast all values to
     // conform to the schema.
-    if ($this->typedConfigManager->hasConfigSchema($this->name)) {
-      // Ensure that the schema wrapper has the latest data.
-      $this->schemaWrapper = NULL;
-      foreach ($this->data as $key => $value) {
-        $this->data[$key] = $this->castValue($key, $value);
+    if (!$trusted_data) {
+      if ($this->typedConfigManager->hasConfigSchema($this->name)) {
+        // Ensure that the schema wrapper has the latest data.
+        $this->schemaWrapper = NULL;
+        foreach ($this->data as $key => $value) {
+          $this->data[$key] = $this->castValue($key, $value);
+        }
       }
-    }
-    else {
-      foreach ($this->data as $key => $value) {
-        $this->validateValue($key, $value);
+      else {
+        foreach ($this->data as $key => $value) {
+          $this->validateValue($key, $value);
+        }
       }
     }
 
@@ -302,4 +304,5 @@ public function getOriginal($key = '', $apply_overrides = TRUE) {
       }
     }
   }
+
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php
index 8065613..7b10e0b 100644
--- a/core/lib/Drupal/Core/Config/ConfigInstaller.php
+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -233,11 +233,11 @@ protected function createConfiguration($collection, array $config_to_install) {
           $entity = $entity_storage->createFromStorageRecord($new_config->get());
         }
         if ($entity->isInstallable()) {
-          $entity->save();
+          $entity->setTrustedData()->save();
         }
       }
       else {
-        $new_config->save();
+        $new_config->save(TRUE);
       }
     }
   }
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
index e1242c6..6f692dd 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -96,6 +96,8 @@
    */
   protected $third_party_settings = array();
 
+  protected $trustedData = FALSE;
+
   /**
    * Overrides Entity::__construct().
    */
@@ -315,7 +317,7 @@ public function preSave(EntityStorageInterface $storage) {
         throw new ConfigDuplicateUUIDException(String::format('Attempt to save a configuration entity %id with UUID %uuid when this entity already exists with UUID %original_uuid', array('%id' => $this->id(), '%uuid' => $this->uuid(), '%original_uuid' => $original->uuid())));
       }
     }
-    if (!$this->isSyncing()) {
+    if (!$this->isSyncing() && !$this->trustedData) {
       // Ensure the correct dependencies are present. If the configuration is
       // being written during a configuration synchronization then there is no
       // need to recalculate the dependencies.
@@ -559,4 +561,28 @@ public function isInstallable() {
     return TRUE;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function setTrustedData() {
+    $this->trustedData = TRUE;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTrustedData() {
+    return $this->trustedData;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save() {
+    $return = parent::save();
+    $this->trustedData = FALSE;
+    return $return;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
index 235581d..6df6127 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
@@ -203,4 +203,25 @@ public function getDependencies();
    */
   public function isInstallable();
 
+  /**
+   * Sets that the data should be trusted.
+   *
+   * @param bool $trust
+   *   TRUE if the configuration data is trusted, FALSE if not. If the data is
+   *   trusted then dependencies will not be calculated on save and schema will
+   *   not be used to cast the values. Generally this is only used during module
+   *   and theme installation.
+   *
+   * @return $this
+   */
+  public function setTrustedData();
+
+  /**
+   * Gets whether on not the data is trusted.
+   *
+   * @return bool
+   *   TRUE if the configuration data is trusted, FALSE if not.
+   */
+  public function getTrustedData();
+
 }
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
index 1527ac6..ff0df4c 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
@@ -256,7 +256,7 @@ protected function doSave($id, EntityInterface $entity) {
 
     // Retrieve the desired properties and set them in config.
     $config->setData($this->mapToStorageRecord($entity));
-    $config->save();
+    $config->save($entity->getTrustedData());
 
     return $is_new ? SAVED_NEW : SAVED_UPDATED;
   }
diff --git a/core/lib/Drupal/Core/Config/ImmutableConfig.php b/core/lib/Drupal/Core/Config/ImmutableConfig.php
index 61e7fdd..af7d140 100644
--- a/core/lib/Drupal/Core/Config/ImmutableConfig.php
+++ b/core/lib/Drupal/Core/Config/ImmutableConfig.php
@@ -44,7 +44,7 @@ public function clear($key) {
   /**
    * {@inheritdoc}
    */
-  public function save() {
+  public function save($trusted_data = FALSE) {
     throw new ImmutableConfigException(String::format('Can not save immutable configuration !name. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object', ['!name' => $this->getName()]));
   }
 
diff --git a/core/lib/Drupal/Core/Config/StorableConfigBase.php b/core/lib/Drupal/Core/Config/StorableConfigBase.php
index 4af470e..101f5b6 100644
--- a/core/lib/Drupal/Core/Config/StorableConfigBase.php
+++ b/core/lib/Drupal/Core/Config/StorableConfigBase.php
@@ -66,11 +66,16 @@
   /**
    * Saves the configuration object.
    *
+   * @param bool $trusted_data
+   *   Set to TRUE is the configuration has already been checked that it
+   *   conforms to schema. Generally this is only used during module and theme
+   *   installation.
+   *
    * Must invalidate the cache tags associated with the configuration object.
    *
    * @return $this
    */
-  abstract public function save();
+  abstract public function save($trusted_data = FALSE);
 
   /**
    * Deletes the configuration object.
@@ -219,4 +224,17 @@ protected function castValue($key, $value) {
     return $value;
   }
 
+  /**
+   * Indicates that the configuration data is trusted.
+   *
+   * If the configuration data is trusted then we don't need to check schema on
+   * save.
+   *
+   * @return $this
+   */
+  public function setTrustedData() {
+    $this->trustedData = TRUE;
+    return $this;
+  }
+
 }
diff --git a/core/modules/book/config/install/node.type.book.yml b/core/modules/book/config/install/node.type.book.yml
index 1a5cc16..a5076b2 100644
--- a/core/modules/book/config/install/node.type.book.yml
+++ b/core/modules/book/config/install/node.type.book.yml
@@ -1,6 +1,8 @@
 langcode: en
 status: true
 dependencies:
+  module:
+    - book
   enforced:
     module:
       - book
diff --git a/core/modules/config/src/Tests/ConfigInstallTest.php b/core/modules/config/src/Tests/ConfigInstallTest.php
index 2da9e53..2ea3b90 100644
--- a/core/modules/config/src/Tests/ConfigInstallTest.php
+++ b/core/modules/config/src/Tests/ConfigInstallTest.php
@@ -45,14 +45,14 @@ function testModuleInstallation() {
 
     // Ensure that schema provided by modules that are not installed is not
     // available.
-    $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install does not exist.');
+    $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
 
     // Install the test module.
     $this->enableModules(array('config_test', 'config_schema_test'));
     $this->installConfig(array('config_test', 'config_schema_test'));
 
     // After module installation the new schema should exist.
-    $this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install exists.');
+    $this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema exists.');
 
     // Verify that default module config exists.
     \Drupal::configFactory()->reset($default_config);
@@ -71,14 +71,10 @@ function testModuleInstallation() {
     $this->assertFalse(isset($GLOBALS['hook_config_test']['predelete']));
     $this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
 
-    // Ensure that data type casting is applied during config installation.
-    $config = $this->config('config_schema_test.schema_in_install');
-    $this->assertIdentical($config->get('integer'), 1);
-
     // Test that uninstalling configuration removes configuration schema.
     $this->config('core.extension')->set('module', array())->save();
     \Drupal::service('config.manager')->uninstall('module', 'config_test');
-    $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install does not exist.');
+    $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
   }
 
   /**
diff --git a/core/modules/config/tests/config_schema_test/config/install/config_schema_test.schema_in_install.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.schema_in_install.yml
deleted file mode 100644
index 2ae0ace..0000000
--- a/core/modules/config/tests/config_schema_test/config/install/config_schema_test.schema_in_install.yml
+++ /dev/null
@@ -1 +0,0 @@
-integer: '1'
diff --git a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
index 8c8660c..a2da749 100644
--- a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
+++ b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
@@ -121,14 +121,6 @@ config_schema_test.schema_data_types:
       sequence:
         - type: boolean
 
-config_schema_test.schema_in_install:
-  label: 'Schema test data with parenting'
-  type: mapping
-  mapping:
-    integer:
-      type: integer
-      label: 'Integer'
-
 config_schema_test_integer:
   type: integer
   label: 'Config test integer'
diff --git a/core/modules/config/tests/config_test/config/install/config_test.types.yml b/core/modules/config/tests/config_test/config/install/config_test.types.yml
index 060a2b0..6c27522 100644
--- a/core/modules/config/tests/config_test/config/install/config_test.types.yml
+++ b/core/modules/config/tests/config_test/config/install/config_test.types.yml
@@ -2,7 +2,7 @@ array: []
 boolean: true
 exp: 1.2e+34
 float: 3.14159
-float_as_integer: 1
+float_as_integer: !!float 1
 hex: 0xC
 int: 99
 octal: 0775
diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module
index 110a6e4..85c5f74 100644
--- a/core/modules/contact/contact.module
+++ b/core/modules/contact/contact.module
@@ -24,8 +24,10 @@ function contact_help($route_name, RouteMatchInterface $route_match) {
       $output .= '<dd>' . t('Site users can be contacted with a user contact form that keeps their email address private. Users may enable or disable their personal contact forms by editing their <em>My account</em> page. If enabled, a <em>Contact</em> tab leads to a personal contact form displayed on their user profile. Site administrators are still able to use the contact form, even if has been disabled. The <em>Contact</em> tab is not shown when you view your own profile.') . '</dd>';
       $output .= '<dt>' . t('Site-wide contact forms') . '</dt>';
       $output .= '<dd>' . t('The <a href="@contact">Contact page</a> provides a simple form for users with the <em>Use the site-wide contact form</em> permission to send comments, feedback, or other requests. You can create forms for directing the contact messages to a set of defined recipients. Common forms for a business site, for example, might include "Website feedback" (messages are forwarded to website administrators) and "Product information" (messages are forwarded to members of the sales department). Email addresses defined within a form are not displayed publicly.', array('@contact' => \Drupal::url('contact.site_page'))) . '</p>';
-      $output .= '<dt>' . t('Navigation') . '</dt>';
-      $output .= '<dd>' . t('When the site-wide contact form is enabled, a link in the <em>Footer</em> menu is created, which you can modify on the <a href="@menu">Menus administration page</a>.', array('@menu' => \Drupal::url('entity.menu.collection'))) . '</dd>';
+      if (\Drupal::moduleHandler()->moduleExists('menu_ui')) {
+        $output .= '<dt>' . t('Navigation') . '</dt>';
+        $output .= '<dd>' . t('When the site-wide contact form is enabled, a link in the <em>Footer</em> menu is created, which you can modify on the <a href="@menu">Menus administration page</a>.', array('@menu' => \Drupal::url('entity.menu.collection'))) . '</dd>';
+      }
       $output .= '<dt>' . t('Customization') . '</dt>';
       $output .= '<dd>' . t('If you would like additional text to appear on the site-wide or personal contact page, use a block. You can create and edit blocks on the <a href="@blocks">Blocks administration page</a>.', array('@blocks' => \Drupal::url('block.admin_display'))) . '</dd>';
       $output .= '</dl>';
@@ -33,7 +35,9 @@ function contact_help($route_name, RouteMatchInterface $route_match) {
 
     case 'entity.contact_form.collection':
       $output = '<p>' . t('Add one or more forms on this page to set up your site-wide <a href="@form">contact form</a>.', array('@form' => \Drupal::url('contact.site_page'))) . '</p>';
-      $output .= '<p>' . t('A <em>Contact</em> menu item is added to the <em>Footer</em> menu, which you can modify on the <a href="@menu-settings">Menus administration page</a>.', array('@menu-settings' => \Drupal::url('entity.menu.collection'))) . '</p>';
+      if (\Drupal::moduleHandler()->moduleExists('menu_ui')) {
+        $output .= '<p>' . t('A <em>Contact</em> menu item is added to the <em>Footer</em> menu, which you can modify on the <a href="@menu-settings">Menus administration page</a>.', array('@menu-settings' => \Drupal::url('entity.menu.collection'))) . '</p>';
+      }
       $output .= '<p>' . t('If you would like additional text to appear on the site-wide contact page, use a block. You can create and edit blocks on the <a href="@blocks">Blocks administration page</a>.', array('@blocks' => \Drupal::url('block.admin_display'))) . '</p>';
       return $output;
   }
diff --git a/core/modules/forum/config/install/node.type.forum.yml b/core/modules/forum/config/install/node.type.forum.yml
index 8ed965d..b03afe0 100644
--- a/core/modules/forum/config/install/node.type.forum.yml
+++ b/core/modules/forum/config/install/node.type.forum.yml
@@ -1,6 +1,8 @@
 langcode: en
 status: true
 dependencies:
+  module:
+    - forum
   enforced:
     module:
       - forum
diff --git a/core/modules/forum/config/install/taxonomy.vocabulary.forums.yml b/core/modules/forum/config/install/taxonomy.vocabulary.forums.yml
index 951e4a3..cfbcca5 100644
--- a/core/modules/forum/config/install/taxonomy.vocabulary.forums.yml
+++ b/core/modules/forum/config/install/taxonomy.vocabulary.forums.yml
@@ -1,6 +1,8 @@
 langcode: en
 status: true
 dependencies:
+  module:
+    - forum
   enforced:
     module:
       - forum
diff --git a/core/modules/language/src/Config/LanguageConfigOverride.php b/core/modules/language/src/Config/LanguageConfigOverride.php
index 5be48ad..c66f3b9 100644
--- a/core/modules/language/src/Config/LanguageConfigOverride.php
+++ b/core/modules/language/src/Config/LanguageConfigOverride.php
@@ -50,13 +50,16 @@ public function __construct($name, StorageInterface $storage, TypedConfigManager
   /**
    * {@inheritdoc}
    */
-  public function save() {
-    // @todo Use configuration schema to validate.
-    //   https://drupal.org/node/2270399
-    // Perform basic data validation.
-    foreach ($this->data as $key => $value) {
-      $this->validateValue($key, $value);
+  public function save($trusted_data = FALSE) {
+    if (!$trusted_data) {
+      // @todo Use configuration schema to validate.
+      //   https://drupal.org/node/2270399
+      // Perform basic data validation.
+      foreach ($this->data as $key => $value) {
+        $this->validateValue($key, $value);
+      }
     }
+
     $this->storage->write($this->name, $this->data);
     // Invalidate the cache tags not only when updating, but also when creating,
     // because a language config override object uses the same cache tag as the
diff --git a/core/modules/node/config/install/system.action.node_promote_action.yml b/core/modules/node/config/install/system.action.node_promote_action.yml
index b1b4f05..4b3a9ae 100644
--- a/core/modules/node/config/install/system.action.node_promote_action.yml
+++ b/core/modules/node/config/install/system.action.node_promote_action.yml
@@ -4,3 +4,6 @@ status: true
 langcode: en
 type: node
 plugin: node_promote_action
+dependencies:
+  module:
+    - node
diff --git a/core/modules/node/config/install/system.action.node_publish_action.yml b/core/modules/node/config/install/system.action.node_publish_action.yml
index e882bf3..af0b82c 100644
--- a/core/modules/node/config/install/system.action.node_publish_action.yml
+++ b/core/modules/node/config/install/system.action.node_publish_action.yml
@@ -4,3 +4,6 @@ status: true
 langcode: en
 type: node
 plugin: node_publish_action
+dependencies:
+  module:
+    - node
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
index 160dce0..5577ddf 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
@@ -109,4 +109,11 @@ public static function simplifyAllowedValues(array $structured_values) {
     return $values;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected static function castAllowedValue($value) {
+    return (float) $value;
+  }
+
 }
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
index afda838..d61c86e 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
@@ -72,4 +72,11 @@ protected static function validateAllowedValue($option) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected static function castAllowedValue($value) {
+    return (int) $value;
+  }
+
 }
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
index bdf063a..9b785d8 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
@@ -314,11 +314,24 @@ protected static function structureAllowedValues(array $values) {
         $label = static::structureAllowedValues($label);
       }
       $structured_values[] = array(
-        'value' => $value,
+        'value' => static::castAllowedValue($value),
         'label' => $label,
       );
     }
     return $structured_values;
   }
 
+  /**
+   * Converts a value to the correct type.
+   *
+   * @param mixed $value
+   *   The value to cast.
+   *
+   * @return mixed
+   *   The casted value.
+   */
+  protected static function castAllowedValue($value) {
+    return $value;
+  }
+
 }
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
index a95c8e8..37c219b 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
@@ -74,4 +74,11 @@ protected static function validateAllowedValue($option) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected static function castAllowedValue($value) {
+    return (string) $value;
+  }
+
 }
diff --git a/core/modules/options/tests/options_config_install_test/config/install/field.storage.node.field_options_float.yml b/core/modules/options/tests/options_config_install_test/config/install/field.storage.node.field_options_float.yml
index f355b2e..1d02c61 100644
--- a/core/modules/options/tests/options_config_install_test/config/install/field.storage.node.field_options_float.yml
+++ b/core/modules/options/tests/options_config_install_test/config/install/field.storage.node.field_options_float.yml
@@ -11,7 +11,7 @@ type: list_float
 settings:
   allowed_values:
     -
-      value: 0
+      value: !!float 0
       label: Zero
     -
       value: 0.5
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 1d3c8be..cb1d321 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -11,6 +11,7 @@
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Timer;
 use Drupal\Component\Utility\Xss;
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
 use Drupal\views\Views;
@@ -1252,4 +1253,18 @@ public function isInstallable() {
     return $this->storage->isInstallable();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function setTrustedData() {
+    return $this->storage->setTrustedData();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTrustedData() {
+    return $this->storage->getTrustedData();
+  }
+
 }
