diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 6270c8e..d687f2b 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -1092,4 +1092,11 @@ public function getModuleDirectories() {
     return $dirs;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getName($module) {
+    $module_data = system_rebuild_module_data();
+    return $module_data[$module]->info['name'];
+  }
 }
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
index 97250aa..48b5760 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
@@ -346,4 +346,15 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE);
    */
   public function getModuleDirectories();
 
+  /**
+   * Gets the human readable name of a given module.
+   *
+   * @param string $module
+   *   The machine name of the module which title should be shown.
+   *
+   * @return string
+   *   Returns the human readable name of the module.
+   */
+  public function getName($theme);
+
 }
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php
index e1b8cbf..2231ca8 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandler.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -664,4 +664,22 @@ protected function systemThemeList() {
     return system_list('theme');
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getThemeDirectories() {
+    $dirs = array();
+    foreach ($this->listInfo() as $name => $theme) {
+      $dirs[$name] = DRUPAL_ROOT . '/' . $theme->getPath();
+    }
+    return $dirs;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function themeExists($theme) {
+    $themes = $this->listInfo();
+    return isset($themes[$theme]);
+  }
 }
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php b/core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php
index da3a6cf..6a3ba66 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php
@@ -131,4 +131,25 @@ public function getBaseThemes(array $themes, $theme);
    */
   public function getName($theme);
 
+  /**
+   * Returns an array of directories for all enabled themes.
+   *
+   * Useful for tasks such as finding a file that exists in all theme
+   * directories.
+   *
+   * @return array
+   */
+  public function getThemeDirectories();
+
+  /**
+   * Determines whether a given theme is enabled.
+   *
+   * @param string $theme
+   *   The name of the theme (without the .module extension).
+   *
+   * @return bool
+   *   TRUE if the theme is both installed and enabled.
+   */
+  public function themeExists($theme);
+
 }
diff --git a/core/modules/breakpoint/breakpoint.module b/core/modules/breakpoint/breakpoint.module
index 6f69efc..4ce64d5 100644
--- a/core/modules/breakpoint/breakpoint.module
+++ b/core/modules/breakpoint/breakpoint.module
@@ -5,9 +5,6 @@
  * Manage breakpoints and breakpoint groups for responsive designs.
  */
 
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\Core\Config\Entity\ConfigEntityStorage;
 use Drupal\Core\Routing\RouteMatchInterface;
 
 /**
@@ -40,33 +37,29 @@ function breakpoint_help($route_name, RouteMatchInterface $route_match) {
 }
 
 /**
- * Load all breakpoint groups as select options.
- *
- * @return array
- *   An array containing breakpoint group labels indexed by their ids.
+ * Implements hook_modules_installed().
  */
-function breakpoint_group_select_options() {
-  $options = array();
-  $breakpoint_groups = BreakpointGroup::loadMultiple();
-  foreach ($breakpoint_groups as $breakpoint_group) {
-    $options[$breakpoint_group->id()] = $breakpoint_group->label();
-  }
-  asort($options);
-  return $options;
+function breakpoint_modules_installed($installed_modules) {
+  \Drupal::service('breakpoint.manager')->clearCachedDefinitions();
 }
 
 /**
- * Load all breakpoints as select options.
- *
- * @return array
- *   An array containing breakpoints indexed by their ids.
+ * Implements hook_modules_uninstalled().
  */
-function breakpoint_select_options() {
-  $options = array();
-  $breakpoints = Breakpoint::loadMultiple();
-  foreach ($breakpoints as $breakpoint) {
-    $options[$breakpoint->id()] = $breakpoint->label() . ' (' . $breakpoint->source . ' - ' . $breakpoint->sourceType . ') [' . $breakpoint->mediaQuery . ']';
-  }
-  asort($options);
-  return $options;
+function breakpoint_modules_uninstalled($uninstalled_modules) {
+  \Drupal::service('breakpoint.manager')->clearCachedDefinitions();
+}
+
+/**
+ * Implements hook_themes_enabled()
+ */
+function breakpoint_themes_enabled($theme_list) {
+  \Drupal::service('breakpoint.manager')->clearCachedDefinitions();
+}
+
+/**
+ * Implements hook_themes_disabled()
+ */
+function breakpoint_themes_disabled($theme_list) {
+  \Drupal::service('breakpoint.manager')->clearCachedDefinitions();
 }
diff --git a/core/modules/breakpoint/breakpoint.services.yml b/core/modules/breakpoint/breakpoint.services.yml
new file mode 100644
index 0000000..f5187fc
--- /dev/null
+++ b/core/modules/breakpoint/breakpoint.services.yml
@@ -0,0 +1,6 @@
+services:
+  breakpoint.manager:
+    class: Drupal\breakpoint\BreakpointManager
+    arguments: ['@module_handler', '@theme_handler', '@cache.discovery', '@language_manager']
+    tags:
+      - { name: plugin_manager_cache_clear }
diff --git a/core/modules/breakpoint/config/schema/breakpoint.schema.yml b/core/modules/breakpoint/config/schema/breakpoint.schema.yml
deleted file mode 100644
index c44ef4c..0000000
--- a/core/modules/breakpoint/config/schema/breakpoint.schema.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-# Schema for the configuration files of the Breakpoint module.
-breakpoint.breakpoint.*.*.*:
-  type: config_entity
-  label: 'Defines the Breakpoint entity'
-  mapping:
-    id:
-      type: string
-      label: 'ID'
-    label:
-      type: label
-      label: 'Label'
-    name:
-      type: string
-      label: 'Machine name'
-    mediaQuery:
-      type: string
-      label: 'Media query'
-    source:
-      type: string
-      label: 'Source'
-    sourceType:
-      type: string
-      label: 'Source type'
-    weight:
-      type: integer
-      label: 'Weight'
-    multipliers:
-      type: sequence
-      label: 'Multipliers'
-      sequence:
-        - type: string
-          label: 'Multiplier'
-
-breakpoint.breakpoint_group.*.*.*:
-  type: config_entity
-  label: 'Breakpoint group settings'
-  mapping:
-    id:
-      type: string
-      label: 'ID'
-    label:
-      type: label
-      label: 'Label'
-    name:
-      type: string
-      label: 'Machine name'
-    breakpoint_ids:
-      type: sequence
-      label: 'Breakpoints'
-      sequence:
-        - type: string
-          label: 'Breakpoint name'
-    source:
-      type: string
-      label: 'Group source: theme or module name'
-    sourceType:
-      type: string
-      label: 'Group source type'
diff --git a/core/modules/breakpoint/src/BreakpointGroupInterface.php b/core/modules/breakpoint/src/BreakpointGroupInterface.php
deleted file mode 100644
index ae4f2e9..0000000
--- a/core/modules/breakpoint/src/BreakpointGroupInterface.php
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\breakpoint\Entity\BreakpointGroupInterface.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-
-/**
- * Provides an interface defining a breakpoint group entity.
- */
-interface BreakpointGroupInterface extends ConfigEntityInterface {
-
-  /**
-   * Checks if the breakpoint group is valid.
-   *
-   * @throws \Drupal\breakpoint\InvalidBreakpointSourceTypeException
-   * @throws \Drupal\breakpoint\InvalidBreakpointSourceException
-   *
-   * @return bool
-   *   Returns TRUE if the breakpoint group is valid.
-   */
-  public function isValid();
-
-  /**
-   * Adds a breakpoint using a name and a media query.
-   *
-   * @param string $name
-   *   The name of the breakpoint.
-   * @param string $media_query
-   *   Media query.
-   */
-  public function addBreakpointFromMediaQuery($name, $media_query);
-
-  /**
-   * Adds one or more breakpoints to this group.
-   *
-   * The breakpoint name is either the machine_name or the ID of a breakpoint.
-   *
-   * @param array $breakpoints
-   *   Array containing breakpoint objects
-   *
-   * @return \Drupal\breakpoint\Entity\BreakpointGroup
-   *   The breakpoint group object.
-   */
-  public function addBreakpoints($breakpoints);
-
-  /**
-   * Gets the array of breakpoints for the breakpoint group.
-   *
-   * @return \Drupal\breakpoint\Entity\BreakpointInterface[]
-   *   The array of breakpoints for the breakpoint group.
-   */
-  public function getBreakpoints();
-
-  /**
-   * Gets a breakpoint from the breakpoint group by ID.
-   *
-   * @param string $id
-   *   The breakpoint ID to get.
-   *
-   * @return \Drupal\breakpoint\Entity\BreakpointInterface|boolean
-   *   The breakpoint or FALSE if not in the Breakpoint group.
-   */
-  public function getBreakpointById($id);
-
-}
diff --git a/core/modules/breakpoint/src/BreakpointInterface.php b/core/modules/breakpoint/src/BreakpointInterface.php
deleted file mode 100644
index cf62bcd..0000000
--- a/core/modules/breakpoint/src/BreakpointInterface.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\breakpoint\Entity\BreakpointInterface.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-
-/**
- * Provides an interface defining a breakpoint entity.
- */
-interface BreakpointInterface extends ConfigEntityInterface {
-
-  /**
-   * Checks if the breakpoint is valid.
-   *
-   * @throws \Drupal\breakpoint\InvalidBreakpointSourceTypeException
-   * @throws \Drupal\breakpoint\InvalidBreakpointSourceException
-   * @throws \Drupal\breakpoint\InvalidBreakpointNameException
-   * @throws \Drupal\breakpoint\InvalidBreakpointMediaQueryException
-   *
-   * @see isValidMediaQuery()
-   */
-  public function isValid();
-
-  /**
-   * Checks if a mediaQuery is valid.
-   *
-   * @throws \Drupal\breakpoint\InvalidBreakpointMediaQueryException
-   *
-   * @return bool
-   *   Returns TRUE if the media query is valid.
-   *
-   * @see http://www.w3.org/TR/css3-mediaqueries/
-   * @see http://www.w3.org/Style/CSS/Test/MediaQueries/20120229/reports/implement-report.html
-   * @see https://github.com/adobe/webkit/blob/master/Source/WebCore/css/
-   */
-  public static function isValidMediaQuery($media_query);
-
-}
diff --git a/core/modules/breakpoint/src/BreakpointManager.php b/core/modules/breakpoint/src/BreakpointManager.php
new file mode 100644
index 0000000..4bdef55
--- /dev/null
+++ b/core/modules/breakpoint/src/BreakpointManager.php
@@ -0,0 +1,186 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\breakpoint\BreakpointManager.
+ */
+
+namespace Drupal\breakpoint;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Extension\ThemeHandlerInterface;
+use Drupal\Core\Language\LanguageManager;
+use Drupal\Core\Plugin\DefaultPluginManager;
+use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
+use Drupal\Core\Plugin\Discovery\YamlDiscovery;
+use Drupal\Core\Plugin\Factory\ContainerFactory;
+
+/**
+ * Defines a breakpoint plugin manager to deal with breakpoints.
+ *
+ * Extension can define breakpoints in a EXTENSION_NAME.breakpoints.yml file
+ * contained in the extension's base directory. Each breakpoint has the
+ * following structure:
+ * @code
+ *   MACHINE_NAME:
+ *     label: STRING
+ *     mediaQuery: STRING
+ *     weight: INTEGER
+ *     multipliers:
+ *       - STRING
+ * @endcode
+ * For example:
+ * @code
+ * bartik.mobile:
+ *   label: mobile
+ *   mediaQuery: '(min-width: 0px)'
+ *   weight: 0
+ *   multipliers:
+ *     - 1x
+ *     - 2x
+ * @endcode
+ * Optionally a breakpoint can provide a group key. By default an extensions
+ * breakpoints will be placed in a group labelled with the extension name.
+ */
+class BreakpointManager extends DefaultPluginManager implements BreakpointManagerInterface {
+
+  /**
+   * The theme handler.
+   *
+   * @var \Drupal\Core\Extension\ThemeHandlerInterface
+   */
+  protected $themeHandler;
+
+  /**
+   * @var array
+   */
+  protected $breakpointsByGroup;
+
+  /**
+   * Constructs a new BreakpointManager instance.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
+   *   The theme handler.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   The cache backend.
+   * @param \Drupal\Core\Language\LanguageManager $language_manager
+   *   The language manager.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, CacheBackendInterface $cache_backend, LanguageManager $language_manager) {
+    $this->discovery = new YamlDiscovery('breakpoints', $module_handler->getModuleDirectories() + $theme_handler->getThemeDirectories());
+    $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
+    $this->factory = new ContainerFactory($this);
+    $this->moduleHandler = $module_handler;
+    $this->themeHandler = $theme_handler;
+    $this->alterInfo('breakpoints');
+    $this->setCacheBackend($cache_backend, 'breakpoints:' . $language_manager->getCurrentLanguage()->getId(), array('breakpoints' => TRUE));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processDefinition(&$definition, $plugin_id) {
+    parent::processDefinition($definition, $plugin_id);
+    // Allow custom groups and therefore more than one group per extension.
+    if (!isset($definition['group'])) {
+      $definition['group'] = $definition['provider'];
+    }
+    // Ensure a 1x multiplier exists.
+    if (!isset($definition['multipliers']) || !in_array('1x', $definition['multipliers'])) {
+      $definition['multipliers'][] = '1x';
+    }
+    // Ensure that multipliers are sorted correctly.
+    sort($definition['multipliers']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function findDefinitions() {
+    $definitions = $this->discovery->getDefinitions();
+    foreach ($definitions as $plugin_id => &$definition) {
+      $this->processDefinition($definition, $plugin_id);
+    }
+    if ($this->alterHook) {
+      $this->moduleHandler->alter($this->alterHook, $definitions);
+    }
+    // If this plugin was provided by a module that does not exist, remove the
+    // plugin definition.
+    foreach ($definitions as $plugin_id => $plugin_definition) {
+      // If the plugin definition is an object, attempt to convert it to an
+      // array, if that is not possible, skip further processing.
+      if (is_object($plugin_definition) && !($plugin_definition = (array) $plugin_definition)) {
+        continue;
+      }
+      // Allow themes to provide breakpoints.
+      if (isset($plugin_definition['provider']) && !in_array($plugin_definition['provider'], array('core', 'component')) && !$this->moduleHandler->moduleExists($plugin_definition['provider']) && !$this->themeHandler->themeExists($plugin_definition['provider'])) {
+        unset($definitions[$plugin_id]);
+      }
+    }
+    return $definitions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getBreakpointsByGroup($group_name) {
+    if (!isset($this->breakpointsByGroup[$group_name])) {
+      if ($cache = $this->cacheBackend->get($this->cacheKey . ':' . $group_name)) {
+        $this->breakpointsByGroup[$group_name] = $cache->data;
+      }
+      else {
+        $breakpoints = array();
+        foreach ($this->getDefinitions() as $plugin_id => $plugin_definition) {
+          if ($plugin_definition['group'] == $group_name) {
+            $breakpoints[$plugin_id] = $plugin_definition;
+          }
+        }
+        $this->cacheBackend->set($this->cacheKey . ':' . $group_name, $breakpoints);
+        $this->breakpointsByGroup[$group_name] = $breakpoints;
+      }
+    }
+    return $this->breakpointsByGroup[$group_name];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getGroups() {
+    // Use a double colon so as to not clash with the cache for each group.
+    if ($cache = $this->cacheBackend->get($this->cacheKey . '::groups')) {
+      return $cache->data;
+    }
+    $groups = array();
+    foreach ($this->getDefinitions() as $plugin_definition) {
+      if (!isset($groups[$plugin_definition['group']])) {
+        $groups[$plugin_definition['group']] = $this->getGroupLabel($plugin_definition['group']);
+      }
+    }
+    asort($groups);
+    $this->cacheBackend->set($this->cacheKey . '::groups', $groups);
+    return $groups;
+  }
+
+  /**
+   * @param string $group
+   *
+   * @return string
+   *   The label
+   */
+  protected function getGroupLabel($group) {
+    if ($this->moduleHandler->moduleExists($group)) {
+      $label = $this->moduleHandler->getName($group);
+    }
+    elseif ($this->themeHandler->themeExists($group)) {
+      $label = $this->themeHandler->getName($group);
+    }
+    else {
+      $label = $group;
+    }
+    return $label;
+  }
+
+}
diff --git a/core/modules/breakpoint/src/BreakpointManagerInterface.php b/core/modules/breakpoint/src/BreakpointManagerInterface.php
new file mode 100644
index 0000000..2e33271
--- /dev/null
+++ b/core/modules/breakpoint/src/BreakpointManagerInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\breakpoint\BreakpointManagerInterface.
+ */
+
+namespace Drupal\breakpoint;
+
+/**
+ * Defines an interface for breakpoint managers.
+ */
+interface BreakpointManagerInterface {
+
+  /**
+   * Gets breakpoints for the specified group.
+   *
+   * @param string $group_name
+   *   The breakpoint group to retrieve.
+   *
+   * @return array
+   *   Array of breakpoints keyed by machine name.
+   */
+  public function getBreakpointsByGroup($group_name);
+
+  /**
+   * Gets all the existing breakpoint groups.
+   *
+   * @return array
+   *   Array of breakpoint group labels. Keyed by group name.
+   */
+  public function getGroups();
+
+}
diff --git a/core/modules/breakpoint/src/Entity/Breakpoint.php b/core/modules/breakpoint/src/Entity/Breakpoint.php
deleted file mode 100644
index 714e44e..0000000
--- a/core/modules/breakpoint/src/Entity/Breakpoint.php
+++ /dev/null
@@ -1,308 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\Entity\Breakpoint.
- */
-
-namespace Drupal\breakpoint\Entity;
-
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-use Drupal\breakpoint\BreakpointInterface;
-use Drupal\breakpoint\InvalidBreakpointException;
-use Drupal\breakpoint\InvalidBreakpointNameException;
-use Drupal\breakpoint\InvalidBreakpointSourceException;
-use Drupal\breakpoint\InvalidBreakpointSourceTypeException;
-use Drupal\breakpoint\InvalidBreakpointMediaQueryException;
-use Drupal\Core\Entity\EntityStorageInterface;
-
-/**
- * Defines the Breakpoint entity.
- *
- * @ConfigEntityType(
- *   id = "breakpoint",
- *   label = @Translation("Breakpoint"),
- *   entity_keys = {
- *     "id" = "id",
- *     "label" = "label"
- *   }
- * )
- */
-class Breakpoint extends ConfigEntityBase implements BreakpointInterface {
-
-  /**
-   * Denotes that a breakpoint or breakpoint group is defined by a theme.
-   */
-  const SOURCE_TYPE_THEME = 'theme';
-
-  /**
-   * Denotes that a breakpoint or breakpoint group is defined by a module.
-   */
-  const SOURCE_TYPE_MODULE = 'module';
-
-  /**
-   * Denotes that a breakpoint or breakpoint group is defined by the user.
-   */
-  const SOURCE_TYPE_USER_DEFINED = 'custom';
-
-  /**
-   * The breakpoint ID (config name).
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The breakpoint name (machine name) as specified by theme or module.
-   *
-   * @var string
-   */
-  public $name;
-
-  /**
-   * The breakpoint label.
-   *
-   * @var string
-   */
-  public $label;
-
-  /**
-   * The breakpoint media query.
-   *
-   * @var string
-   */
-  public $mediaQuery = '';
-
-  /**
-   * The breakpoint source.
-   *
-   * @var string
-   */
-  public $source = 'user';
-
-  /**
-   * The breakpoint source type.
-   *
-   * @var string
-   *   Allowed values:
-   *     Breakpoint::SOURCE_TYPE_THEME
-   *     Breakpoint::SOURCE_TYPE_MODULE
-   *     Breakpoint::SOURCE_TYPE_USER_DEFINED
-   */
-  public $sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
-
-  /**
-   * The breakpoint weight.
-   *
-   * @var weight
-   */
-  public $weight = 0;
-
-  /**
-   * The breakpoint multipliers.
-   *
-   * @var multipliers
-   */
-  public $multipliers = array();
-
-  /**
-   * {@inheritdoc}
-   *
-   * @throws \Drupal\breakpoint\InvalidBreakpointNameException
-   *   Exception thrown if $values['name'] is empty.
-   */
-  public function __construct(array $values, $entity_type = 'breakpoint') {
-    // Check required properties.
-    if (empty($values['name'])) {
-      throw new InvalidBreakpointNameException('Attempt to create an unnamed breakpoint.');
-    }
-    parent::__construct($values, $entity_type);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function id() {
-    // If no ID is specified, build one from the properties that uniquely define
-    // this breakpoint.
-    if (!isset($this->id)) {
-      $this->id = $this->sourceType . '.' . $this->source . '.' . $this->name;
-    }
-    return $this->id;
-  }
-
-  /**
-   * Overrides Drupal\config\ConfigEntityBase::save().
-   */
-  public function save() {
-    // Check if everything is valid.
-    if (!$this->isValid()) {
-      throw new InvalidBreakpointException('Invalid data detected.');
-    }
-
-    // Set the label if none is set.
-    if (empty($this->label)) {
-      $this->label = $this->name;
-    }
-
-    // Remove unused multipliers.
-    $this->multipliers = array_filter($this->multipliers);
-
-    // Always add '1x' multiplier, use array_key_exists since the value might
-    // be NULL.
-    if (!array_key_exists('1x', $this->multipliers)) {
-      $this->multipliers = array('1x' => '1x') + $this->multipliers;
-    }
-    return parent::save();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isValid() {
-    // Check for illegal values in breakpoint source type.
-    if (!in_array($this->sourceType, array(
-        Breakpoint::SOURCE_TYPE_USER_DEFINED,
-        Breakpoint::SOURCE_TYPE_MODULE,
-        Breakpoint::SOURCE_TYPE_THEME)
-      )) {
-      throw new InvalidBreakpointSourceTypeException(format_string('Invalid source type @source_type', array(
-        '@source_type' => $this->sourceType,
-      )));
-    }
-    // Check for illegal characters in breakpoint source.
-    if (preg_match('/[^0-9a-z_]+/', $this->source)) {
-      throw new InvalidBreakpointSourceException(format_string("Invalid value '@source' for breakpoint source property. Breakpoint source property can only contain lowercase alphanumeric characters and underscores.", array('@source' => $this->source)));
-    }
-    // Check for illegal characters in breakpoint names.
-    if (preg_match('/[^0-9a-z_\-]/', $this->name)) {
-      throw new InvalidBreakpointNameException(format_string("Invalid value '@name' for breakpoint name property. Breakpoint name property can only contain lowercase alphanumeric characters, underscores (_), and hyphens (-).", array('@name' => $this->name)));
-    }
-    return $this::isValidMediaQuery($this->mediaQuery);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function isValidMediaQuery($media_query) {
-    // Array describing all known media features and the expected value type or
-    // an array containing the allowed values.
-    $media_features = array(
-      'width' => 'length', 'min-width' => 'length', 'max-width' => 'length',
-      'height' => 'length', 'min-height' => 'length', 'max-height' => 'length',
-      'device-width' => 'length', 'min-device-width' => 'length', 'max-device-width' => 'length',
-      'device-height' => 'length', 'min-device-height' => 'length', 'max-device-height' => 'length',
-      'orientation' => array('portrait', 'landscape'),
-      'aspect-ratio' => 'ratio', 'min-aspect-ratio' => 'ratio', 'max-aspect-ratio' => 'ratio',
-      'device-aspect-ratio' => 'ratio', 'min-device-aspect-ratio' => 'ratio', 'max-device-aspect-ratio' => 'ratio',
-      'color' => 'integer', 'min-color' => 'integer', 'max-color' => 'integer',
-      'color-index' => 'integer', 'min-color-index' => 'integer', 'max-color-index' => 'integer',
-      'monochrome' => 'integer', 'min-monochrome' => 'integer', 'max-monochrome' => 'integer',
-      'resolution' => 'resolution', 'min-resolution' => 'resolution', 'max-resolution' => 'resolution',
-      'scan' => array('progressive', 'interlace'),
-      'grid' => 'integer',
-    );
-    if ($media_query) {
-      // Strip new lines and trim.
-      $media_query = str_replace(array("\r", "\n"), ' ', trim($media_query));
-
-      // Remove comments /* ... */.
-      $media_query = preg_replace('/\/\*[\s\S]*?\*\//', '', $media_query);
-
-      // Check media list.
-      $parts = explode(',', $media_query);
-      foreach ($parts as $part) {
-        // Split on ' and '
-        $query_parts = explode(' and ', trim($part));
-        $media_type_found = FALSE;
-        foreach ($query_parts as $query_part) {
-          $matches = array();
-          // Try to match: '(media_feature: value)' and variants.
-          if (preg_match('/^\(([\w\-]+)(:\s?([\w\-\.]+))?\)/', trim($query_part), $matches)) {
-            // Single expression like '(color)'.
-            if (isset($matches[1]) && !isset($matches[2])) {
-              if (!array_key_exists($matches[1], $media_features)) {
-                throw new InvalidBreakpointMediaQueryException('Invalid media feature detected.');
-              }
-            }
-            // Full expression like '(min-width: 20em)'.
-            elseif (isset($matches[3]) && !isset($matches[4])) {
-              $value = trim($matches[3]);
-              if (!array_key_exists($matches[1], $media_features)) {
-                // We need to allow vendor prefixed media features and make sure
-                // we are future proof, so only check allowed characters.
-                if (!preg_match('/^[a-zA-Z0-9\:\-\\ ]+$/i', trim($matches[1]))) {
-                  throw new InvalidBreakpointMediaQueryException('Invalid media query detected.');
-                }
-              }
-              elseif (is_array($media_features[$matches[1]])) {
-                // Check if value is allowed.
-                if (!array_key_exists($value, $media_features[$matches[1]])) {
-                  throw new InvalidBreakpointMediaQueryException('Value is not allowed.');
-                }
-              }
-              elseif (isset ($media_features[$matches[1]])) {
-                switch ($media_features[$matches[1]]) {
-                  case 'length':
-                    $length_matches = array();
-                    // Check for a valid number and an allowed unit.
-                    if (preg_match('/^(\-)?(\d+(?:\.\d+)?)?((?:|em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|dpi|dpcm))$/i', trim($value), $length_matches)) {
-                      // Only -0 is allowed.
-                      if ($length_matches[1] === '-' && $length_matches[2] !== '0') {
-                        throw new InvalidBreakpointMediaQueryException('Invalid length detected.');
-                      }
-                      // If there's a unit, a number is needed as well.
-                      if ($length_matches[2] === '' && $length_matches[3] !== '') {
-                        throw new InvalidBreakpointMediaQueryException('Unit found, value is missing.');
-                      }
-                    }
-                    else {
-                      throw new InvalidBreakpointMediaQueryException('Invalid unit detected.');
-                    }
-                    break;
-                }
-              }
-            }
-          }
-
-          // Check for screen, only screen, not screen and variants.
-          elseif (preg_match('/^((?:only|not)?\s?)([\w\-]+)$/i', trim($query_part), $matches)) {
-            if ($media_type_found) {
-              throw new InvalidBreakpointMediaQueryException('Only one media type is allowed.');
-            }
-            $media_type_found = TRUE;
-          }
-          // Check for (scan), (only scan), (not scan) and variants.
-          elseif (preg_match('/^((?:only|not)\s?)\(([\w\-]+)\)$/i', trim($query_part), $matches)) {
-            throw new InvalidBreakpointMediaQueryException('Invalid media query detected.');
-          }
-          else {
-            // We need to allow vendor prefixed media fetures and make sure we
-            // are future proof, so only check allowed characters.
-            if (!preg_match('/^[a-zA-Z0-9\-\\ ]+$/i', trim($query_part), $matches)) {
-              throw new InvalidBreakpointMediaQueryException('Invalid media query detected.');
-            }
-          }
-        }
-      }
-      return TRUE;
-    }
-    throw new InvalidBreakpointMediaQueryException('Media query is empty.');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function calculateDependencies() {
-    parent::calculateDependencies();
-    $this->dependencies = array();
-    if ($this->sourceType == static::SOURCE_TYPE_MODULE) {
-      $this->addDependency('module', $this->source);
-    }
-    elseif ($this->sourceType == static::SOURCE_TYPE_THEME) {
-      $this->addDependency('theme', $this->source);
-    }
-    return $this->dependencies;
-  }
-
-}
diff --git a/core/modules/breakpoint/src/Entity/BreakpointGroup.php b/core/modules/breakpoint/src/Entity/BreakpointGroup.php
deleted file mode 100644
index 0b585e2..0000000
--- a/core/modules/breakpoint/src/Entity/BreakpointGroup.php
+++ /dev/null
@@ -1,234 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\Entity\BreakpointGroup.
- */
-
-namespace Drupal\breakpoint\Entity;
-
-use Drupal\breakpoint\InvalidBreakpointNameException;
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-use Drupal\breakpoint\BreakpointGroupInterface;
-use Drupal\breakpoint\InvalidBreakpointSourceException;
-use Drupal\breakpoint\InvalidBreakpointSourceTypeException;
-use Drupal\Core\Entity\EntityStorageInterface;
-
-/**
- * Defines the BreakpointGroup entity.
- *
- * @ConfigEntityType(
- *   id = "breakpoint_group",
- *   label = @Translation("Breakpoint group"),
- *   entity_keys = {
- *     "id" = "id",
- *     "label" = "label"
- *   }
- * )
- */
-class BreakpointGroup extends ConfigEntityBase implements BreakpointGroupInterface {
-
-  /**
-   * The breakpoint group ID.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The breakpoint group machine name.
-   *
-   * @var string
-   */
-  public $name;
-
-  /**
-   * The breakpoint group label.
-   *
-   * @var string
-   */
-  public $label;
-
-  /**
-   * The breakpoint group breakpoint IDs.
-   *
-   * @var array
-   *   Array containing all breakpoints IDs of this group.
-   *
-   * @see \Drupal\breakpoint\Entity\Breakpoint
-   */
-  protected $breakpoint_ids = array();
-
-  /**
-   * The breakpoint group breakpoints.
-   *
-   * @var array
-   *   Array containing all breakpoints objects of this group.
-   *
-   * @see \Drupal\breakpoint\Entity\Breakpoint
-   */
-  protected $breakpoints = array();
-
-  /**
-   * The breakpoint group source: theme or module name. Use 'user' for
-   * user-created groups.
-   *
-   * @var string
-   */
-  public $source = 'user';
-
-  /**
-   * The breakpoint group source type.
-   *
-   * @var string
-   *   Allowed values:
-   *     Breakpoint::SOURCE_TYPE_THEME
-   *     Breakpoint::SOURCE_TYPE_MODULE
-   *     Breakpoint::SOURCE_TYPE_USER_DEFINED
-   *
-   * @see \Drupal\breakpoint\Entity\Breakpoint
-   */
-  public $sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
-
-  /**
-   * {@inheritdoc}
-   *
-   * @throws \Drupal\breakpoint\InvalidBreakpointNameException
-   *   Exception thrown if $values['name'] is empty.
-   */
-  public function __construct(array $values, $entity_type = 'breakpoint_group') {
-    // Check required properties.
-    if (empty($values['name'])) {
-      throw new InvalidBreakpointNameException('Attempt to create an unnamed breakpoint group.');
-    }
-    parent::__construct($values, $entity_type);
-  }
-
-  /**
-   * Overrides Drupal\Core\Entity\Entity::save().
-   */
-  public function save() {
-    // Check if everything is valid.
-    if (!$this->isValid()) {
-      throw new InvalidBreakpointException('Invalid data detected.');
-    }
-    parent::save();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function id() {
-    // If no ID is specified, build one from the properties that uniquely define
-    // this breakpoint group.
-    if (!isset($this->id)) {
-      $this->id = $this->sourceType . '.' . $this->source . '.' . $this->name;
-    }
-    return $this->id;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isValid() {
-    // Check for illegal values in breakpoint group source type.
-    if (!in_array($this->sourceType, array(
-        Breakpoint::SOURCE_TYPE_USER_DEFINED,
-        Breakpoint::SOURCE_TYPE_MODULE,
-        Breakpoint::SOURCE_TYPE_THEME)
-      )) {
-      throw new InvalidBreakpointSourceTypeException(format_string('Invalid source type @source_type', array(
-        '@source_type' => $this->sourceType,
-      )));
-    }
-    // Check for illegal characters in breakpoint group source.
-    if (preg_match('/[^a-z_]+/', $this->source) || empty($this->source)) {
-      throw new InvalidBreakpointSourceException(format_string("Invalid value '@source' for breakpoint group source property. Breakpoint group source property can only contain lowercase letters and underscores.", array('@source' => $this->source)));
-    }
-    // Check for illegal characters in breakpoint group name.
-    if (preg_match('/[^a-z0-9_]+/', $this->name || empty($this->name))) {
-      throw new InvalidBreakpointNameException(format_string("Invalid value '@name' for breakpoint group name property. Breakpoint group name property can only contain lowercase letters, numbers and underscores.", array('@name' => $this->name)));
-    }
-    return TRUE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function addBreakpointFromMediaQuery($name, $media_query) {
-    // Use the existing breakpoint if it exists.
-    $breakpoint = Breakpoint::load($this->sourceType . '.' . $this->name . '.' . $name);
-    if (!$breakpoint) {
-      // Build a new breakpoint.
-      $breakpoint = entity_create('breakpoint', array(
-        'name' => $name,
-        'label' => $name,
-        'mediaQuery' => $media_query,
-        'source' => $this->name,
-        'sourceType' => $this->sourceType,
-        'weight' => count($this->breakpoint_ids),
-      ));
-      $breakpoint->save();
-    }
-    return $this->addBreakpoints(array($breakpoint));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function addBreakpoints($breakpoints) {
-    foreach ($breakpoints as $breakpoint) {
-      // Add breakpoint to group.
-      $this->breakpoints[$breakpoint->id()] = $breakpoint;
-      $this->breakpoint_ids[] = $breakpoint->id();
-    }
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getBreakpoints() {
-    if (empty($this->breakpoints)) {
-      foreach ($this->breakpoint_ids as $breakpoint_id) {
-        $breakpoint = Breakpoint::load($breakpoint_id);
-        if ($breakpoint) {
-          $this->breakpoints[$breakpoint_id] = $breakpoint;
-        }
-      }
-    }
-    return $this->breakpoints;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getBreakpointById($id) {
-    $breakpoints = $this->getBreakpoints();
-    if (isset($breakpoints[$id])) {
-      return $breakpoints[$id];
-    }
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function calculateDependencies() {
-    parent::calculateDependencies();
-
-    $this->dependencies = array();
-    if ($this->sourceType == Breakpoint::SOURCE_TYPE_MODULE) {
-      $this->addDependency('module', $this->source);
-    }
-    elseif ($this->sourceType == Breakpoint::SOURCE_TYPE_THEME) {
-      $this->addDependency('theme', $this->source);
-    }
-    $breakpoints = $this->getBreakpoints();
-    foreach ($breakpoints as $breakpoint) {
-      $this->addDependency('entity', $breakpoint->getConfigDependencyName());
-    }
-    return $this->dependencies;
-  }
-
-}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointException.php b/core/modules/breakpoint/src/InvalidBreakpointException.php
deleted file mode 100644
index 6889fa2..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointException.php
+++ /dev/null
@@ -1,13 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointException.
- */
-
-namespace Drupal\breakpoint;
-
-/**
- * Base exception for breakpoint exception.
- */
-class InvalidBreakpointException extends \RuntimeException {}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointMediaQueryException.php b/core/modules/breakpoint/src/InvalidBreakpointMediaQueryException.php
deleted file mode 100644
index 3999965..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointMediaQueryException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointMediaQueryException.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\breakpoint\InvalidBreakpointException;
-
-/**
- * Exception thrown if an illegal media query is detected.
- */
-class InvalidBreakpointMediaQueryException extends InvalidBreakpointException {}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointNameException.php b/core/modules/breakpoint/src/InvalidBreakpointNameException.php
deleted file mode 100644
index 1121465..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointNameException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointNameException.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\breakpoint\InvalidBreakpointException;
-
-/**
- * Exception thrown if an invalid name is detected.
- */
-class InvalidBreakpointNameException extends InvalidBreakpointException {}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointSourceException.php b/core/modules/breakpoint/src/InvalidBreakpointSourceException.php
deleted file mode 100644
index 3ad5556..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointSourceException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointSourceException.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\breakpoint\InvalidBreakpointException;
-
-/**
- * Exception thrown if an invalid source is detected.
- */
-class InvalidBreakpointSourceException extends InvalidBreakpointException {}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointSourceTypeException.php b/core/modules/breakpoint/src/InvalidBreakpointSourceTypeException.php
deleted file mode 100644
index d9e2483..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointSourceTypeException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointSourceTypeException.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\breakpoint\InvalidBreakpointException;
-
-/**
- * Exception thrown if an invalid source_type is detected.
- */
-class InvalidBreakpointSourceTypeException extends InvalidBreakpointException {}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointAPITest.php b/core/modules/breakpoint/src/Tests/BreakpointAPITest.php
deleted file mode 100644
index abfb430..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointAPITest.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointAPITest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointsTestBase;
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\InvalidBreakpointNameException;
-use Drupal\breakpoint\InvalidBreakpointSourceException;
-use Drupal\breakpoint\InvalidBreakpointSourceTypeException;
-use Drupal\Component\Utility\Unicode;
-
-/**
- * Tests general API functions of the breakpoint module.
- *
- * @group breakpoint
- */
-class BreakpointAPITest extends BreakpointTestBase {
-
-  /**
-   * Test Breakpoint::buildConfigName().
-   */
-  public function testConfigName() {
-    // Try an invalid sourceType.
-    $label = $this->randomMachineName();
-    $breakpoint = entity_create('breakpoint', array(
-      'label' => $label,
-      'name' => Unicode::strtolower($label),
-      'source' => 'custom_module',
-      'sourceType' => 'oops',
-    ));
-
-    $exception = FALSE;
-    try {
-      $breakpoint->save();
-    }
-    catch (InvalidBreakpointSourceTypeException $e) {
-      $exception = TRUE;
-    }
-    $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid sourceType is entered.');
-
-    // Try an invalid source.
-    $breakpoint = $breakpoint->createDuplicate();
-    $breakpoint->sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
-    $breakpoint->source = 'custom*_module source';
-
-    $exception = FALSE;
-    try {
-      $breakpoint->save();
-    }
-    catch (InvalidBreakpointSourceException $e) {
-      $exception = TRUE;
-    }
-    $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid source is entered.');
-
-    // Try an invalid name (make sure there is at least once capital letter).
-    $breakpoint = $breakpoint->createDuplicate();
-    $breakpoint->source = 'custom_module';
-    $breakpoint->name = drupal_ucfirst($this->randomMachineName());
-
-    $exception = FALSE;
-    try {
-      $breakpoint->save();
-    }
-    catch (InvalidBreakpointNameException $e) {
-      $exception = TRUE;
-    }
-    $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid name is entered.');
-
-    // Try a valid breakpoint.
-    $breakpoint = $breakpoint->createDuplicate();
-    $breakpoint->name = drupal_strtolower($this->randomMachineName());
-    $breakpoint->mediaQuery = 'all';
-
-    $exception = FALSE;
-    try {
-      $breakpoint->save();
-    }
-    catch (\Exception $e) {
-      $exception = TRUE;
-    }
-    $this->assertFalse($exception, 'breakpoint_config_name: No exception is thrown when a valid breakpoint is passed.');
-    $this->assertEqual($breakpoint->id(), Breakpoint::SOURCE_TYPE_USER_DEFINED . '.custom_module.' . $breakpoint->name, 'breakpoint_config_name: A id is set when a valid breakpoint is passed.');
-  }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointCRUDTest.php b/core/modules/breakpoint/src/Tests/BreakpointCRUDTest.php
deleted file mode 100644
index 5b46d3d..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointCRUDTest.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointCRUDTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointTestBase;
-use Drupal\breakpoint\Entity\Breakpoint;
-
-/**
- * Tests creation, loading, updating, deleting of breakpoints.
- *
- * @group breakpoint
- */
-class BreakpointCRUDTest extends BreakpointTestBase {
-
-  /**
-   * Test CRUD operations for breakpoints.
-   */
-  public function testBreakpointCRUD() {
-    // Add a breakpoint with minimum data only.
-    $label = $this->randomMachineName();
-    $breakpoint = entity_create('breakpoint', array(
-      'label' => $label,
-      'mediaQuery' => '(min-width: 600px)',
-      'name' => drupal_strtolower($label),
-    ));
-    $breakpoint->save();
-
-    $this->verifyBreakpoint($breakpoint);
-
-    // Test BreakPoint::loadMultiple().
-    $all_breakpoints = Breakpoint::loadMultiple();
-    $config_name = $breakpoint->id();
-    $this->assertTrue(isset($all_breakpoints[$config_name]), 'New breakpoint is present when loading all breakpoints.');
-    $this->verifyBreakpoint($breakpoint, $all_breakpoints[$config_name]);
-
-    // Update the breakpoint.
-    $breakpoint->weight = 1;
-    $breakpoint->multipliers['2x'] = '2x';
-    $breakpoint->save();
-    $this->verifyBreakpoint($breakpoint);
-
-    // Delete the breakpoint.
-    $breakpoint->delete();
-    $this->assertNull(Breakpoint::load($config_name), 'Loading a deleted breakpoint returns null.', 'Breakpoints API');
-  }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php b/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php
new file mode 100644
index 0000000..d1804a2
--- /dev/null
+++ b/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * @file
+ * Definition of Drupal\breakpoint\Tests\BreakpointDiscoveryTest.
+ */
+
+namespace Drupal\breakpoint\Tests;
+
+use Drupal\simpletest\KernelTestBase;
+
+/**
+ * Tests discovery of breakpoints provided by themes and modules.
+ *
+ * @group breakpoint
+ */
+class BreakpointDiscoveryTest extends KernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('breakpoint', 'breakpoints_module_test');
+
+  public function setUp() {
+    parent::setUp();
+    \Drupal::service('theme_handler')->enable(array('breakpoint_test_theme'));
+  }
+
+  /**
+   * Test the breakpoint group created for a theme.
+   */
+  public function testThemeBreakpoints() {
+    // Verify the breakpoint group for breakpoint_test_theme was created.
+    $expected_breakpoints = array(
+        'breakpoint_test_theme.mobile' => array(
+          'label' => 'mobile',
+          'mediaQuery' => '(min-width: 0px)',
+          'weight' => 0,
+          'multipliers' => array(
+            '1x',
+          ),
+          'provider' => 'breakpoint_test_theme',
+          'id' => 'breakpoint_test_theme.mobile',
+          'group' => 'breakpoint_test_theme',
+        ),
+        'breakpoint_test_theme.narrow' => array(
+          'label' => 'narrow',
+          'mediaQuery' => '(min-width: 560px)',
+          'weight' => 1,
+          'multipliers' => array(
+            '1x',
+          ),
+          'provider' => 'breakpoint_test_theme',
+          'id' => 'breakpoint_test_theme.narrow',
+          'group' => 'breakpoint_test_theme',
+        ),
+        'breakpoint_test_theme.wide' => array(
+          'label' => 'wide',
+          'mediaQuery' => '(min-width: 851px)',
+          'weight' => 2,
+          'multipliers' => array(
+            '1x',
+          ),
+          'provider' => 'breakpoint_test_theme',
+          'id' => 'breakpoint_test_theme.wide',
+          'group' => 'breakpoint_test_theme',
+        ),
+        'breakpoint_test_theme.tv' => array(
+          'label' => 'tv',
+          'mediaQuery' => 'only screen and (min-width: 3456px)',
+          'weight' => 3,
+          'multipliers' => array(
+            '1x',
+          ),
+          'provider' => 'breakpoint_test_theme',
+          'id' => 'breakpoint_test_theme.tv',
+          'group' => 'breakpoint_test_theme',
+        ),
+    );
+
+    $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('breakpoint_test_theme');
+    foreach ($expected_breakpoints as $id => $expected_breakpoint) {
+      $this->assertEqual($expected_breakpoint, $breakpoints[$id]);
+    }
+
+    // Verify the breakpoint group for breakpoint_test_theme.group2 was created.
+    $expected_breakpoints = array(
+      'breakpoint_test_theme.group2.narrow' => array(
+        'label' => 'narrow',
+        'mediaQuery' => '(min-width: 560px)',
+        'weight' => 1,
+        'multipliers' => array(
+          '1x',
+          '2x'
+        ),
+        'provider' => 'breakpoint_test_theme',
+        'id' => 'breakpoint_test_theme.group2.narrow',
+        'group' => 'breakpoint_test_theme.group2',
+      ),
+      'breakpoint_test_theme.group2.wide' => array(
+        'label' => 'wide',
+        'mediaQuery' => '(min-width: 851px)',
+        'weight' => 2,
+        'multipliers' => array(
+          '1x',
+          '2x'
+        ),
+        'provider' => 'breakpoint_test_theme',
+        'id' => 'breakpoint_test_theme.group2.wide',
+        'group' => 'breakpoint_test_theme.group2',
+      ),
+    );
+
+    $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('breakpoint_test_theme.group2');
+    foreach ($expected_breakpoints as $id => $expected_breakpoint) {
+      $this->assertEqual($expected_breakpoint, $breakpoints[$id]);
+    }
+  }
+
+  /**
+   * Test the breakpoint group created for a module.
+   */
+  public function testModuleBreakpoints() {
+    $expected_breakpoints = array(
+      'breakpoints_module_test.mobile' => array(
+        'label' => 'mobile',
+        'mediaQuery' => '(min-width: 0px)',
+        'weight' => 0,
+        'multipliers' => array(
+          '1x',
+        ),
+        'provider' => 'breakpoints_module_test',
+        'id' => 'breakpoints_module_test.mobile',
+        'group' => 'breakpoints_module_test',
+      ),
+      'breakpoints_module_test.standard' => array(
+        'label' => 'standard',
+        'mediaQuery' => '(min-width: 560px)',
+        'weight' => 1,
+        'multipliers' => array(
+          '1x',
+          '2x',
+        ),
+        'provider' => 'breakpoints_module_test',
+        'id' => 'breakpoints_module_test.standard',
+        'group' => 'breakpoints_module_test',
+      ),
+    );
+
+    $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('breakpoints_module_test');
+    foreach ($expected_breakpoints as $id => $expected_breakpoint) {
+      $this->assertEqual($expected_breakpoint, $breakpoints[$id]);
+    }
+  }
+
+  /**
+   * Test the collection of breakpoint groups.
+   */
+  public function testBreakpointGroups() {
+    $expected = array(
+      'bartik' => 'Bartik',
+      'breakpoints_module_test' => 'Breakpoint test module',
+      'breakpoint_test_theme' => 'Breakpoint test theme',
+      'breakpoint_test_theme.group2' => 'breakpoint_test_theme.group2',
+    );
+    $breakpoint_groups = \Drupal::service('breakpoint.manager')->getGroups();
+    $this->assertEqual($expected, $breakpoint_groups);
+  }
+
+}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointGroupAPITest.php b/core/modules/breakpoint/src/Tests/BreakpointGroupAPITest.php
deleted file mode 100644
index f8a0191..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointGroupAPITest.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointGroupAPITest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointsTestBase;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\InvalidBreakpointNameException;
-use Drupal\breakpoint\InvalidBreakpointSourceException;
-use Drupal\breakpoint\InvalidBreakpointSourceTypeException;
-use Drupal\Component\Utility\Unicode;
-
-/**
- * Tests general API functions of the breakpoint module.
- *
- * @group breakpoint
- */
-class BreakpointGroupAPITest extends BreakpointGroupTestBase {
-
-  /**
-   * Test Breakpoint::buildConfigName().
-   */
-  public function testConfigName() {
-    // Try an invalid sourceType.
-    $label = $this->randomMachineName();
-    $breakpoint_group = entity_create('breakpoint_group', array(
-      'label' => $label,
-      'name' => drupal_strtolower($label),
-      'source' => 'custom_module',
-      'sourceType' => 'oops',
-    ));
-
-    $exception = FALSE;
-    try {
-      $breakpoint_group->save();
-    }
-    catch (InvalidBreakpointSourceTypeException $e) {
-      $exception = TRUE;
-    }
-    $this->assertTrue($exception, 'An exception is thrown when an invalid sourceType is entered.');
-
-    // Try an invalid source.
-    $breakpoint_group = $breakpoint_group->createDuplicate();
-    $breakpoint_group->name = '';
-    $breakpoint_group->sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
-    $breakpoint_group->source = 'custom*_module source';
-
-    $exception = FALSE;
-    try {
-      $breakpoint_group->save();
-    }
-    catch (InvalidBreakpointSourceException $e) {
-      $exception = TRUE;
-    }
-    $this->assertTrue($exception, 'An exception is thrown when an invalid source is entered.');
-
-    // Try a valid breakpoint_group.
-    $breakpoint_group = $breakpoint_group->createDuplicate();
-    $breakpoint_group->name = 'test';
-    $breakpoint_group->source = 'custom_module_source';
-
-    $exception = FALSE;
-    try {
-      $breakpoint_group->save();
-    }
-    catch (\Exception $e) {
-      $exception = TRUE;
-    }
-    $this->assertFalse($exception, 'No exception is thrown when a valid data is passed.');
-  }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointGroupCRUDTest.php b/core/modules/breakpoint/src/Tests/BreakpointGroupCRUDTest.php
deleted file mode 100644
index aa949de..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointGroupCRUDTest.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointGroupCRUDTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointGroupTestBase;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\breakpoint\Entity\Breakpoint;
-
-/**
- * Tests creation, loading, updating, deleting of breakpoint groups.
- *
- * @group breakpoint
- */
-class BreakpointGroupCRUDTest extends BreakpointGroupTestBase {
-
-  /**
-   * Test CRUD operations for breakpoint groups.
-   */
-  public function testBreakpointGroupCRUD() {
-    // Add breakpoints.
-    $breakpoints = array();
-    for ($i = 0; $i <= 3; $i++) {
-      $width = ($i + 1) * 200;
-      $breakpoint = entity_create('breakpoint', array(
-        'name' => drupal_strtolower($this->randomMachineName()),
-        'weight' => $i,
-        'mediaQuery' => "(min-width: {$width}px)",
-      ));
-      $breakpoint->save();
-      $breakpoints[$breakpoint->id()] = $breakpoint;
-    }
-    // Add a breakpoint group with minimum data only.
-    $label = $this->randomMachineName();
-
-    $group = entity_create('breakpoint_group', array(
-      'label' => $label,
-      'name' => drupal_strtolower($label),
-    ));
-    $group->save();
-    $this->verifyBreakpointGroup($group);
-
-    // Update the breakpoint group.
-    $group->addBreakpoints($breakpoints)->save();
-    $this->verifyBreakpointGroup($group);
-
-    // Delete the breakpoint group.
-    $group->delete();
-    $this->assertFalse(entity_load('breakpoint_group', $group->id()), 'breakpoint_group_load: Loading a deleted breakpoint group returns false.', 'Breakpoints API');
-  }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointGroupTestBase.php b/core/modules/breakpoint/src/Tests/BreakpointGroupTestBase.php
deleted file mode 100644
index 95141e3..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointGroupTestBase.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointGroupTestBase.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\simpletest\WebTestBase;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-
-/**
- * Base class for Breakpoint group tests.
- */
-abstract class BreakpointGroupTestBase extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('breakpoint');
-
-  public function setUp() {
-    parent::setUp();
-  }
-
-  /**
-   * Verify that a breakpoint is properly stored.
-   */
-  public function verifyBreakpointGroup(BreakpointGroup $group, BreakpointGroup $compare_set = NULL) {
-    $properties = array(
-      'label',
-      'id',
-      'name',
-      'sourceType',
-    );
-
-    // Verify breakpoint_group_load().
-    $compare_set = is_null($compare_set) ? entity_load('breakpoint_group', $group->id()) : $compare_set;
-
-    foreach ($properties as $property) {
-      $t_args = array(
-        '%group' => $group->label(),
-        '%property' => $property,
-      );
-      if (is_array($compare_set->{$property})) {
-        $this->assertEqual(array_keys($compare_set->{$property}), array_keys($group->{$property}), format_string('breakpoint_group_load: Proper %property for breakpoint group %group.', $t_args), 'Breakpoint API');
-      }
-      else {
-        $t_args = array(
-          '%group' => $group->label(),
-          '%property' => $property,
-          '%property1' => $compare_set->{$property},
-          '%property2' => $group->{$property},
-        );
-        $this->assertEqual($compare_set->{$property}, $group->{$property}, format_string('breakpoint_group_load: Proper %property: %property1 == %property2 for breakpoint group %group.', $t_args), 'Breakpoint API');
-      }
-    }
-
-    // Ensure that the breakpoint group has the expected breakpoints.
-    $this->assertEqual(array_keys($compare_set->getBreakpoints()), array_keys($group->getBreakpoints()));
-  }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointTestBase.php b/core/modules/breakpoint/src/Tests/BreakpointTestBase.php
deleted file mode 100644
index aac96c9..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointTestBase.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointTestBase.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\simpletest\WebTestBase;
-use Drupal\breakpoint\Entity\Breakpoint;
-
-/**
- * Base class for Breakpoint tests.
- */
-abstract class BreakpointTestBase extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('breakpoint');
-
-  public function setUp() {
-    parent::setUp();
-  }
-
-  /**
-   * Verify that a breakpoint is properly stored.
-   */
-  public function verifyBreakpoint(Breakpoint $breakpoint, Breakpoint $compare_breakpoint = NULL) {
-    $properties = array(
-      'label',
-      'mediaQuery',
-      'source',
-      'sourceType',
-      'weight',
-      'multipliers',
-    );
-
-    // Verify Breakpoint::load().
-    $compare_breakpoint = is_null($compare_breakpoint) ? Breakpoint::load($breakpoint->id()) : $compare_breakpoint;
-    foreach ($properties as $property) {
-      $t_args = array(
-        '%breakpoint' => $breakpoint->label(),
-        '%property' => $property,
-      );
-      $this->assertEqual($compare_breakpoint->{$property}, $breakpoint->{$property}, format_string('Proper %property for breakpoint %breakpoint.', $t_args), 'Breakpoint API');
-    }
-  }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointThemeTest.php b/core/modules/breakpoint/src/Tests/BreakpointThemeTest.php
deleted file mode 100644
index f5d3e82..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointThemeTest.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointsThemeTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointGroupTestBase;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\breakpoint\Entity\Breakpoint;
-
-/**
- * Thoroughly test the breakpoints provided by a theme.
- *
- * @group breakpoint
- */
-class BreakpointThemeTest extends BreakpointGroupTestBase {
-
-  public function setUp() {
-    parent::setUp();
-    theme_enable(array('breakpoint_test_theme'));
-  }
-
-  /**
-   * Test the breakpoints provided by a theme.
-   */
-  public function testThemeBreakpoints() {
-    // Verify the breakpoint group for breakpoint_test_theme was created.
-    $breakpoint_group_obj = entity_create('breakpoint_group', array(
-      'label' => 'Breakpoint test theme',
-      'name' => 'breakpoint_test_theme',
-      'source' => 'breakpoint_test_theme',
-      'sourceType' => Breakpoint::SOURCE_TYPE_THEME,
-      'id' => Breakpoint::SOURCE_TYPE_THEME . '.breakpoint_test_theme.breakpoint_test_theme',
-    ));
-    $breakpoint_group_obj->addBreakpoints(entity_load_multiple('breakpoint',
-      array(
-        'theme.breakpoint_test_theme.mobile',
-        'theme.breakpoint_test_theme.narrow',
-        'theme.breakpoint_test_theme.wide',
-        'theme.breakpoint_test_theme.tv',
-      )
-    ));
-
-    // Verify we can load this breakpoint defined by the theme.
-    $this->verifyBreakpointGroup($breakpoint_group_obj);
-  }
-
-  /**
-   * Test the breakpoints defined by the custom group.
-   */
-  public function testThemeBreakpointGroup() {
-    // Verify the breakpoint group 'test' was created by breakpoint_test_theme.
-    $breakpoint_group_obj = entity_create('breakpoint_group', array(
-      'label' => 'Test Theme',
-      'name' => 'test',
-      'sourceType' => Breakpoint::SOURCE_TYPE_THEME,
-      'source' => 'breakpoint_test_theme',
-      'id' => Breakpoint::SOURCE_TYPE_THEME . '.breakpoint_test_theme.test',
-    ));
-    $breakpoint_group_obj->addBreakpoints(entity_load_multiple('breakpoint',
-      array(
-        'theme.breakpoint_test_theme.mobile',
-        'theme.breakpoint_test_theme.narrow',
-        'theme.breakpoint_test_theme.wide',
-      )
-    ));
-
-    // Verify we can load this breakpoint defined by the theme.
-    $this->verifyBreakpointGroup($breakpoint_group_obj);
-  }
-
-}
diff --git a/core/modules/breakpoint/tests/modules/breakpoints_module_test/breakpoints_module_test.breakpoints.yml b/core/modules/breakpoint/tests/modules/breakpoints_module_test/breakpoints_module_test.breakpoints.yml
new file mode 100644
index 0000000..3270116
--- /dev/null
+++ b/core/modules/breakpoint/tests/modules/breakpoints_module_test/breakpoints_module_test.breakpoints.yml
@@ -0,0 +1,12 @@
+breakpoints_module_test.mobile:
+  label: mobile
+  mediaQuery: '(min-width: 0px)'
+  weight: 0
+  # Don't include multipliers. A 1x multiplier this will be enforced by default.
+breakpoints_module_test.standard:
+  label: standard
+  mediaQuery: '(min-width: 560px)'
+  weight: 1
+  # Don't include a 1x multiplier this will be enforced by default.
+  multipliers:
+    - 2x
diff --git a/core/modules/breakpoint/tests/modules/breakpoints_module_test/breakpoints_module_test.info.yml b/core/modules/breakpoint/tests/modules/breakpoints_module_test/breakpoints_module_test.info.yml
new file mode 100644
index 0000000..5acc9cd
--- /dev/null
+++ b/core/modules/breakpoint/tests/modules/breakpoints_module_test/breakpoints_module_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Breakpoint test module'
+type: module
+description: 'Test module for breakpoint.'
+version: VERSION
+core: 8.x
+
diff --git a/core/modules/breakpoint/tests/src/BreakpointConfigEntityUnitTest.php b/core/modules/breakpoint/tests/src/BreakpointConfigEntityUnitTest.php
deleted file mode 100644
index 4ba41b5..0000000
--- a/core/modules/breakpoint/tests/src/BreakpointConfigEntityUnitTest.php
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\breakpoint\Tests\BreakpointConfigEntityUnitTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\breakpoint\Entity\Breakpoint
- * @group breakpoint
- */
-class BreakpointConfigEntityUnitTest extends UnitTestCase {
-
-  /**
-   * The entity under test.
-   *
-   * @var \Drupal\breakpoint\Entity\Breakpoint|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entity;
-
-  /**
-   * The entity type used for testing.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityType;
-
-  /**
-   * The entity manager used for testing.
-   *
-   * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityManager;
-
-  /**
-   * The ID of the type of the entity under test.
-   *
-   * @var string
-   */
-  protected $entityTypeId;
-
-  /**
-   * The UUID generator used for testing.
-   *
-   * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $uuid;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setUp() {
-    $this->entityTypeId = $this->randomMachineName();
-
-    $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
-    $this->entityType->expects($this->any())
-      ->method('getProvider')
-      ->will($this->returnValue('breakpoint'));
-
-    $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
-    $this->entityManager->expects($this->any())
-      ->method('getDefinition')
-      ->with($this->entityTypeId)
-      ->will($this->returnValue($this->entityType));
-
-    $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
-
-    $container = new ContainerBuilder();
-    $container->set('entity.manager', $this->entityManager);
-    $container->set('uuid', $this->uuid);
-    \Drupal::setContainer($container);
-  }
-
-  /**
-   * @covers ::calculateDependencies
-   */
-  public function testCalculateDependenciesModule() {
-    $values = array(
-      'name' => 'test',
-      'source' => 'test_module',
-      'sourceType' => Breakpoint::SOURCE_TYPE_MODULE,
-    );
-    $entity = new Breakpoint($values, $this->entityTypeId);
-
-    $dependencies = $entity->calculateDependencies();
-    $this->assertArrayNotHasKey('theme', $dependencies);
-    $this->assertContains('test_module', $dependencies['module']);
-  }
-
-  /**
-   * @covers ::calculateDependencies
-   */
-  public function testCalculateDependenciesTheme() {
-    $values = array(
-      'name' => 'test',
-      'source' => 'test_theme',
-      'sourceType' => Breakpoint::SOURCE_TYPE_THEME,
-    );
-    $entity = new Breakpoint($values, $this->entityTypeId);
-
-    $dependencies = $entity->calculateDependencies();
-    $this->assertArrayNotHasKey('module', $dependencies);
-    $this->assertContains('test_theme', $dependencies['theme']);
-  }
-
-  /**
-   * @expectedException \Drupal\breakpoint\InvalidBreakpointNameException
-   */
-  public function testNameException () {
-    new Breakpoint(array(
-      'label' => $this->randomMachineName(),
-      'source' => 'custom_module',
-      'sourceType' => 'oops',
-    ));
-  }
-
-}
diff --git a/core/modules/breakpoint/tests/src/BreakpointGroupConfigEntityUnitTest.php b/core/modules/breakpoint/tests/src/BreakpointGroupConfigEntityUnitTest.php
deleted file mode 100644
index 685c951..0000000
--- a/core/modules/breakpoint/tests/src/BreakpointGroupConfigEntityUnitTest.php
+++ /dev/null
@@ -1,158 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\breakpoint\Tests\BreakpointGroupConfigEntityUnitTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\breakpoint\Entity\BreakpointGroup
- * @group breakpoint
- */
-class BreakpointGroupConfigEntityUnitTest extends UnitTestCase {
-
-  /**
-   * The entity under test.
-   *
-   * @var \Drupal\breakpoint\Entity\BreakpointGroup|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entity;
-
-  /**
-   * The entity type used for testing.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityType;
-
-  /**
-   * The entity manager used for testing.
-   *
-   * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityManager;
-
-  /**
-   * The ID of the type of the entity under test.
-   *
-   * @var string
-   */
-  protected $entityTypeId;
-
-  /**
-   * The UUID generator used for testing.
-   *
-   * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $uuid;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setUp() {
-    $this->entityTypeId = $this->randomMachineName();
-
-    $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
-    $this->entityType->expects($this->any())
-      ->method('getProvider')
-      ->will($this->returnValue('breakpoint'));
-
-    $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
-    $this->entityManager->expects($this->any())
-      ->method('getDefinition')
-      ->with($this->entityTypeId)
-      ->will($this->returnValue($this->entityType));
-
-    $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
-
-    $container = new ContainerBuilder();
-    $container->set('entity.manager', $this->entityManager);
-    $container->set('uuid', $this->uuid);
-    \Drupal::setContainer($container);
-  }
-
-  /**
-   * Sets up the entity to test.
-   */
-  public function setUpEntity($values) {
-    // Mocking the entity under test because the class contains calls to
-    // procedural code.
-    $this->entity = $this->getMockBuilder('\Drupal\breakpoint\Entity\BreakpointGroup')
-      ->setConstructorArgs(array($values, $this->entityTypeId))
-      ->setMethods(array('getBreakpoints'))
-      ->getMock();
-  }
-
-  /**
-   * @covers ::calculateDependencies
-   */
-  public function testCalculateDependenciesModule() {
-    $this->setUpEntity(
-      array(
-        'name' => 'test',
-        'source' => 'test_module',
-        'sourceType' => Breakpoint::SOURCE_TYPE_MODULE,
-      )
-    );
-    $breakpoint = $this->getMock('\Drupal\breakpoint\BreakpointInterface');
-    $breakpoint->expects($this->once())
-      ->method('getConfigDependencyName')
-      ->will($this->returnValue('breakpoint.breakpoint.test'));
-
-    $this->entity->expects($this->once())
-      ->method('getBreakpoints')
-      ->will($this->returnValue(array($breakpoint)));
-
-    $dependencies = $this->entity->calculateDependencies();
-    $this->assertArrayNotHasKey('theme', $dependencies);
-    $this->assertContains('test_module', $dependencies['module']);
-    $this->assertContains('breakpoint.breakpoint.test', $dependencies['entity']);
-  }
-
-  /**
-   * @covers ::calculateDependencies
-   */
-  public function testCalculateDependenciesTheme() {
-    $this->setUpEntity(
-      array(
-        'name' => 'test',
-        'source' => 'test_theme',
-        'sourceType' => Breakpoint::SOURCE_TYPE_THEME,
-      )
-    );
-
-    $breakpoint = $this->getMockBuilder('\Drupal\breakpoint\Entity\Breakpoint')
-                       ->disableOriginalConstructor()->getMock();
-    $breakpoint->expects($this->once())
-               ->method('getConfigDependencyName')
-               ->will($this->returnValue('breakpoint.breakpoint.test'));
-
-    $this->entity->expects($this->once())
-                 ->method('getBreakpoints')
-                 ->will($this->returnValue(array($breakpoint)));
-
-    $dependencies = $this->entity->calculateDependencies();
-    $this->assertArrayNotHasKey('module', $dependencies);
-    $this->assertContains('test_theme', $dependencies['theme']);
-    $this->assertContains('breakpoint.breakpoint.test', $dependencies['entity']);
-  }
-
-  /**
-   * @expectedException \Drupal\breakpoint\InvalidBreakpointNameException
-   */
-  public function testNameException () {
-    new BreakpointGroup(array(
-      'label' => $this->randomMachineName(),
-      'source' => 'custom_module',
-      'sourceType' => 'oops',
-    ));
-  }
-
-}
diff --git a/core/modules/breakpoint/tests/src/BreakpointMediaQueryTest.php b/core/modules/breakpoint/tests/src/BreakpointMediaQueryTest.php
deleted file mode 100644
index c8ab81d..0000000
--- a/core/modules/breakpoint/tests/src/BreakpointMediaQueryTest.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointMediaQueryTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\Tests\UnitTestCase;
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\InvalidBreakpointMediaQueryException;
-
-/**
- * Tests validation of media queries.
- *
- * @group breakpoint
- */
-class BreakpointMediaQueryTest extends UnitTestCase {
-
-  /**
-   * Test valid media queries.
-   */
-  public function testValidMediaQueries() {
-    $media_queries = array(
-      // Bartik breakpoints.
-      '(min-width: 0px)',
-      'all and (min-width: 560px) and (max-width:850px)',
-      'all and (min-width: 851px)',
-      // Seven breakpoints.
-      '(min-width: 0em)',
-      'screen and (min-width: 40em)',
-      // Stark breakpoints.
-      '(min-width: 0px)',
-      'all and (min-width: 480px) and (max-width: 959px)',
-      'all and (min-width: 960px)',
-      // Other media queries.
-      '(orientation)',
-      'all and (orientation)',
-      'not all and (orientation)',
-      'only all and (orientation)',
-      'screen and (width)',
-      'screen and (width: 0)',
-      'screen and (width: 0px)',
-      'screen and (width: 0em)',
-      'screen and (min-width: -0)',
-      'screen and (max-width: 0)',
-      'screen and (max-width: 0.3)',
-      'screen and (min-width)',
-      // Multiline and comments.
-      'screen and /* this is a comment */ (min-width)',
-      "screen\nand /* this is a comment */ (min-width)",
-      "screen\n\nand /* this is\n a comment */ (min-width)",
-      // Unrecognized features are allowed.
-      'screen and (-webkit-min-device-pixel-ratio: 7)',
-      'screen and (min-orientation: landscape)',
-      'screen and (max-orientation: landscape)',
-    );
-
-    foreach ($media_queries as $media_query) {
-      $this->assertTrue(Breakpoint::isValidMediaQuery($media_query), $media_query . ' is valid.');
-    }
-  }
-
-  /**
-   * Test invalid media queries.
-   */
-  public function testInvalidMediaQueries() {
-    $media_queries = array(
-      '',
-      'not (orientation)',
-      'only (orientation)',
-      'all and not all',
-      'screen and (width: 0xx)',
-      'screen and (width: -8xx)',
-      'screen and (width: -xx)',
-      'screen and (width: xx)',
-      'screen and (width: px)',
-      'screen and (width: -8px)',
-      'screen and (width: -0.8px)',
-      'screen and (height: 0xx)',
-      'screen and (height: -8xx)',
-      'screen and (height: -xx)',
-      'screen and (height: xx)',
-      'screen and (height: px)',
-      'screen and (height: -8px)',
-      'screen and (height: -0.8px)',
-      'screen and (device-width: 0xx)',
-      'screen and (device-width: -8xx)',
-      'screen and (device-width: -xx)',
-      'screen and (device-width: xx)',
-      'screen and (device-width: px)',
-      'screen and (device-width: -8px)',
-      'screen and (device-width: -0.8px)',
-      'screen and (device-height: 0xx)',
-      'screen and (device-height: -8xx)',
-      'screen and (device-height: -xx)',
-      'screen and (device-height: xx)',
-      'screen and (device-height: px)',
-      'screen and (device-height: -8px)',
-      'screen and (device-height: -0.8px)',
-      'screen and (min-orientation)',
-      'screen and (max-orientation)',
-      'screen and (orientation: bogus)',
-      '(orientation: bogus)',
-      'screen and (ori"entation: bogus)',
-    );
-
-    foreach ($media_queries as $media_query) {
-      try {
-        $this->assertFalse(Breakpoint::isValidMediaQuery($media_query), $media_query . ' is not valid.');
-      }
-      catch (InvalidBreakpointMediaQueryException $e) {
-        $this->assertTrue(TRUE, sprintf('%s is not valid.', $media_query));
-      }
-    }
-  }
-}
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/breakpoint_test_theme.breakpoints.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/breakpoint_test_theme.breakpoints.yml
new file mode 100644
index 0000000..2afb0ab
--- /dev/null
+++ b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/breakpoint_test_theme.breakpoints.yml
@@ -0,0 +1,40 @@
+breakpoint_test_theme.mobile:
+  label: mobile
+  mediaQuery: '(min-width: 0px)'
+  weight: 0
+  multipliers:
+    - 1x
+breakpoint_test_theme.narrow:
+  label: narrow
+  mediaQuery: '(min-width: 560px)'
+  weight: 1
+  multipliers:
+    - 1x
+breakpoint_test_theme.wide:
+  label: wide
+  mediaQuery: '(min-width: 851px)'
+  weight: 2
+  multipliers:
+    - 1x
+breakpoint_test_theme.tv:
+  label: tv
+  mediaQuery: 'only screen and (min-width: 3456px)'
+  weight: 3
+  multipliers:
+    - 1x
+breakpoint_test_theme.group2.narrow:
+  label: narrow
+  mediaQuery: '(min-width: 560px)'
+  weight: 1
+  multipliers:
+    - 1x
+    - 2x
+  group: breakpoint_test_theme.group2
+breakpoint_test_theme.group2.wide:
+  label: wide
+  mediaQuery: '(min-width: 851px)'
+  weight: 2
+  multipliers:
+    - 1x
+    - 2x
+  group: breakpoint_test_theme.group2
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.mobile.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.mobile.yml
deleted file mode 100644
index 8e5e3c4..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.mobile.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.mobile
-name: mobile
-label: mobile
-mediaQuery: '(min-width: 0px)'
-source: breakpoint_test_theme
-sourceType: theme
-weight: 0
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.narrow.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.narrow.yml
deleted file mode 100644
index a34b582..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.narrow.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.narrow
-name: narrow
-label: narrow
-mediaQuery: '(min-width: 560px)'
-source: breakpoint_test_theme
-sourceType: theme
-weight: 1
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.tv.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.tv.yml
deleted file mode 100644
index d594ff4..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.tv.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.tv
-name: tv
-label: tv
-mediaQuery: 'only screen and (min-width: 3456px)'
-source: breakpoint_test_theme
-sourceType: theme
-weight: 3
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.wide.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.wide.yml
deleted file mode 100644
index 34e5f4f..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.wide.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.wide
-name: wide
-label: wide
-mediaQuery: '(min-width: 851px)'
-source: breakpoint_test_theme
-sourceType: theme
-weight: 2
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.breakpoint_test_theme.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.breakpoint_test_theme.yml
deleted file mode 100644
index c335fb0..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.breakpoint_test_theme.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: theme.breakpoint_test_theme.breakpoint_test_theme
-name: breakpoint_test_theme
-label: 'Breakpoint test theme'
-breakpoint_ids:
-  - theme.breakpoint_test_theme.mobile
-  - theme.breakpoint_test_theme.narrow
-  - theme.breakpoint_test_theme.wide
-  - theme.breakpoint_test_theme.tv
-source: breakpoint_test_theme
-sourceType: theme
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.test.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.test.yml
deleted file mode 100644
index e074998..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.test.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.test
-name: test
-label: 'Test Theme'
-breakpoint_ids:
-  - theme.breakpoint_test_theme.mobile
-  - theme.breakpoint_test_theme.narrow
-  - theme.breakpoint_test_theme.wide
-source: breakpoint_test_theme
-sourceType: theme
-status: true
-langcode: en
diff --git a/core/modules/responsive_image/config/schema/responsive_image.schema.yml b/core/modules/responsive_image/config/schema/responsive_image.schema.yml
index 4cdb149..aac9add 100644
--- a/core/modules/responsive_image/config/schema/responsive_image.schema.yml
+++ b/core/modules/responsive_image/config/schema/responsive_image.schema.yml
@@ -17,17 +17,18 @@ responsive_image.mappings.*:
       type: sequence
       label: 'Mappings'
       sequence:
-        - type: sequence
-          label: 'Source type'
-          sequence:
-            - type: sequence
-              label: 'Source'
-              sequence:
-                - type: sequence
-                  label: 'Machine name'
-                  sequence:
-                    - type: string
-                      label: 'Image style'
+        - type: mapping
+          label: 'Mapping'
+          mapping:
+            breakpoint_id:
+              type: string
+              label: 'Breakpoint ID'
+            multiplier:
+              type: string
+              label: 'Multiplier'
+            image_style:
+              type: string
+              label: 'Image style'
     breakpointGroup:
       type: string
       label: 'Breakpoint group'
diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module
index 63f25e6..4830473 100644
--- a/core/modules/responsive_image/responsive_image.module
+++ b/core/modules/responsive_image/responsive_image.module
@@ -5,7 +5,6 @@
  * Responsive image display formatter for image fields.
  */
 
-use Drupal\breakpoint\Entity\Breakpoint;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Routing\RouteMatchInterface;
 use \Drupal\Core\Template\Attribute;
@@ -90,7 +89,7 @@ function responsive_image_theme() {
         'alt' => '',
         'title' => NULL,
         'attributes' => array(),
-        'breakpoints' => array(),
+        'mapping_id' => array(),
       ),
     ),
     'responsive_image_formatter' => array(
@@ -98,7 +97,7 @@ function responsive_image_theme() {
         'item' => NULL,
         'path' => NULL,
         'image_style' => NULL,
-        'breakpoints' => array(),
+        'mapping_id' => array(),
       ),
     ),
     'responsive_image_source' => array(
@@ -120,13 +119,13 @@ function responsive_image_theme() {
  *   - item: An ImageItem object.
  *   - image_style: An optional image style.
  *   - path: An optional array containing the link 'path' and link 'options'.
- *   - breakpoints: An array containing breakpoints.
+ *   - mapping_id: The ID of the responsive image mapping.
  *
  * @ingroup themeable
  */
 function theme_responsive_image_formatter($variables) {
   $item = $variables['item'];
-  if (!isset($variables['breakpoints']) || empty($variables['breakpoints'])) {
+  if (!isset($variables['mapping_id']) || empty($variables['mapping_id'])) {
     $image_formatter = array(
       '#theme' => 'image_formatter',
       '#item' => $item,
@@ -141,7 +140,7 @@ function theme_responsive_image_formatter($variables) {
     '#width' => $item->width,
     '#height' => $item->height,
     '#style_name' => $variables['image_style'],
-    '#breakpoints' => $variables['breakpoints'],
+    '#mapping_id' => $variables['mapping_id'],
   );
   if (isset($item->uri)) {
     $responsive_image['#uri'] = $item->uri;
@@ -178,7 +177,7 @@ function theme_responsive_image_formatter($variables) {
  *   - title: The title text is displayed when the image is hovered in some
  *     popular browsers.
  *   - style_name: The name of the style to be used as a fallback image.
- *   - breakpoints: An array containing breakpoints.
+ *   - mapping_id: The ID of the responsive image mapping.
  *
  * @ingroup themeable
  */
@@ -202,11 +201,12 @@ function theme_responsive_image($variables) {
     'src' => _responsive_image_image_style_url($variables['style_name'], $variables['uri']),
     'dimensions' => responsive_image_get_image_dimensions($variables),
   );
-
+  $responsive_image_mapping = entity_load('responsive_image_mapping', $variables['mapping_id']);
   // All breakpoints and multipliers.
-  foreach ($variables['breakpoints'] as $breakpoint_name => $multipliers) {
-    $breakpoint = Breakpoint::load($breakpoint_name);
-    if ($breakpoint) {
+  $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($responsive_image_mapping->getBreakpointGroup());
+  foreach ($responsive_image_mapping->getKeyedMappings() as $breakpoint_id => $multipliers) {
+    if (isset($breakpoints[$breakpoint_id])) {
+      $breakpoint = $breakpoints[$breakpoint_id];
       $new_sources = array();
       foreach ($multipliers as $multiplier => $image_style) {
         $new_source = $variables;
@@ -220,7 +220,7 @@ function theme_responsive_image($variables) {
         $sources[] = array(
           'src' => _responsive_image_image_style_url($new_sources[0]['style_name'], $new_sources[0]['uri']),
           'dimensions' => responsive_image_get_image_dimensions($new_sources[0]),
-          'media' => $breakpoint->mediaQuery,
+          'media' => $breakpoint['mediaQuery'],
         );
       }
       else {
@@ -232,7 +232,7 @@ function theme_responsive_image($variables) {
         $sources[] = array(
           'srcset' => implode(', ', $srcset),
           'dimensions' => responsive_image_get_image_dimensions($new_sources[0]),
-          'media' => $breakpoint->mediaQuery,
+          'media' => $breakpoint['mediaQuery'],
         );
       }
     }
@@ -266,7 +266,7 @@ function theme_responsive_image($variables) {
 /**
  * Returns HTML for a source tag.
  *
- * @param type $variables
+ * @param array $variables
  *   An associative array containing:
  *   - media: The media query to use.
  *   - srcset: The srcset containing the the path of the image file or a full
diff --git a/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php b/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
index 0780a0c..7aa24c6 100644
--- a/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
+++ b/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\responsive_image\Entity;
 
-use Drupal\Component\Utility\String;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\responsive_image\ResponsiveImageMappingInterface;
 
@@ -46,174 +45,141 @@ class ResponsiveImageMapping extends ConfigEntityBase implements ResponsiveImage
    *
    * @var string
    */
-  public $id;
+  protected $id;
 
   /**
    * The responsive image label.
    *
    * @var string
    */
-  public $label;
+  protected $label;
 
   /**
    * The responsive image mappings.
    *
+   * Each responsive mapping array contains the following keys:
+   * - breakpoint_id
+   * - multiplier
+   * - image_style
+   *
    * @var array
    */
   protected $mappings = array();
 
   /**
-   * The responsive image breakpoint group.
-   *
-   * @var Drupal\breakpoint\Entity\BreakpointGroup
+   * @var array
    */
-  protected $breakpointGroup = '';
+  protected $keyedMappings;
 
   /**
-   * Overrides Drupal\config\ConfigEntityBase::__construct().
+   * The responsive image breakpoint group.
+   *
+   * @var string
    */
-  public function __construct(array $values, $entity_type) {
-    parent::__construct($values, $entity_type);
-    $this->loadBreakpointGroup();
-    $this->loadAllMappings();
-  }
+  protected $breakpointGroup = '';
 
   /**
    * {@inheritdoc}
    */
-  public function calculateDependencies() {
-    parent::calculateDependencies();
-    if (isset($this->breakpointGroup)) {
-      // @todo Implement toArray() so we do not have reload the
-      //   entity since this property is changed in
-      //   \Drupal\responsive_image\Entity\ResponsiveImageMapping::save().
-      $breakpoint_group = \Drupal::entityManager()->getStorage('breakpoint_group')->load($this->breakpointGroup);
-      $this->addDependency('entity', $breakpoint_group->getConfigDependencyName());
-    }
-    return $this->dependencies;
-  }
-
-  /**
-   * Overrides Drupal\Core\Entity::save().
-   */
-  public function save() {
-    // Only save the keys, but return the full objects.
-    $breakpoint_group = $this->getBreakpointGroup();
-    if ($breakpoint_group && is_object($breakpoint_group)) {
-      $this->setBreakpointGroup($breakpoint_group->id());
-    }
-
-    // Split the breakpoint ids into their different parts, as dots as
-    // identifiers are not possible.
-    $loaded_mappings = $this->mappings;
-    $this->mappings = array();
-    foreach ($loaded_mappings as $breakpoint_id => $mapping) {
-      list($source_type, $source, $name) = explode('.', $breakpoint_id);
-      $this->mappings[$source_type][$source][$name] = $mapping;
+  public function addMapping($breakpoint_id, $multiplier, $image_style) {
+    foreach ($this->mappings as &$mapping) {
+      if ($mapping['breakpoint_id'] === $breakpoint_id && $mapping['multiplier'] === $multiplier) {
+        $mapping['image_style'] = $image_style;
+        return $this;
+      }
     }
-
-    parent::save();
-    $this->loadBreakpointGroup();
-    $this->loadAllMappings();
+    $this->mappings[] = array(
+      'breakpoint_id' => $breakpoint_id,
+      'multiplier' => $multiplier,
+      'image_style' => $image_style,
+    );
+    return $this;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::createDuplicate().
+   * {@inheritdoc}
    */
-  public function createDuplicate() {
-    return entity_create('responsive_image_mapping', array(
-      'id' => '',
-      'label' => t('Clone of !label', array('!label' => String::checkPlain($this->label()))),
-      'mappings' => $this->getMappings(),
-    ));
+  public function hasMappings() {
+    return !empty($this->mappings);
   }
 
   /**
-   * Loads the breakpoint group.
+   * {@inheritdoc}
    */
-  protected function loadBreakpointGroup() {
-    if ($this->getBreakpointGroup()) {
-      $breakpoint_group = entity_load('breakpoint_group', $this->getBreakpointGroup());
-      $this->setBreakpointGroup($breakpoint_group);
+  public function getKeyedMappings() {
+    if (!$this->keyedMappings) {
+      $this->keyedMappings = array();
+      $valid_breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($this->breakpointGroup);
+      foreach($this->mappings as $mapping) {
+        // If the breakpoint exists and the multiplier exists.
+        // @todo think about if this is just super defensive?
+        if (isset($valid_breakpoints[$mapping['breakpoint_id']])
+          && in_array($mapping['multiplier'], $valid_breakpoints[$mapping['breakpoint_id']]['multipliers'])) {
+          $this->keyedMappings[$mapping['breakpoint_id']][$mapping['multiplier']] = $mapping['image_style'];
+        }
+      }
     }
+    return $this->keyedMappings;
   }
 
   /**
-   * Loads all mappings and removes non-existing ones.
+   * {@inheritdoc}
    */
-  protected function loadAllMappings() {
-    $loaded_mappings = $this->getMappings();
-    $all_mappings = array();
-    if ($breakpoint_group = $this->getBreakpointGroup()) {
-      foreach ($breakpoint_group->getBreakpoints() as $breakpoint_id => $breakpoint) {
-        // Get the components of the breakpoint ID to match the format of the
-        // configuration file.
-        list($source_type, $source, $name) = explode('.', $breakpoint_id);
-
-        // Get the mapping for the default multiplier.
-        $all_mappings[$breakpoint_id]['1x'] = '';
-        if (isset($loaded_mappings[$source_type][$source][$name]['1x'])) {
-          $all_mappings[$breakpoint_id]['1x'] = $loaded_mappings[$source_type][$source][$name]['1x'];
-        }
-
-        // Get the mapping for the other multipliers.
-        if (isset($breakpoint->multipliers) && !empty($breakpoint->multipliers)) {
-          foreach ($breakpoint->multipliers as $multiplier => $status) {
-            if ($status) {
-              $all_mappings[$breakpoint_id][$multiplier] = '';
-              if (isset($loaded_mappings[$source_type][$source][$name][$multiplier])) {
-                $all_mappings[$breakpoint_id][$multiplier] = $loaded_mappings[$source_type][$source][$name][$multiplier];
-              }
-            }
-          }
-        }
-      }
+  public function getImageStyle($breakpoint_id, $multiplier) {
+    $map = $this->getKeyedMappings();
+    if (isset($map[$breakpoint_id][$multiplier])) {
+      return $map[$breakpoint_id][$multiplier];
     }
-    $this->setMappings($all_mappings);
   }
 
   /**
    * {@inheritdoc}
    */
-  public function hasMappings() {
-    $mapping_found = FALSE;
-    foreach ($this->getMappings() as $multipliers) {
-      $filtered_array = array_filter($multipliers);
-      if (!empty($filtered_array)) {
-        $mapping_found = TRUE;
-        break;
-      }
-    }
-    return $mapping_found;
+  public function getMappings() {
+    return $this->get('mappings');
   }
 
   /**
    * {@inheritdoc}
    */
-  public function setMappings(array $mappings) {
-    $this->set('mappings', $mappings);
+  public function setBreakpointGroup($breakpoint_group) {
+    $this->set('breakpointGroup', $breakpoint_group);
     return $this;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getMappings() {
-    return $this->get('mappings');
+  public function getBreakpointGroup() {
+    return $this->get('breakpointGroup');
   }
 
   /**
    * {@inheritdoc}
    */
-  public function setBreakpointGroup($breakpoint_group) {
-    $this->set('breakpointGroup', $breakpoint_group);
+  public function removeMappings() {
+    $this->mappings = array();
     return $this;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getBreakpointGroup() {
-    return $this->get('breakpointGroup');
+  public function calculateDependencies() {
+    parent::calculateDependencies();
+    $group = $this->getBreakpointGroup();
+    $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($group);
+    foreach ($breakpoints as $breakpoint) {
+      if (isset($breakpoint['provider'])) {
+        if (\Drupal::moduleHandler()->moduleExists($breakpoint['provider'])) {
+          $this->addDependency('module', $breakpoint['provider']);
+        }
+        elseif (\Drupal::service('theme_handler')->themeExists($breakpoint['provider'])) {
+          $this->addDependency('theme', $breakpoint['provider']);
+        }
+      }
+    }
+    return $this->dependencies;
   }
+
 }
diff --git a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php
index 24a80d4..68aa58b 100644
--- a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php
+++ b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php
@@ -132,59 +132,35 @@ public function viewElements(FieldItemListInterface $items) {
       $link_file = TRUE;
     }
 
-    $breakpoint_styles = array();
     $fallback_image_style = '';
 
-    $responsive_image_mapping = entity_load('responsive_image_mapping', $this->getSetting('responsive_image_mapping'));
-    if ($responsive_image_mapping) {
-      foreach ($responsive_image_mapping->getMappings() as $breakpoint_name => $multipliers) {
-        // Make sure there are multipliers.
-        if (!empty($multipliers)) {
-          // Make sure that the breakpoint exists and is enabled.
-          // @todo add the following when breakpoint->status is added again:
-          // $responsive_image_mapping->breakpointGroup->breakpoints[$breakpoint_name]->status
-          $breakpoint = $responsive_image_mapping->getBreakpointGroup()->getBreakpointById($breakpoint_name);
-          if ($breakpoint) {
-            // Determine the enabled multipliers.
-            $multipliers = array_intersect_key($multipliers, $breakpoint->multipliers);
-            foreach ($multipliers as $multiplier => $image_style) {
-              // Make sure the multiplier still exists.
-              if (!empty($image_style)) {
-                // First mapping found is used as fallback.
-                if (empty($fallback_image_style)) {
-                  $fallback_image_style = $image_style;
-                }
-                if (!isset($breakpoint_styles[$breakpoint_name])) {
-                  $breakpoint_styles[$breakpoint_name] = array();
-                }
-                $breakpoint_styles[$breakpoint_name][$multiplier] = $image_style;
-              }
-            }
-          }
-        }
-      }
-    }
-
     // Check if the user defined a custom fallback image style.
     if ($this->getSetting('fallback_image_style')) {
       $fallback_image_style = $this->getSetting('fallback_image_style');
     }
 
     // Collect cache tags to be added for each item in the field.
+    $responsive_image_mapping = entity_load('responsive_image_mapping', $this->getSetting('responsive_image_mapping'));
+    $image_styles_to_load = array();
+    if ($fallback_image_style) {
+      $image_styles_to_load[] = $fallback_image_style;
+    }
     $all_cache_tags = array();
     if ($responsive_image_mapping) {
       $all_cache_tags[] = $responsive_image_mapping->getCacheTag();
-      foreach ($breakpoint_styles as $breakpoint_name => $style_per_multiplier) {
-        foreach ($style_per_multiplier as $multiplier => $image_style_name) {
-          $image_style = entity_load('image_style', $image_style_name);
-          $all_cache_tags[] = $image_style->getCacheTag();
+      foreach ($responsive_image_mapping->getMappings() as $mapping) {
+        // First mapping found is used as fallback.
+        if (empty($fallback_image_style)) {
+          $fallback_image_style = $mapping['image_style'];
         }
+        $image_styles_to_load[] = $mapping['image_style'];
       }
     }
-    if ($fallback_image_style) {
-      $image_style = entity_load('image_style', $fallback_image_style);
+    $image_styles = entity_load_multiple('image_style', $image_styles_to_load);
+    foreach ($image_styles as $image_style) {
       $all_cache_tags[] = $image_style->getCacheTag();
     }
+
     $cache_tags = NestedArray::mergeDeepArray($all_cache_tags);
 
     foreach ($items as $delta => $item) {
@@ -203,7 +179,7 @@ public function viewElements(FieldItemListInterface $items) {
         ),
         '#item' => $item,
         '#image_style' => $fallback_image_style,
-        '#breakpoints' => $breakpoint_styles,
+        '#mapping_id' => $responsive_image_mapping ? $responsive_image_mapping->id() : '',
         '#path' => isset($uri) ? $uri : '',
         '#cache' => array(
           'tags' => $cache_tags,
diff --git a/core/modules/responsive_image/src/ResponsiveImageMappingForm.php b/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
index d1510dd..2e77d50 100644
--- a/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
+++ b/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
@@ -23,8 +23,6 @@ class ResponsiveImageMappingForm extends EntityForm {
    *   A nested array form elements comprising the form.
    * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   The current state of the form.
-   * @param \Drupal\responsive_image\ResponsiveImageMappingInterface $responsive_image_mapping
-   *   The entity being edited.
    *
    * @return array
    *   The array containing the complete form.
@@ -67,23 +65,23 @@ public function form(array $form, FormStateInterface $form_state) {
     $form['breakpointGroup'] = array(
       '#type' => 'select',
       '#title' => $this->t('Breakpoint group'),
-      '#default_value' => ($responsive_image_mapping->getBreakpointGroup() != '') ? $responsive_image_mapping->getBreakpointGroup()->id() : '',
-      '#options' => breakpoint_group_select_options(),
+      '#default_value' => $responsive_image_mapping->getBreakpointGroup(),
+      '#options' => \Drupal::service('breakpoint.manager')->getGroups(),
       '#required' => TRUE,
       '#description' => $description,
     );
 
     $image_styles = image_style_options(TRUE);
     $image_styles[RESPONSIVE_IMAGE_EMPTY_IMAGE] = $this->t('- empty image -');
-    foreach ($responsive_image_mapping->getMappings() as $breakpoint_id => $mapping) {
-      foreach ($mapping as $multiplier => $image_style) {
-        $breakpoint = $responsive_image_mapping->getBreakpointGroup()->getBreakpointById($breakpoint_id);
-        $label = $multiplier . ' ' . $breakpoint->name . ' [' . $breakpoint->mediaQuery . ']';
-        $form['mappings'][$breakpoint_id][$multiplier] = array(
+    $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($responsive_image_mapping->getBreakpointGroup());
+    foreach ($breakpoints as $breakpoint_id => $breakpoint) {
+      foreach ($breakpoint['multipliers'] as $multiplier) {
+        $label = $multiplier . ' ' . $breakpoint['label'] . ' [' . $breakpoint['mediaQuery'] . ']';
+        $form['keyed_mappings'][$breakpoint_id][$multiplier] = array(
           '#type' => 'select',
           '#title' => String::checkPlain($label),
           '#options' => $image_styles,
-          '#default_value' => $image_style,
+          '#default_value' => $responsive_image_mapping->getImageStyle($breakpoint_id, $multiplier),
           '#description' => $this->t('Select an image style for this breakpoint.'),
         );
       }
@@ -98,21 +96,12 @@ public function form(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function validate(array $form, FormStateInterface $form_state) {
-    /** @var \Drupal\responsive_image\ResponsiveImageMappingInterface $responsive_image_mapping */
-    $responsive_image_mapping = $this->entity;
-
     // Only validate on edit.
-    if ($form_state->hasValue('mappings')) {
-      $responsive_image_mapping->setMappings($form_state->getValue('mappings'));
-
+    if ($form_state->hasValue('keyed_mappings')) {
       // Check if another breakpoint group is selected.
       if ($form_state->getValue('breakpointGroup') != $form_state->getCompleteForm()['breakpointGroup']['#default_value']) {
-        // Remove the mappings.
-        $form_state->unsetValue('mappings');
-      }
-      // Make sure at least one mapping is defined.
-      elseif (!$responsive_image_mapping->isNew() && !$responsive_image_mapping->hasMappings()) {
-        $form_state->setErrorByName('mappings', $this->t('Please select at least one mapping.'));
+        // Remove the mappings since the breakpoint ID has changed.
+        $form_state->unsetValue('keyed_mappings');
       }
     }
   }
@@ -123,6 +112,15 @@ public function validate(array $form, FormStateInterface $form_state) {
   public function save(array $form, FormStateInterface $form_state) {
     /** @var \Drupal\responsive_image\ResponsiveImageMappingInterface $responsive_image_mapping */
     $responsive_image_mapping = $this->entity;
+    // Remove all the existing mappings and replace with submitted values.
+    $responsive_image_mapping->removeMappings();
+    if ($form_state->hasValue('keyed_mappings')) {
+      foreach ($form_state->getValue('keyed_mappings') as $breakpoint_id => $multipliers) {
+        foreach ($multipliers as $multiplier => $image_style) {
+          $responsive_image_mapping->addMapping($breakpoint_id, $multiplier, $image_style);
+        }
+      }
+    }
     $responsive_image_mapping->save();
 
     $this->logger('responsive_image')->notice('Responsive image mapping @label saved.', array('@label' => $responsive_image_mapping->label()));
diff --git a/core/modules/responsive_image/src/ResponsiveImageMappingInterface.php b/core/modules/responsive_image/src/ResponsiveImageMappingInterface.php
index bb8b535..fd9b28b 100644
--- a/core/modules/responsive_image/src/ResponsiveImageMappingInterface.php
+++ b/core/modules/responsive_image/src/ResponsiveImageMappingInterface.php
@@ -18,47 +18,81 @@
    * Checks if there is at least one mapping defined.
    *
    * return bool
-   *   Whether the entity has any responsive_image mappings.
+   *   Whether the entity has any responsive image mappings.
    */
   public function hasMappings();
 
   /**
-   * Sets the mappings for the responsive_image mapping.
+   * Returns the mappings of breakpoint ID and multiplier to image style.
    *
-   * The array is keyed by the Breakpoint Group Id and then then by each
-   * Breakpoints multipliers within the Breakpoint Group.
-   *
-   * @param array[] $mappings
-   *   The mappings the responsive_image mapping will be set with.
-   *
-   * @return $this
+   * @return array[]
+   *   The responsive image mappings. Keyed by breakpoint ID then multiplier.
+   *   The value is the image style ID.
    */
-  public function setMappings(array $mappings);
+  public function getKeyedMappings();
 
   /**
-   * Returns the mappings for the responsive_image mapping.
+   * Returns the mappings for the responsive image mapping.
    *
    * @return array[]
-   *   The responsive_imagemappings.
+   *   An array responsive image mappings. Each responsive mapping array
+   *   contains the following keys:
+   *   - breakpoint_id
+   *   - multiplier
+   *   - image_style
    */
   public function getMappings();
 
   /**
    * Sets the breakpoint group for the responsive_image mapping.
    *
-   * @param \Drupal\breakpoint\Entity\BreakpointGroup $breakpoint_group
-   *   The responsive_image mappings breakpoint group.
+   * @param string $breakpoint_group
+   *   The responsive image mapping breakpoint group.
    *
    * @return $this
    */
   public function setBreakpointGroup($breakpoint_group);
 
   /**
-   * Returns the breakpoint group for the responsive_image mapping.
+   * Returns the breakpoint group for the responsive image mapping.
    *
-   * @return \Drupal\breakpoint\Entity\BreakpointGroup
-   *   The responsive_image mappings breakpoint group.
+   * @return string
+   *   The breakpoint group.
    */
   public function getBreakpointGroup();
 
+  /**
+   * Gets the image style ID for a breakpoint ID and multiplier.
+   *
+   * @param string $breakpoint_id
+   *   The breakpoint ID.
+   * @param string $multiplier
+   *   The multiplier.
+   *
+   * @return string|null
+   *   The image style ID. Null if the mapping does not exist.
+   */
+  public function getImageStyle($breakpoint_id, $multiplier);
+
+  /**
+   * Adds a mapping to the responsive image configuration entity.
+   *
+   * @param string $breakpoint_id
+   *   The breakpoint ID.
+   * @param string $multiplier
+   *   The multiplier.
+   * @param string $image_style
+   *   The image style ID.
+   *
+   * @return $this
+   */
+  public function addMapping($breakpoint_id, $multiplier, $image_style);
+
+  /**
+   * Removes all mappings from the responsive image configuration entity.
+   *
+   * @return $this
+   */
+  public function removeMappings();
+
 }
diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php
index ca65b1d..42bde4f 100644
--- a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php
+++ b/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php
@@ -8,7 +8,6 @@
 namespace Drupal\responsive_image\Tests;
 
 use Drupal\simpletest\WebTestBase;
-use Drupal\breakpoint\Entity\Breakpoint;
 
 /**
  * Thoroughly test the administrative interface of the Responsive Image module.
@@ -18,18 +17,11 @@
 class ResponsiveImageAdminUITest extends WebTestBase {
 
   /**
-   * The breakpoint group for testing.
-   *
-   * @var \Drupal\breakpoint\Entity\BreakpointGroupInterface
-   */
-  protected $breakpointGroup;
-
-  /**
    * Modules to enable.
    *
    * @var array
    */
-  public static $modules = array('responsive_image');
+  public static $modules = array('responsive_image', 'responsive_image_test_module');
 
   /**
    * Drupal\simpletest\WebTestBase\setUp().
@@ -43,32 +35,6 @@ public function setUp() {
     ));
 
     $this->drupalLogin($this->admin_user);
-
-    // Add breakpoint_group and breakpoints.
-    $this->breakpointGroup = entity_create('breakpoint_group', array(
-      'name' => 'atestset',
-      'label' => 'A test set',
-      'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
-    ));
-
-    $breakpoint_names = array('small', 'medium', 'large');
-    for ($i = 0; $i < 3; $i++) {
-      $width = ($i + 1) * 200;
-      $breakpoint = entity_create('breakpoint', array(
-        'name' => $breakpoint_names[$i],
-        'mediaQuery' => "(min-width: {$width}px)",
-        'source' => 'user',
-        'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
-        'multipliers' => array(
-          '1.5x' => 0,
-          '2x' => '2x',
-        ),
-      ));
-      $breakpoint->save();
-      $this->breakpointGroup->addBreakpoints(array($breakpoint));
-    }
-    $this->breakpointGroup->save();
-
   }
 
   /**
@@ -81,13 +47,13 @@ public function testResponsiveImageAdmin() {
 
     // Add a new responsive image mapping, our breakpoint set should be selected.
     $this->drupalGet('admin/config/media/responsive-image-mapping/add');
-    $this->assertFieldByName('breakpointGroup', $this->breakpointGroup->id());
+    $this->assertFieldByName('breakpointGroup', 'responsive_image_test_module');
 
     // Create a new group.
     $edit = array(
       'label' => 'Mapping One',
       'id' => 'mapping_one',
-      'breakpointGroup' => $this->breakpointGroup->id(),
+      'breakpointGroup' => 'responsive_image_test_module',
     );
     $this->drupalPostForm('admin/config/media/responsive-image-mapping/add', $edit, t('Save'));
 
@@ -101,32 +67,32 @@ public function testResponsiveImageAdmin() {
     // Edit the group.
     $this->drupalGet('admin/config/media/responsive-image-mapping/mapping_one');
     $this->assertFieldByName('label', 'Mapping One');
-    $this->assertFieldByName('breakpointGroup', $this->breakpointGroup->id());
+    $this->assertFieldByName('breakpointGroup', 'responsive_image_test_module');
 
-    // Check if the dropdows are present for the mappings.
-    $this->assertFieldByName('mappings[custom.user.small][1x]', '');
-    $this->assertFieldByName('mappings[custom.user.small][2x]', '');
-    $this->assertFieldByName('mappings[custom.user.medium][1x]', '');
-    $this->assertFieldByName('mappings[custom.user.medium][2x]', '');
-    $this->assertFieldByName('mappings[custom.user.large][1x]', '');
-    $this->assertFieldByName('mappings[custom.user.large][2x]', '');
+    // Check if the dropdowns are present for the mappings.
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.mobile][1x]', '');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.mobile][2x]', '');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.narrow][1x]', '');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.narrow][2x]', '');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.wide][1x]', '');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.wide][2x]', '');
 
     // Save mappings for 1x variant only.
     $edit = array(
       'label' => 'Mapping One',
-      'breakpointGroup' => $this->breakpointGroup->id(),
-      'mappings[custom.user.small][1x]' => 'thumbnail',
-      'mappings[custom.user.medium][1x]' => 'medium',
-      'mappings[custom.user.large][1x]' => 'large',
+      'breakpointGroup' => 'responsive_image_test_module',
+      'keyed_mappings[responsive_image_test_module.mobile][1x]' => 'thumbnail',
+      'keyed_mappings[responsive_image_test_module.narrow][1x]' => 'medium',
+      'keyed_mappings[responsive_image_test_module.wide][1x]' => 'large',
     );
     $this->drupalPostForm('admin/config/media/responsive-image-mapping/mapping_one', $edit, t('Save'));
     $this->drupalGet('admin/config/media/responsive-image-mapping/mapping_one');
-    $this->assertFieldByName('mappings[custom.user.small][1x]', 'thumbnail');
-    $this->assertFieldByName('mappings[custom.user.small][2x]', '');
-    $this->assertFieldByName('mappings[custom.user.medium][1x]', 'medium');
-    $this->assertFieldByName('mappings[custom.user.medium][2x]', '');
-    $this->assertFieldByName('mappings[custom.user.large][1x]', 'large');
-    $this->assertFieldByName('mappings[custom.user.large][2x]', '');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.mobile][1x]', 'thumbnail');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.mobile][2x]', '');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.narrow][1x]', 'medium');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.narrow][2x]', '');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.wide][1x]', 'large');
+    $this->assertFieldByName('keyed_mappings[responsive_image_test_module.wide][2x]', '');
 
     // Delete the mapping.
     $this->drupalGet('admin/config/media/responsive-image-mapping/mapping_one/delete');
diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
index 27450e6..aa665d4 100644
--- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
+++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\responsive_image\Tests;
 
-use Drupal\breakpoint\Entity\Breakpoint;
 use Drupal\image\Tests\ImageFieldTestBase;
 
 /**
@@ -24,7 +23,7 @@ class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase {
    *
    * @var array
    */
-  public static $modules = array('field_ui', 'responsive_image');
+  public static $modules = array('field_ui', 'responsive_image', 'responsive_image_test_module');
 
   /**
    * Drupal\simpletest\WebTestBase\setUp().
@@ -47,45 +46,17 @@ public function setUp() {
       'administer image styles'
     ));
     $this->drupalLogin($this->admin_user);
-
-    // Add breakpoint_group and breakpoints.
-    $breakpoint_group = entity_create('breakpoint_group', array(
-      'name' => 'atestset',
-      'label' => 'A test set',
-      'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
-    ));
-
-    $breakpoint_names = array('small', 'medium', 'large');
-    for ($i = 0; $i < 3; $i++) {
-      $width = ($i + 1) * 200;
-      $breakpoint = entity_create('breakpoint', array(
-        'name' => $breakpoint_names[$i],
-        'mediaQuery' => "(min-width: {$width}px)",
-        'source' => 'user',
-        'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
-        'multipliers' => array(
-          '1.5x' => 0,
-          '2x' => '2x',
-        ),
-      ));
-      $breakpoint->save();
-      $breakpoint_group->addBreakpoints(array($breakpoint));
-    }
-    $breakpoint_group->save();
-
     // Add responsive image mapping.
     $responsive_image_mapping = entity_create('responsive_image_mapping', array(
       'id' => 'mapping_one',
       'label' => 'Mapping One',
-      'breakpointGroup' => $breakpoint_group->id(),
+      'breakpointGroup' => 'responsive_image_test_module',
     ));
-    $responsive_image_mapping->save();
-    $mappings = array();
-    $mappings['custom.user.small']['1x'] = 'thumbnail';
-    $mappings['custom.user.medium']['1x'] = 'medium';
-    $mappings['custom.user.large']['1x'] = 'large';
-    $responsive_image_mapping->setMappings($mappings);
-    $responsive_image_mapping->save();
+    $responsive_image_mapping
+      ->addMapping('responsive_image_test_module.mobile', '1x', 'thumbnail')
+      ->addMapping('responsive_image_test_module.narrow', '1x', 'medium')
+      ->addMapping('responsive_image_test_module.wide', '1x', 'large')
+      ->save();
   }
 
   /**
@@ -130,7 +101,9 @@ public function _testResponsiveImageFieldFormatters($scheme) {
     $display_options = array(
       'type' => 'responsive_image',
       'module' => 'responsive_image',
-      'settings' => array('image_link' => 'file'),
+      'settings' => array(
+        'image_link' => 'file'
+      ),
     );
     $display = entity_get_display('node', 'article', 'default');
     $display->setComponent($field_name, $display_options)
@@ -178,9 +151,9 @@ public function _testResponsiveImageFieldFormatters($scheme) {
     $this->assertRaw('/styles/thumbnail/');
     $this->assertRaw('/styles/medium/');
     $this->assertRaw('/styles/large/');
-    $this->assertRaw('media="(min-width: 200px)"');
-    $this->assertRaw('media="(min-width: 400px)"');
-    $this->assertRaw('media="(min-width: 600px)"');
+    $this->assertRaw('media="(min-width: 0px)"');
+    $this->assertRaw('media="(min-width: 560px)"');
+    $this->assertRaw('media="(min-width: 851px)"');
     $cache_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags'));
     $this->assertTrue(in_array('responsive_image_mapping:mapping_one', $cache_tags));
     $this->assertTrue(in_array('image_style:thumbnail', $cache_tags));
diff --git a/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.breakpoints.yml b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.breakpoints.yml
new file mode 100644
index 0000000..247ab23
--- /dev/null
+++ b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.breakpoints.yml
@@ -0,0 +1,21 @@
+responsive_image_test_module.mobile:
+  label: mobile
+  mediaQuery: '(min-width: 0px)'
+  weight: 0
+  multipliers:
+    - 1x
+    - 2x
+responsive_image_test_module.narrow:
+  label: narrow
+  mediaQuery: '(min-width: 560px)'
+  weight: 1
+  multipliers:
+    - 1x
+    - 2x
+responsive_image_test_module.wide:
+  label: wide
+  mediaQuery: '(min-width: 851px)'
+  weight: 2
+  multipliers:
+    - 1x
+    - 2x
diff --git a/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml
new file mode 100644
index 0000000..7610145
--- /dev/null
+++ b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml
@@ -0,0 +1,6 @@
+name: 'Responsive image test theme'
+type: module
+description: 'Test theme for responsive image.'
+version: VERSION
+core: 8.x
+
diff --git a/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityTest.php b/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityTest.php
deleted file mode 100644
index 506bd00..0000000
--- a/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityTest.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\responsive_image\Tests\ResponsiveImageMappingEntityTest.
- */
-
-namespace Drupal\responsive_image\Tests;
-
-use Drupal\responsive_image\Entity\ResponsiveImageMapping;
-use Drupal\Tests\UnitTestCase;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-
-/**
- * @coversDefaultClass \Drupal\responsive_image\Entity\ResponsiveImageMapping
- * @group responsive_image
- */
-class ResponsiveImageMappingEntityTest extends UnitTestCase {
-
-  /**
-   * The entity type used for testing.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityType;
-
-  /**
-   * The entity manager used for testing.
-   *
-   * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityManager;
-
-  /**
-   * The ID of the type of the entity under test.
-   *
-   * @var string
-   */
-  protected $entityTypeId;
-
-  /**
-   * The UUID generator used for testing.
-   *
-   * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $uuid;
-
-  /**
-   * The ID of the breakpoint group used for testing.
-   *
-   * @var string
-   */
-  protected $breakpointGroupId;
-
-  /**
-   * The breakpoint group used for testing.
-   *
-   * @var \Drupal\breakpoint\Entity\BreakpointGroup|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $breakpointGroup;
-
-  /**
-   * The breakpoint group storage used for testing.
-   *
-   * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $breakpointGroupStorage;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setUp() {
-    $this->entityTypeId = $this->randomMachineName();
-    $this->provider = $this->randomMachineName();
-    $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
-    $this->entityType->expects($this->any())
-                     ->method('getProvider')
-                     ->will($this->returnValue($this->provider));
-
-    $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
-    $this->entityManager->expects($this->any())
-                        ->method('getDefinition')
-                        ->with($this->entityTypeId)
-                        ->will($this->returnValue($this->entityType));
-
-    $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
-
-    $this->breakpointGroupId = $this->randomMachineName(9);
-    $this->breakpointGroup = $this->getMock('Drupal\breakpoint\Entity\BreakpointGroup', array(), array(array('name' => 'test', 'id' => $this->breakpointGroupId)));
-
-    $this->breakpointGroupStorage = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityStorageInterface');
-    $this->breakpointGroupStorage
-      ->expects($this->any())
-      ->method('load')
-      ->with($this->breakpointGroupId)
-      ->will($this->returnValue($this->breakpointGroup));
-
-    $this->entityManager->expects($this->any())
-      ->method('getStorage')
-      ->will($this->returnValue($this->breakpointGroupStorage));
-
-    $container = new ContainerBuilder();
-    $container->set('entity.manager', $this->entityManager);
-    $container->set('uuid', $this->uuid);
-    \Drupal::setContainer($container);
-  }
-
-  /**
-   * @covers ::calculateDependencies
-   */
-  public function testCalculateDependencies() {
-    $responsive_image_mapping = new ResponsiveImageMapping(array(), $this->entityTypeId);
-    // Set the breakpoint group after creating the entity to avoid the calls
-    // in the constructor.
-    $responsive_image_mapping->setBreakpointGroup($this->breakpointGroupId);
-    $this->breakpointGroup->expects($this->once())
-      ->method('getConfigDependencyName')
-      ->will($this->returnValue('breakpoint.breakpoint_group.' . $this->breakpointGroupId));
-
-    $dependencies = $responsive_image_mapping->calculateDependencies();
-    $this->assertContains('breakpoint.breakpoint_group.' . $this->breakpointGroupId, $dependencies['entity']);
-  }
-
-}
diff --git a/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityUnitTest.php b/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityUnitTest.php
new file mode 100644
index 0000000..562ffd6
--- /dev/null
+++ b/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityUnitTest.php
@@ -0,0 +1,153 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\responsive_image\Tests\ResponsiveImageMappingEntityUnitTest.
+ */
+
+namespace Drupal\responsive_image\Tests;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\responsive_image\Entity\ResponsiveImageMapping;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass Drupal\responsive_image\Entity\ResponsiveImageMapping
+ * @group responsive_image
+ */
+class ResponsiveImageMappingEntityUnitTest extends UnitTestCase {
+
+  /**
+   * The entity type used for testing.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $entityType;
+
+  /**
+   * The entity manager used for testing.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $entityManager;
+
+  /**
+   * The ID of the type of the entity under test.
+   *
+   * @var string
+   */
+  protected $entityTypeId;
+
+  /**
+   * The UUID generator used for testing.
+   *
+   * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $uuid;
+
+  /**
+   * The breakpoint manager used for testing.
+   *
+   * @var \Drupal\breakpoint\BreakpointManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $breakpointManager;
+
+  /**
+   * The module handler used for testing.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $moduleHandler;
+
+  /**
+   * The module handler used for testing.
+   *
+   * @var \Drupal\Core\Extension\ThemeHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $themeHandler;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    $this->entityTypeId = $this->randomMachineName();
+
+    $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
+    $this->entityType->expects($this->any())
+      ->method('getProvider')
+      ->will($this->returnValue('responsive_image'));
+
+    $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
+    $this->entityManager->expects($this->any())
+      ->method('getDefinition')
+      ->with($this->entityTypeId)
+      ->will($this->returnValue($this->entityType));
+
+    $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
+
+    $this->breakpointManager = $this->getMock('\Drupal\breakpoint\BreakpointManagerInterface');
+
+    $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
+
+    $this->themeHandler = $this->getMock('\Drupal\Core\Extension\ThemeHandlerInterface');
+
+    $container = new ContainerBuilder();
+    $container->set('entity.manager', $this->entityManager);
+    $container->set('uuid', $this->uuid);
+    $container->set('breakpoint.manager', $this->breakpointManager);
+    $container->set('module_handler', $this->moduleHandler);
+    $container->set('theme_handler', $this->themeHandler);
+    \Drupal::setContainer($container);
+  }
+
+  /**
+   * @covers ::calculateDependencies
+   */
+  public function testCalculateDependencies() {
+    $this->breakpointManager->expects($this->any())
+      ->method('getBreakpointsByGroup')
+      ->with('test_group')
+      ->will($this->returnValue(array(
+        'some_module.mobile' => array(
+          'label' => 'Module Breakpoint',
+          'mediaQuery' => '(min-width: 0px)',
+          'provider' => 'some_module',
+          'multipliers' => array('1x', '2x'),
+        ),
+        'some_theme.narrow' => array(
+          'label' => 'Theme Breakpoint',
+          'mediaQuery' => 'all and (min-width: 480px) and (max-width: 959px)',
+          'provider' => 'some_theme',
+          'multipliers' => array('1x', '2x'),
+        )
+      )));
+    $this->moduleHandler->expects($this->any())
+      ->method('moduleExists')
+      ->with($this->logicalOr('some_module', 'some_theme'))
+      ->will($this->returnCallback(array($this, 'moduleExistsMock')));
+
+    $this->themeHandler->expects($this->any())
+      ->method('themeExists')
+      ->with('some_theme')
+      ->will($this->returnCallback(array($this, 'themeExistsMock')));
+    $values = array(
+      'label' => 'TestMapping',
+      'breakpointGroup' => 'test_group'
+    );
+    $mapping = new ResponsiveImageMapping($values, $this->entityTypeId);
+    $mapping->addMapping('some_module.mobile', '1x', 'thumbnail');
+    $mapping->addMapping('some_theme.narrow', '1x', 'medium');
+    $dependencies = $mapping->calculateDependencies();
+    $this->assertContains('some_module', $dependencies['module']);
+    $this->assertContains('some_theme', $dependencies['theme']);
+  }
+
+  public function moduleExistsMock($module) {
+    return $module == 'some_module';
+  }
+
+  public function themeExistsMock($theme) {
+    return $theme == 'some_theme';
+  }
+
+}
diff --git a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.narrow.yml b/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.narrow.yml
deleted file mode 100644
index 5fae446..0000000
--- a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.narrow.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: module.toolbar.narrow
-name: narrow
-label: narrow
-mediaQuery: 'only screen and (min-width: 16.5em)'
-source: toolbar
-sourceType: module
-weight: 0
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.standard.yml b/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.standard.yml
deleted file mode 100644
index feda076..0000000
--- a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.standard.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: module.toolbar.standard
-name: standard
-label: standard
-mediaQuery: 'only screen and (min-width: 38.125em)'
-source: toolbar
-sourceType: module
-weight: 1
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.wide.yml b/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.wide.yml
deleted file mode 100644
index 554b286..0000000
--- a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.wide.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: module.toolbar.wide
-name: wide
-label: wide
-mediaQuery: 'only screen and (min-width: 61em)'
-source: toolbar
-sourceType: module
-weight: 2
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/toolbar/config/install/breakpoint.breakpoint_group.module.toolbar.toolbar.yml b/core/modules/toolbar/config/install/breakpoint.breakpoint_group.module.toolbar.toolbar.yml
deleted file mode 100644
index 148cd20..0000000
--- a/core/modules/toolbar/config/install/breakpoint.breakpoint_group.module.toolbar.toolbar.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: module.toolbar.toolbar
-name: toolbar
-label: toolbar
-breakpoint_ids:
-  - module.toolbar.narrow
-  - module.toolbar.standard
-  - module.toolbar.wide
-source: toolbar
-sourceType: module
-status: true
-langcode: en
diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js
index 909708d..b99e0c7 100644
--- a/core/modules/toolbar/js/toolbar.js
+++ b/core/modules/toolbar/js/toolbar.js
@@ -11,9 +11,9 @@
   var options = $.extend(
     {
       breakpoints: {
-        'module.toolbar.narrow': '',
-        'module.toolbar.standard': '',
-        'module.toolbar.wide': ''
+        'toolbar.narrow': '',
+        'toolbar.standard': '',
+        'toolbar.wide': ''
       }
     },
     drupalSettings.toolbar,
@@ -156,7 +156,7 @@
      */
     mediaQueryChangeHandler: function (model, label, mql) {
       switch (label) {
-        case 'module.toolbar.narrow':
+        case 'toolbar.narrow':
           model.set({
             'isOriented': mql.matches,
             'isTrayToggleVisible': false
@@ -168,12 +168,12 @@
             model.set({'orientation': 'vertical'}, {validate: true});
           }
           break;
-        case 'module.toolbar.standard':
+        case 'toolbar.standard':
           model.set({
             'isFixed': mql.matches
           });
           break;
-        case 'module.toolbar.wide':
+        case 'toolbar.wide':
           model.set({
             'orientation': ((mql.matches) ? 'horizontal' : 'vertical')
           }, {validate: true});
diff --git a/core/modules/toolbar/toolbar.breakpoints.yml b/core/modules/toolbar/toolbar.breakpoints.yml
new file mode 100644
index 0000000..a68784a
--- /dev/null
+++ b/core/modules/toolbar/toolbar.breakpoints.yml
@@ -0,0 +1,18 @@
+toolbar.narrow:
+  label: narrow
+  mediaQuery: 'only screen and (min-width: 16.5em)'
+  weight: 0
+  multipliers:
+    - 1x
+toolbar.standard:
+  label: standard
+  mediaQuery: 'only screen and (min-width: 38.125em)'
+  weight: 1
+  multipliers:
+    - 1x
+toolbar.wide:
+  label: wide
+  mediaQuery: 'only screen and (min-width: 61em)'
+  weight: 2
+  multipliers:
+    - 1x
diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module
index a667e08..4d0389b 100644
--- a/core/modules/toolbar/toolbar.module
+++ b/core/modules/toolbar/toolbar.module
@@ -175,15 +175,12 @@ function toolbar_pre_render($element) {
 
   // Get the configured breakpoints to switch from vertical to horizontal
   // toolbar presentation.
-  $breakpoints = entity_load('breakpoint_group', 'module.toolbar.toolbar');
+  $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('toolbar');
   if (!empty($breakpoints)) {
     $media_queries = array();
-    $media_queries['toolbar']['breakpoints'] = array_map(
-      function ($object) {
-        return $object->mediaQuery;
-      },
-      $breakpoints->getBreakpoints()
-    );
+    foreach ($breakpoints as $id => $breakpoint) {
+      $media_queries['toolbar']['breakpoints'][$id] = $breakpoint['mediaQuery'];
+    }
 
     $element['#attached']['js'][] = array(
       'data' => $media_queries,
diff --git a/core/themes/bartik/bartik.breakpoints.yml b/core/themes/bartik/bartik.breakpoints.yml
new file mode 100644
index 0000000..17b9fc8
--- /dev/null
+++ b/core/themes/bartik/bartik.breakpoints.yml
@@ -0,0 +1,18 @@
+bartik.mobile:
+  label: mobile
+  mediaQuery: '(min-width: 0px)'
+  weight: 0
+  multipliers:
+    - 1x
+bartik.narrow:
+  label: narrow
+  mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)'
+  weight: 1
+  multipliers:
+    - 1x
+bartik.wide:
+  label: wide
+  mediaQuery: 'all and (min-width: 851px)'
+  weight: 2
+  multipliers:
+    - 1x
diff --git a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.mobile.yml b/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.mobile.yml
deleted file mode 100644
index 7add4c0..0000000
--- a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.mobile.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.bartik.mobile
-name: mobile
-label: mobile
-mediaQuery: '(min-width: 0px)'
-source: bartik
-sourceType: theme
-weight: 0
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.narrow.yml b/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.narrow.yml
deleted file mode 100644
index 0736ab6..0000000
--- a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.narrow.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.bartik.narrow
-name: narrow
-label: narrow
-mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)'
-source: bartik
-sourceType: theme
-weight: 1
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.wide.yml b/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.wide.yml
deleted file mode 100644
index d43f1ae..0000000
--- a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.wide.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.bartik.wide
-name: wide
-label: wide
-mediaQuery: 'all and (min-width: 851px)'
-source: bartik
-sourceType: theme
-weight: 2
-multipliers:
-  1x: 1x
-status: true
-langcode: en
diff --git a/core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml b/core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml
deleted file mode 100644
index a7d85fc..0000000
--- a/core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.bartik.bartik
-name: bartik
-label: Bartik
-breakpoint_ids:
-  - theme.bartik.mobile
-  - theme.bartik.narrow
-  - theme.bartik.wide
-source: bartik
-sourceType: theme
-status: true
-langcode: en
diff --git a/core/themes/seven/config/install/seven.breakpoints.yml b/core/themes/seven/config/install/seven.breakpoints.yml
deleted file mode 100644
index 9fd82d7..0000000
--- a/core/themes/seven/config/install/seven.breakpoints.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-mobile: '(min-width: 0em)'
-wide: 'screen and (min-width: 40em)'
diff --git a/core/themes/seven/seven.breakpoints.yml b/core/themes/seven/seven.breakpoints.yml
new file mode 100644
index 0000000..1b6bd2f
--- /dev/null
+++ b/core/themes/seven/seven.breakpoints.yml
@@ -0,0 +1,12 @@
+seven.mobile:
+  label: mobile
+  mediaQuery: '(min-width: 0em)'
+  weight: 0
+  multipliers:
+    - 1x
+seven.wide:
+  label: wide
+  mediaQuery: 'screen and (min-width: 40em)'
+  weight: 1
+  multipliers:
+    - 1x
diff --git a/core/themes/stark/config/install/stark.breakpoints.yml b/core/themes/stark/config/install/stark.breakpoints.yml
deleted file mode 100644
index e2eb626..0000000
--- a/core/themes/stark/config/install/stark.breakpoints.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-mobile: '(min-width: 0px)'
-narrow: 'all and (min-width: 480px) and (max-width: 959px)'
-wide: 'all and (min-width: 960px)'
diff --git a/core/themes/stark/stark.breakpoints.yml b/core/themes/stark/stark.breakpoints.yml
new file mode 100644
index 0000000..0442687
--- /dev/null
+++ b/core/themes/stark/stark.breakpoints.yml
@@ -0,0 +1,19 @@
+stark.mobile:
+  label: mobile
+  mediaQuery: '(min-width: 0px)'
+  weight: 0
+  multipliers:
+    - 1x
+stark.narrow:
+  label: narrow
+  mediaQuery: 'all and (min-width: 480px) and (max-width: 959px)'
+  weight: 1
+  multipliers:
+    - 1x
+stark.wide:
+  name: wide
+  label: wide
+  mediaQuery: 'all and (min-width: 960px)'
+  weight: 2
+  multipliers:
+    - 1x
