diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorCategoryBlock.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorCategoryBlock.php
index 4c2df27..3e7f642 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorCategoryBlock.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorCategoryBlock.php
@@ -58,7 +58,9 @@ public function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['block_count'] = $form_state['values']['block_count'];
+    return array(
+      'block_count' => $form_state['values']['block_count'],
+    );
   }
 
   /**
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorFeedBlock.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorFeedBlock.php
index e902eb5..79439cb 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorFeedBlock.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorFeedBlock.php
@@ -58,7 +58,9 @@ public function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['block_count'] = $form_state['values']['block_count'];
+    return array(
+      'block_count' => $form_state['values']['block_count'],
+    );
   }
 
   /**
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorRenderingTest.php b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorRenderingTest.php
index cd083b7..1f13232 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorRenderingTest.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorRenderingTest.php
@@ -38,6 +38,10 @@ public function testBlockLinks() {
     $feed = $this->createFeed();
     $this->updateFeedItems($feed, $this->getDefaultFeedItemCount());
 
+    // Clear the block cache to load the new block definitions.
+    $manager = $this->container->get('plugin.manager.block');
+    $manager->clearCachedDefinitions();
+
     // Need admin user to be able to access block admin.
     $admin_user = $this->drupalCreateUser(array(
       'administer blocks',
@@ -47,16 +51,11 @@ public function testBlockLinks() {
     ));
     $this->drupalLogin($admin_user);
 
-    $current_theme = variable_get('theme_default', 'stark');
-    $machine_name = 'test_aggregator_feed_block';
     $block = array(
-      'machine_name' => $machine_name,
-      'region' => 'footer',
       'title' => 'feed-' . $feed->title,
       'block_count' => 2,
     );
-    $this->drupalPost("admin/structure/block/manage/aggregator_feed_block:{$feed->fid}/$current_theme", $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Block was saved.');
+    $this->drupalPlaceBlock("aggregator_feed_block:{$feed->fid}", $block);
 
     // Confirm that the block is now being displayed on pages.
     $this->drupalGet('node');
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Tests/ImportOpmlTest.php b/core/modules/aggregator/lib/Drupal/aggregator/Tests/ImportOpmlTest.php
index 5eb110f..7a9f463 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Tests/ImportOpmlTest.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/ImportOpmlTest.php
@@ -49,15 +49,7 @@ function openImportForm() {
       ->execute();
 
     // Enable the help block.
-    $block_id = 'system_help_block';
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'help',
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), '"Help" block enabled');
+    $this->drupalPlaceBlock('system_help_block', array('region' => 'help'));
 
     $this->drupalGet('admin/config/services/aggregator/add/opml');
     $this->assertText('A single OPML document may contain a collection of many feeds.', 'Found OPML help text.');
diff --git a/core/modules/block/block.admin.inc b/core/modules/block/block.admin.inc
index 13f17ad..2c57578 100644
--- a/core/modules/block/block.admin.inc
+++ b/core/modules/block/block.admin.inc
@@ -56,7 +56,7 @@ function block_admin_display_prepare_blocks($theme) {
   $blocks = _block_rehash($theme);
   $compare_theme = &drupal_static('_block_compare:theme');
   $compare_theme = $theme;
-  usort($blocks, '_block_compare');
+  uasort($blocks, '_block_compare');
   return $blocks;
 }
 
@@ -115,11 +115,6 @@ function block_admin_display_form($form, &$form_state, $blocks, $theme, $block_r
   $form['#tree'] = TRUE;
 
   foreach ($blocks as $key => $instance) {
-    $block = $instance->getConfig();
-    $form['blocks'][$key]['config_id'] = array(
-      '#type' => 'value',
-      '#value' => $block['config_id'],
-    );
     $info = $instance->getDefinition();
     $form['blocks'][$key]['info'] = array(
       '#markup' => check_plain($info['subject']),
@@ -130,14 +125,14 @@ function block_admin_display_form($form, &$form_state, $blocks, $theme, $block_r
     );
     $form['blocks'][$key]['weight'] = array(
       '#type' => 'weight',
-      '#default_value' => $block['weight'],
+      '#default_value' => $instance->get('weight'),
       '#delta' => $weight_delta,
       '#title_display' => 'invisible',
       '#title' => t('Weight for @block block', array('@block' => $info['subject'])),
     );
     $form['blocks'][$key]['region'] = array(
       '#type' => 'select',
-      '#default_value' => $block['region'] != BLOCK_REGION_NONE ? $block['region'] : NULL,
+      '#default_value' => $instance->get('region') != BLOCK_REGION_NONE ? $instance->get('region') : NULL,
       '#empty_value' => BLOCK_REGION_NONE,
       '#title_display' => 'invisible',
       '#title' => t('Region for @block block', array('@block' => $info['subject'])),
@@ -145,11 +140,11 @@ function block_admin_display_form($form, &$form_state, $blocks, $theme, $block_r
     );
     $links['configure'] = array(
       'title' => t('configure'),
-      'href' => 'admin/structure/block/manage/' . $block['config_id'] . '/' . $theme . '/configure',
+      'href' => 'admin/structure/block/manage/' . $key . '/' . $theme . '/configure',
     );
     $links['delete'] = array(
       'title' => t('delete'),
-      'href' => 'admin/structure/block/manage/' . $block['config_id'] . '/' . $theme . '/delete',
+      'href' => 'admin/structure/block/manage/' . $key . '/' . $theme . '/delete',
     );
     $form['blocks'][$key]['operations'] = array(
       '#type' => 'operations',
@@ -180,11 +175,11 @@ function block_admin_display_form($form, &$form_state, $blocks, $theme, $block_r
  * @see block_admin_display_form()
  */
 function block_admin_display_form_submit($form, &$form_state) {
-  foreach ($form_state['values']['blocks'] as $block) {
-    $config = config($block['config_id']);
-    $config->set('weight', $block['weight']);
-    $config->set('region', $block['region']);
-    $config->save();
+  $blocks = entity_load_multiple('block', array_keys($form_state['values']['blocks']));
+  foreach ($blocks as $block_id => $block) {
+    $block->set('weight', $form_state['values']['blocks'][$block_id]['weight']);
+    $block->set('region', $form_state['values']['blocks'][$block_id]['region']);
+    $block->save();
   }
   drupal_set_message(t('The block settings have been updated.'));
   cache_invalidate_tags(array('content' => TRUE));
@@ -195,10 +190,8 @@ function block_admin_display_form_submit($form, &$form_state) {
  *
  * Callback for usort() in block_admin_display_prepare_blocks().
  */
-function _block_compare($ainstance, $binstance) {
+function _block_compare($a, $b) {
   global $theme_key;
-  $a = $ainstance->getConfig();
-  $b = $binstance->getConfig();
 
   // Theme should be set before calling this function, or the current theme
   // is being used.
@@ -215,24 +208,26 @@ function _block_compare($ainstance, $binstance) {
   }
 
   // Separate enabled from disabled.
-  $status = $b['status'] - $a['status'];
+  $status = $b->get('status') - $a->get('status');
   if ($status) {
     return $status;
   }
   // Sort by region (in the order defined by theme .info file).
-  if ((!empty($a['region']) && !empty($b['region'])) && ($place = ($regions[$a['region']] - $regions[$b['region']]))) {
+  $aregion = $a->get('region');
+  $bregion = $b->get('region');
+  if ((!empty($aregion) && !empty($bregion)) && ($place = ($regions[$aregion] - $regions[$bregion]))) {
     return $place;
   }
   // Sort by weight, unless disabled.
-  if ($a['region'] != BLOCK_REGION_NONE) {
-    $weight = $a['weight'] - $b['weight'];
+  if ($a->get('region') != BLOCK_REGION_NONE) {
+    $weight = $a->get('weight') - $b->get('weight');
     if ($weight) {
       return $weight;
     }
   }
   // Sort by title.
-  $ainfo = $ainstance->getDefinition();
-  $binfo = $binstance->getDefinition();
+  $ainfo = $a->getDefinition();
+  $binfo = $b->getDefinition();
   return strcmp($ainfo['subject'], $binfo['subject']);
 }
 
@@ -252,22 +247,9 @@ function _block_compare($ainstance, $binstance) {
  *
  * @ingroup forms
  */
-function block_admin_configure($form, &$form_state, $plugin_id, $theme = NULL) {
-  $instance = block_load($plugin_id);
-  $form['#instance'] = $instance;
-  $config = $instance->getConfig();
-  if (!isset($config['config_id']) && !$theme) {
-    $theme = variable_get('theme_default', 'stark');
-  }
-  elseif (!$theme && isset($config['config_id'])) {
-    list(, , , $theme) = explode('.', $config['config_id']);
-  }
-  $form['theme'] = array(
-    '#type' => 'value',
-    '#value' => $theme,
-  );
-  $form += $instance->form($form, $form_state);
-  return $form;
+function block_admin_configure($plugin_id, $theme = NULL) {
+  $instance = block_load($plugin_id, array('theme' => $theme));
+  return entity_get_form($instance);
 }
 
 /**
@@ -288,14 +270,6 @@ function block_admin_configure_validate($form, &$form_state) {
  */
 function block_admin_configure_submit($form, &$form_state) {
   $form['#instance']->submit($form, $form_state);
-  $config_values = $form['#instance']->getConfig();
-  $machine_name = 'plugin.core.block.' . $form_state['values']['theme'] . '.' . $form_state['values']['machine_name'];
-  $config = config($machine_name);
-  $config->set('id', $form['#instance']->getPluginId());
-  foreach ($config_values as $key => $value) {
-    $config->set($key, $value);
-  }
-  $config->save();
   drupal_set_message(t('The block configuration has been saved.'));
   cache_invalidate_tags(array('content' => TRUE));
   $form_state['redirect'] = 'admin/structure/block/list/block_plugin_ui:' . $form_state['values']['theme'];
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 31ef8db..1caf798 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -121,8 +121,8 @@ function block_menu() {
   );
   $items['admin/structure/block/manage/%/%'] = array(
     'title' => 'Configure block',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('block_admin_configure', 4, 5),
+    'page callback' => 'block_admin_configure',
+    'page arguments' => array(4, 5),
     'access arguments' => array('administer blocks'),
     'file' => 'block.admin.inc',
   );
@@ -304,15 +304,13 @@ function _block_get_renderable_region($list = array()) {
     !in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD'));
 
   foreach ($list as $key => $block) {
-    $config = $block->getConfig();
-    $definition = $block->getDefinition();
     $build[$key] = array(
       '#block' => $block,
-      '#weight' => (int) $config['weight'],
+      '#weight' => $block->get('weight'),
       '#theme_wrappers' => array('block'),
     );
 
-    if ($not_cacheable || in_array($config['cache'], array(DRUPAL_NO_CACHE, DRUPAL_CACHE_CUSTOM))) {
+    if ($not_cacheable || in_array($block->get('cache'), array(DRUPAL_NO_CACHE, DRUPAL_CACHE_CUSTOM))) {
       // Non-cached blocks get built immediately. Provides more content
       // that can be easily manipulated during hook_page_alter().
       $build[$key] = _block_get_renderable_block($build[$key]);
@@ -323,8 +321,8 @@ function _block_get_renderable_region($list = array()) {
       $build[$key] += array(
         '#pre_render' => array('_block_get_renderable_block'),
         '#cache' => array(
-          'keys' => array($id, $config['module']),
-          'granularity' => $config['cache'],
+          'keys' => array($id, $block->get('module')),
+          'granularity' => $block->get('cache'),
           'bin' => 'block',
           'tags' => array('content' => TRUE),
         ),
@@ -336,7 +334,7 @@ function _block_get_renderable_region($list = array()) {
     // skip the help block, since we assume that most users do not need or want
     // to perform contextual actions on the help block, and the links needlessly
     // draw attention on it.
-    if ($definition['class'] != 'Drupal\\system\\Plugin\\block\\block\\SystemHelpBlock' && $definition['class'] != 'Drupal\\system\\Plugin\\block\\block\\SystemMainBlock') {
+    if (!in_array($block->getPluginId(), array('system_help_block', 'system_main_block'))) {
       global $theme;
       $build[$key]['#contextual_links']['block'] = array('admin/structure/block/manage', array($key, $theme));
     }
@@ -356,28 +354,29 @@ function _block_get_renderable_region($list = array()) {
  */
 function _block_rehash($theme = NULL) {
   $blocks = array();
-  $instances = array();
   $theme = $theme ? $theme : variable_get('theme_default', 'stark');
-  $block_configs = config_get_storage_names_with_prefix('plugin.core.block.' . $theme);
   $regions = system_region_list($theme);
-  foreach ($block_configs as $config) {
-    $blocks[$config] = block_load($config);
-    $config = config($config);
-    $region = $config->get('region');
-    $status = $config->get('status');
+  foreach (entity_load_multiple('block') as $block_id => $block) {
+    if (strpos($block_id, $theme . '.') !== 0) {
+      continue;
+    }
+
+    $blocks[$block_id] = $block;
+    $region = $block->get('region');
+    $status = $block->get('status');
     // Disable blocks in invalid regions.
     if (!empty($region) && $region != BLOCK_REGION_NONE && !isset($regions[$region]) && $status == 1) {
-      drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $config->get('id'), '%region' => $region)), 'warning');
+      drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block_id, '%region' => $region)), 'warning');
       // Disabled modules are moved into the BLOCK_REGION_NONE later so no
       // need to move the block to another region.
-      $config->set('status', 0);
-      $config->save();
+      $block->set('status', 0);
+      $block->save();
     }
     // Set region to none if not enabled and make sure status is set.
     if (empty($status)) {
-      $config->set('region', BLOCK_REGION_NONE);
-      $config->set('status', 0);
-      $config->save();
+      $block->set('region', BLOCK_REGION_NONE);
+      $block->set('status', 0);
+      $block->save();
     }
   }
   return $blocks;
@@ -466,19 +465,19 @@ function block_list($region) {
  *
  * @param string $plugin_id
  *   The plugin ID to load.
- * @param array $conf
+ * @param array $values
  *   An optional configuration array for creating a block instance manually
  *   rather than retrieving it from the configuration system.
  *
  * @return
  *   A block object.
  */
-function block_load($plugin_id, array $conf = array()) {
-  $manager = drupal_container()->get('plugin.manager.block');
-  if (!$block = $manager->getInstance(array('config' => $plugin_id))) {
-    $block = $manager->createInstance($plugin_id, $conf);
+function block_load($plugin_id, array $values = array()) {
+  if ($entity = entity_load('block', str_replace('plugin.core.block.', '', $plugin_id))) {
+    return $entity;
   }
-  return $block;
+  $values['pluginID'] = $plugin_id;
+  return entity_create('block', $values);
 }
 
 /**
@@ -490,12 +489,10 @@ function block_load($plugin_id, array $conf = array()) {
 function _block_load_blocks() {
   global $theme;
   $blocks = array();
-  $instances = config_get_storage_names_with_prefix('plugin.core.block.' . $theme);
-  $manager = drupal_container()->get('plugin.manager.block');
-  foreach ($instances as $plugin_id) {
-    $block = $manager->getInstance(array('config' => $plugin_id));
-    $config = $block->getConfig();
-    $blocks[$config['region']]["$plugin_id"] = $block;
+  foreach (entity_load_multiple('block') as $block_id => $block) {
+    if (strpos($block_id, $theme . '.') === 0) {
+      $blocks[$block->get('region')][$block_id] = $block;
+    }
   }
   return $blocks;
 }
@@ -515,7 +512,7 @@ function _block_get_renderable_block($element) {
   $block = $element['#block'];
   // Don't bother to build blocks that aren't accessible.
   if ($element['#access'] = $block->access()) {
-    $build = $block->build();
+    $build = $block->getPlugin()->build();
     if ($build) {
       if (isset($build['#title'])) {
         $element['#title'] = $build['#title'];
@@ -567,10 +564,12 @@ function block_rebuild() {
  */
 function template_preprocess_block(&$variables) {
   $block_counter = &drupal_static(__FUNCTION__, array());
-  $variables['block'] = (object) array_merge($variables['elements']['#block']->getDefinition(), $variables['elements']['#block']->getConfig());
-  if (!empty($variables['elements']['#title']) && empty($variables['block']->subject)) {
-    $variables['block']->subject = $variables['elements']['#title'];
+  $block = $variables['elements']['#block'];
+  $variables['block'] = (object) $block->getDefinition();
+  if ($label = $block->label()) {
+    $variables['block']->subject = $label;
   }
+
   // All blocks get an independent counter for each region.
   if (!isset($block_counter[$variables['block']->region])) {
     $block_counter[$variables['block']->region] = 1;
@@ -600,14 +599,14 @@ function template_preprocess_block(&$variables) {
 
   // We can safely explode on : because we know the Block plugin type manager
   // enforces that delimiter for all derivatives.
-  $parts = explode(':', $variables['elements']['#block']->getPluginId());
+  $parts = explode(':', $block->getPluginId());
   $suggestion = 'block';
   while ($part = array_shift($parts)) {
     $variables['theme_hook_suggestions'][] = $suggestion .= '__' . strtr($part, '-', '_');
   }
   // Create a valid HTML ID and make sure it is unique.
-  if (!empty($variables['block']->config_id)) {
-    $config_id = explode('.', $variables['block']->config_id);
+  if ($id = $block->id()) {
+    $config_id = explode('.', $id);
     $machine_name = array_pop($config_id);
     $variables['block_html_id'] = drupal_html_id('block-' . $machine_name);
     $variables['theme_hook_suggestions'][] = 'block__' . $machine_name;
@@ -620,14 +619,12 @@ function template_preprocess_block(&$variables) {
  * Removes deleted role from blocks that use it.
  */
 function block_user_role_delete($role) {
-  $block_configs = config_get_storage_names_with_prefix('plugin.core.block');
-  foreach ($block_configs as $config_id) {
-    $config = config($config_id);
-    $roles = $config->get('visibility.role.roles');
-    if (isset($roles[$role->rid])) {
-      unset($roles[$role->rid]);
-      $config->set('visibility.role.roles', $roles);
-      $config->save();
+  foreach (entity_load_multiple('block') as $block_id => $block) {
+    $visibility = $block->get('visibility');
+    if (isset($visibility['roles']['roles'][$role->rid])) {
+      unset($visibility['roles']['roles'][$role->rid]);
+      $block->set('visibility', $visibility);
+      $block->save();
     }
   }
 }
@@ -636,11 +633,9 @@ function block_user_role_delete($role) {
  * Implements hook_menu_delete().
  */
 function block_menu_delete($menu) {
-  $block_configs = config_get_storage_names_with_prefix('plugin.core.block');
-  foreach ($block_configs as $config_id) {
-    $config = config($config_id);
-    if ($config->get('id') == 'menu_menu_block:' . $menu['menu_name']) {
-      $config->delete();
+  foreach (entity_load_multiple('block') as $block_id => $block) {
+    if ($block->getPluginId() == 'menu_menu_block:' . $menu['menu_name']) {
+      $block->delete();
     }
   }
 }
@@ -658,35 +653,18 @@ function block_admin_paths() {
 }
 
 /**
- * Implements hook_modules_uninstalled().
- *
- * Cleans up any block configuration for uninstalled modules.
- */
-function block_modules_uninstalled($modules) {
-  $block_configs = config_get_storage_names_with_prefix('plugin.core.block');
-  foreach ($block_configs as $config_id) {
-    $config = config($config_id);
-    if (in_array($config->get('module'), $modules)) {
-      $config->delete();
-    }
-  }
-}
-
-/**
  * Implements hook_language_delete().
  *
  * Delete the potential block visibility settings of the deleted language.
  */
 function block_language_delete($language) {
   // Remove the block visibility settings for the deleted language.
-  $block_configs = config_get_storage_names_with_prefix('plugin.core.block');
-  foreach ($block_configs as $config_id) {
-    $config = config($config_id);
-    $languages = $config->get('visibility.language.langcodes');
-    if (isset($languages[$language->langcode])) {
-      unset($languages[$language->langcode]);
-      $config->set('visibility.language.langcodes', $languages);
-      $config->save();
+  foreach (entity_load_multiple('block') as $block_id => $block) {
+    $visibility = $block->get('visibility');
+    if (isset($visibility['language']['langcodes'][$language->langcode])) {
+      unset($visibility['language']['langcodes'][$language->langcode]);
+      $block->set('visibility', $visibility);
+      $block->save();
     }
   }
 }
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/block/block/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/block/block/CustomBlock.php
index 8b142ef..447b069 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/block/block/CustomBlock.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/block/block/CustomBlock.php
@@ -94,11 +94,13 @@ public function blockSubmit($form, &$form_state) {
       'bid' => is_numeric($bid) ? $bid : NULL,
     );
     drupal_write_record('block_custom', $block, !is_null($block['bid']) ? array('bid') : array());
-    $this->configuration['id'] = 'custom_block:' . $block['bid'];
     // Invalidate the block cache to update custom block-based derivatives.
     if (module_exists('block')) {
       drupal_container()->get('plugin.manager.block')->clearCachedDefinitions();
     }
+    return array(
+      'id' => 'custom_block:' . $block['bid'],
+    );
   }
 
   /**
diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php
index b8f770d..d11ead0 100644
--- a/core/modules/block/lib/Drupal/block/BlockBase.php
+++ b/core/modules/block/lib/Drupal/block/BlockBase.php
@@ -19,6 +19,22 @@
 abstract class BlockBase extends PluginBase implements BlockInterface {
 
   /**
+   * @todo.
+   *
+   * @var @todo.
+   */
+  protected $entity;
+
+  /**
+   * @todo.
+   */
+  public function init($entity) {
+    $this->entity = $entity;
+    // @todo.
+    $this->configuration = $entity->get('plugin');
+  }
+
+  /**
    * Implements \Drupal\block\BlockInterface::settings().
    *
    * Most block plugins should not override this method. To add additional
@@ -28,13 +44,7 @@
    * @see \Drupal\block\BlockBase::blockSettings()
    */
   public function settings() {
-    $settings = $this->blockSettings();
-    // By default, blocks are enabled and not cached.
-    $settings += array(
-      'status' => TRUE,
-      'cache' => DRUPAL_NO_CACHE,
-    );
-    return $settings;
+    return $this->blockSettings();
   }
 
   /**
@@ -118,313 +128,6 @@ public function blockAccess() {
   }
 
   /**
-   * Implements \Drupal\block\BlockInterface::access().
-   *
-   * Adds the user-configured per-role, per-path, and per-language visibility
-   * settings to all blocks, and invokes hook_block_access().
-   *
-   * Most plugins should not override this method unless they need to remove
-   * the user-defined access restrictions. To add specific access
-   * restrictions for a particular block type, override
-   * BlockBase::blockAccess() instead.
-   *
-   * @see hook_block_access()
-   * @see \Drupal\block\BlockBase::blockAccess()
-   */
-  public function access() {
-    // If the block-specific access restrictions indicate the block is not
-    // accessible, always deny access.
-    if (!$this->blockAccess()) {
-      return FALSE;
-    }
-
-    // Otherwise, check for other access restrictions.
-    global $user;
-
-    // Deny access to disabled blocks.
-    if (empty($this->configuration['status'])) {
-      return FALSE;
-    }
-
-    // User role access handling.
-    // If a block has no roles associated, it is displayed for every role.
-    // For blocks with roles associated, if none of the user's roles matches
-    // the settings from this block, access is denied.
-    if (!empty($this->configuration['visibility']['role']['roles']) && !array_intersect(array_filter($this->configuration['visibility']['role']['roles']), array_keys($user->roles))) {
-      // No match.
-      return FALSE;
-    }
-
-    // Page path handling.
-    // Limited visibility blocks must list at least one page.
-    if (!empty($this->configuration['visibility']['path']['visibility']) && $this->configuration['visibility']['path']['visibility'] == BLOCK_VISIBILITY_LISTED && empty($this->configuration['visibility']['path']['pages'])) {
-      return FALSE;
-    }
-
-    // Match path if necessary.
-    if (!empty($this->configuration['visibility']['path']['pages'])) {
-      // Assume there are no matches until one is found.
-      $page_match = FALSE;
-
-      // Convert path to lowercase. This allows comparison of the same path
-      // with different case. Ex: /Page, /page, /PAGE.
-      $pages = drupal_strtolower($this->configuration['visibility']['path']['pages']);
-      if ($this->configuration['visibility']['path']['visibility'] < BLOCK_VISIBILITY_PHP) {
-        // Compare the lowercase path alias (if any) and internal path.
-        $path = current_path();
-        $path_alias = drupal_strtolower(drupal_container()->get('path.alias_manager')->getPathAlias($path));
-        $page_match = drupal_match_path($path_alias, $pages) || (($path != $path_alias) && drupal_match_path($path, $pages));
-        // When $block->visibility has a value of 0
-        // (BLOCK_VISIBILITY_NOTLISTED), the block is displayed on all pages
-        // except those listed in $block->pages. When set to 1
-        // (BLOCK_VISIBILITY_LISTED), it is displayed only on those pages
-        // listed in $block->pages.
-        $page_match = !($this->configuration['visibility']['path']['visibility'] xor $page_match);
-      }
-      elseif (module_exists('php')) {
-        $page_match = php_eval($this->configuration['visibility']['path']['pages']);
-      }
-
-      // If there are page visibility restrictions and this page does not
-      // match, deny access.
-      if (!$page_match) {
-        return FALSE;
-      }
-    }
-
-    // Language visibility settings.
-    if (!empty($this->configuration['visibility']['language']['langcodes']) && array_filter($this->configuration['visibility']['language']['langcodes'])) {
-      if (empty($this->configuration['visibility']['language']['langcodes'][language($this->configuration['visibility']['language']['language_type'])->langcode])) {
-        return FALSE;
-      }
-    }
-
-    // Check other modules for block access rules.
-    foreach (module_implements('block_access') as $module) {
-      if (module_invoke($module, 'block_access', $this) === FALSE) {
-        return FALSE;
-      }
-    }
-
-    // If nothing denied access to the block, it is accessible.
-    return TRUE;
-  }
-
-  /**
-   * Implements \Drupal\block\BlockInterface::form().
-   *
-   * Creates a generic configuration form for all block types. Individual
-   * block plugins can add elements to this form by overriding
-   * BlockBase::blockForm(). Most block plugins should not override this
-   * method unless they need to alter the generic form elements.
-   *
-   * @see \Drupal\block\BlockBase::blockForm()
-   */
-  public function form($form, &$form_state) {
-    $definition = $this->getDefinition();
-    $config = $this->getConfig();
-    $form['id'] = array(
-      '#type' => 'value',
-      '#value' => $definition['id'],
-    );
-    $form['module'] = array(
-      '#type' => 'value',
-      '#value' => $definition['module'],
-    );
-
-    // Get the block subject for the page title.
-    $subject = isset($config['subject']) ? $config['subject'] : '';
-
-    // Get the theme for the page title.
-    $theme_default = variable_get('theme_default', 'stark');
-    $admin_theme = config('system.theme')->get('admin');
-    $themes = list_themes();
-    $theme_key = $form['theme']['#value'];
-    $theme = $themes[$theme_key];
-    // Use meaningful titles for the main site and administrative themes.
-    $theme_title = $theme->info['name'];
-    if ($theme_key == $theme_default) {
-      $theme_title = t('!theme (default theme)', array('!theme' => $theme_title));
-    }
-    elseif ($admin_theme && $theme_key == $admin_theme) {
-      $theme_title = t('!theme (administration theme)', array('!theme' => $theme_title));
-    }
-
-    if ($subject) {
-      drupal_set_title(t("%subject block in %theme", array('%subject' => $subject, '%theme' => $theme_title)), PASS_THROUGH);
-    }
-
-    $form['settings'] = array(
-      '#weight' => -5,
-    );
-    $form['settings']['title'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Block title'),
-      '#maxlength' => 255,
-      '#default_value' => isset($subject) ? $subject : '',
-    );
-    $form['settings']['machine_name'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Block machine name'),
-      '#maxlength' => 64,
-      '#description' => t('A unique name to save this block configuration. Must be alpha-numeric and be underscore separated.'),
-      '#default_value' => isset($config['config_id']) ? $config['config_id'] : '',
-      '#required' => TRUE,
-    );
-    if (isset($config['config_id'])) {
-      $form['settings']['machine_name']['#disabled'] = TRUE;
-    }
-
-    // Region settings.
-    $form['region'] = array(
-      '#type' => 'select',
-      '#title' => t('Region'),
-      '#description' => t('Select the region where this block should be displayed.'),
-      '#default_value' => !empty($config['region']) && $config['region'] != -1 ? $config['region'] : NULL,
-      '#empty_value' => BLOCK_REGION_NONE,
-      '#options' => system_region_list($theme_key, REGIONS_VISIBLE),
-    );
-
-
-    // Visibility settings.
-    $form['visibility_title'] = array(
-      '#type' => 'item',
-      '#title' => t('Visibility settings'),
-      '#weight' => 10,
-    );
-    $form['visibility'] = array(
-      '#type' => 'vertical_tabs',
-      '#attached' => array(
-        'js' => array(drupal_get_path('module', 'block') . '/block.js'),
-      ),
-      '#tree' => TRUE,
-      '#weight' => 15,
-    );
-
-    // Per-path visibility.
-    $form['visibility']['path'] = array(
-      '#type' => 'details',
-      '#title' => t('Pages'),
-      '#collapsed' => TRUE,
-      '#group' => 'visibility',
-      '#weight' => 0,
-    );
-
-    // @todo remove this access check and inject it in some other way. In fact
-    //   this entire visibility settings section probably needs a separate user
-    //   interface in the near future.
-    $access = user_access('use PHP for settings');
-    if (!empty($config['visibility']['path']['visibility']) && $config['visibility']['path']['visibility'] == BLOCK_VISIBILITY_PHP && !$access) {
-      $form['visibility']['path']['visibility'] = array(
-        '#type' => 'value',
-        '#value' => BLOCK_VISIBILITY_PHP,
-      );
-      $form['visibility']['path']['pages'] = array(
-        '#type' => 'value',
-        '#value' => !empty($config['visibility']['path']['pages']) ? $config['visibility']['path']['pages'] : '',
-      );
-    }
-    else {
-      $options = array(
-        BLOCK_VISIBILITY_NOTLISTED => t('All pages except those listed'),
-        BLOCK_VISIBILITY_LISTED => t('Only the listed pages'),
-      );
-      $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %user for the current user's page and %user-wildcard for every user page. %front is the front page.", array('%user' => 'user', '%user-wildcard' => 'user/*', '%front' => '<front>'));
-
-      if (module_exists('php') && $access) {
-        $options += array(BLOCK_VISIBILITY_PHP => t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'));
-        $title = t('Pages or PHP code');
-        $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'));
-      }
-      else {
-        $title = t('Pages');
-      }
-      $form['visibility']['path']['visibility'] = array(
-        '#type' => 'radios',
-        '#title' => t('Show block on specific pages'),
-        '#options' => $options,
-        '#default_value' => !empty($this->configuration['visibility']['path']['visibility']) ? $this->configuration['visibility']['path']['visibility'] : BLOCK_VISIBILITY_NOTLISTED,
-      );
-      $form['visibility']['path']['pages'] = array(
-        '#type' => 'textarea',
-        '#title' => '<span class="element-invisible">' . $title . '</span>',
-        '#default_value' => !empty($this->configuration['visibility']['path']['pages']) ? $this->configuration['visibility']['path']['pages'] : '',
-        '#description' => $description,
-      );
-    }
-
-    // Configure the block visibility per language.
-    if (module_exists('language') && language_multilingual()) {
-      $configurable_language_types = language_types_get_configurable();
-
-      // Fetch languages.
-      $languages = language_list(LANGUAGE_ALL);
-      foreach ($languages as $language) {
-        // @todo $language->name is not wrapped with t(), it should be replaced
-        //   by CMI translation implementation.
-        $langcodes_options[$language->langcode] = $language->name;
-      }
-      $form['visibility']['language'] = array(
-        '#type' => 'details',
-        '#title' => t('Languages'),
-        '#collapsed' => TRUE,
-        '#group' => 'visibility',
-        '#weight' => 5,
-      );
-      // If there are multiple configurable language types, let the user pick
-      // which one should be applied to this visibility setting. This way users
-      // can limit blocks by interface language or content language for exmaple.
-      $language_types = language_types_info();
-      $language_type_options = array();
-      foreach ($configurable_language_types as $type_key) {
-        $language_type_options[$type_key] = $language_types[$type_key]['name'];
-      }
-      $form['visibility']['language']['language_type'] = array(
-        '#type' => 'radios',
-        '#title' => t('Language type'),
-        '#options' => $language_type_options,
-        '#default_value' => !empty($this->configuration['visibility']['language']['language_type']) ? $this->configuration['visibility']['language']['language_type'] : $configurable_language_types[0],
-        '#access' => count($language_type_options) > 1,
-      );
-      $form['visibility']['language']['langcodes'] = array(
-        '#type' => 'checkboxes',
-        '#title' => t('Show this block only for specific languages'),
-        '#default_value' => !empty($this->configuration['visibility']['language']['langcodes']) ? $this->configuration['visibility']['language']['langcodes'] : array(),
-        '#options' => $langcodes_options,
-        '#description' => t('Show this block only for the selected language(s). If you select no languages, the block will be visibile in all languages.'),
-      );
-    }
-
-    // Per-role visibility.
-    $role_options = array_map('check_plain', user_roles());
-    $form['visibility']['role'] = array(
-      '#type' => 'details',
-      '#title' => t('Roles'),
-      '#collapsed' => TRUE,
-      '#group' => 'visibility',
-      '#weight' => 10,
-    );
-    $form['visibility']['role']['roles'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Show block for specific roles'),
-      '#default_value' => !empty($this->configuration['visibility']['role']['roles']) ? $this->configuration['visibility']['role']['roles'] : array(),
-      '#options' => $role_options,
-      '#description' => t('Show this block only for the selected role(s). If you select no roles, the block will be visible to all users.'),
-    );
-
-    // Add specific configuration for this block type.
-    $form += $this->blockForm($form, $form_state);
-
-    $form['actions'] = array('#type' => 'actions');
-    $form['actions']['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Save block'),
-    );
-
-    return $form;
-  }
-
-  /**
    * Returns the configuration form elements specific to this block plugin.
    *
    * Blocks that need to add form elements to the normal block configuration
@@ -445,44 +148,6 @@ public function blockForm($form, &$form_state) {
   }
 
   /**
-   * Implements \Drupal\block\BlockInterface::validate().
-   *
-   * Most block plugins should not override this method. To add validation
-   * for a specific block type, override BlockBase::blockValdiate().
-   *
-   * @todo Add inline documentation to this method.
-   *
-   * @see \Drupal\block\BlockBase::blockValidate()
-   */
-  public function validate($form, &$form_state) {
-    if (empty($form['settings']['machine_name']['#disabled'])) {
-      if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['machine_name'])) {
-        form_set_error('machine_name', t('Block name must be alphanumeric or underscores only.'));
-      }
-      if (in_array('plugin.core.block.' . $form_state['values']['machine_name'], config_get_storage_names_with_prefix('plugin.core.block'))) {
-        form_set_error('machine_name', t('Block name must be unique.'));
-      }
-    }
-    else {
-      $config_id = explode('.', $form_state['values']['machine_name']);
-      $form_state['values']['machine_name'] = array_pop($config_id);
-    }
-    if ($form_state['values']['module'] == 'block') {
-      $custom_block_exists = (bool) db_query_range('SELECT 1 FROM {block_custom} WHERE bid <> :bid AND info = :info', 0, 1, array(
-        ':bid' => $form_state['values']['delta'],
-        ':info' => $form_state['values']['info'],
-      ))->fetchField();
-      if (empty($form_state['values']['info']) || $custom_block_exists) {
-        form_set_error('info', t('Ensure that each block description is unique.'));
-      }
-    }
-    $form_state['values']['visibility']['role']['roles'] = array_filter($form_state['values']['visibility']['role']['roles']);
-
-    // Perform block type-specific validation.
-    $this->blockValidate($form, $form_state);
-  }
-
-  /**
    * Adds block type-specific validation for the block form.
    *
    * Note that this method takes the form structure and form state arrays for
@@ -501,47 +166,6 @@ public function validate($form, &$form_state) {
   public function blockValidate($form, &$form_state) {}
 
   /**
-   * Implements \Drupal\block\BlockInterface::submit().
-   *
-   * Most block plugins should not override this method. To add submission
-   * handling for a specific block type, override BlockBase::blockSubmit().
-   *
-   * @todo Add inline documentation to this method.
-   *
-   * @see \Drupal\block\BlockBase::blockSubmit()
-   */
-  public function submit($form, &$form_state) {
-    if (!form_get_errors()) {
-      $transaction = db_transaction();
-      try {
-        $keys = array(
-          'visibility' => 'visibility',
-          'pages' => 'pages',
-          'title' => 'subject',
-          'module' => 'module',
-          'region' => 'region',
-        );
-        foreach ($keys as $key => $new_key) {
-          if (isset($form_state['values'][$key])) {
-            $this->configuration[$new_key] = $form_state['values'][$key];
-          }
-        }
-      }
-      catch (Exception $e) {
-        $transaction->rollback();
-        watchdog_exception('block', $e);
-        throw $e;
-      }
-      if (empty($this->configuration['weight'])) {
-        $this->configuration['weight'] = 0;
-      }
-
-      // Perform block type-specific validation.
-      $this->blockSubmit($form, $form_state);
-    }
-  }
-
-  /**
    * Adds block type-specific submission handling for the block form.
    *
    * Note that this method takes the form structure and form state arrays for
@@ -557,7 +181,9 @@ public function submit($form, &$form_state) {
    * @see \Drupal\block\BlockBase::blockValidate()
    * @see \Drupal\block\BlockBase::submit()
    */
-  public function blockSubmit($form, &$form_state) {}
+  public function blockSubmit($form, &$form_state) {
+    return array();
+  }
 
   /**
    * Implements \Drupal\block\BlockInterface::build().
@@ -582,9 +208,7 @@ public function build() {
     // hook_block_view_NAME_alter().
     $id = str_replace(':', '__', $this->getPluginId());
 
-    $config = $this->getConfig();
-    $config_id = explode('.', $config['config_id']);
-    $name = array_pop($config_id);
+    $name = '';
 
     $build = $this->blockBuild();
     drupal_alter(array('block_view', "block_view_$id", "block_view_$name"), $build, $this);
diff --git a/core/modules/block/lib/Drupal/block/BlockFormController.php b/core/modules/block/lib/Drupal/block/BlockFormController.php
new file mode 100644
index 0000000..7e4b11c
--- /dev/null
+++ b/core/modules/block/lib/Drupal/block/BlockFormController.php
@@ -0,0 +1,272 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\block\BlockFormController.
+ */
+
+namespace Drupal\block;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityFormController;
+
+/**
+ * Form controller for the user account forms.
+ */
+class BlockFormController extends EntityFormController {
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityFormController::form().
+   */
+  public function form(array $form, array &$form_state, EntityInterface $entity) {
+    $definition = $entity->getDefinition();
+    $form['module'] = array(
+      '#type' => 'value',
+      '#value' => $definition['module'],
+    );
+    $form['id'] = array(
+      '#type' => 'value',
+      '#value' => $entity->id(),
+    );
+
+    // Get the theme for the page title.
+    $admin_theme = config('system.theme')->get('admin');
+    $themes = list_themes();
+    $theme_key = $entity->get('theme');
+    $theme = $themes[$theme_key];
+    // Use meaningful titles for the main site and administrative themes.
+    $theme_title = $theme->info['name'];
+    if ($theme_key == variable_get('theme_default', 'stark')) {
+      $theme_title = t('!theme (default theme)', array('!theme' => $theme_title));
+    }
+    elseif ($admin_theme && $theme_key == $admin_theme) {
+      $theme_title = t('!theme (administration theme)', array('!theme' => $theme_title));
+    }
+
+    // Get the block subject for the page title.
+    if ($label = $entity->label()) {
+      drupal_set_title(t("%label block in %theme", array('%label' => $label, '%theme' => $theme_title)), PASS_THROUGH);
+    }
+
+    $form['settings'] = array(
+      '#weight' => -5,
+    );
+    $form['settings']['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Block title'),
+      '#maxlength' => 255,
+      '#default_value' => $label,
+    );
+    $form['settings']['machine_name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Block machine name'),
+      '#maxlength' => 64,
+      '#description' => t('A unique name to save this block configuration. Must be alpha-numeric and be underscore separated.'),
+      '#default_value' => $entity->id(),
+      '#required' => TRUE,
+      '#disabled' => !$entity->isNew(),
+    );
+
+    // Region settings.
+    $form['region'] = array(
+      '#type' => 'select',
+      '#title' => t('Region'),
+      '#description' => t('Select the region where this block should be displayed.'),
+      '#default_value' => $entity->get('region'),
+      '#empty_value' => BLOCK_REGION_NONE,
+      '#options' => system_region_list($theme_key, REGIONS_VISIBLE),
+    );
+
+    // Visibility settings.
+    $form['visibility_title'] = array(
+      '#type' => 'item',
+      '#title' => t('Visibility settings'),
+      '#weight' => 10,
+    );
+    $form['visibility'] = array(
+      '#type' => 'vertical_tabs',
+      '#attached' => array(
+        'js' => array(drupal_get_path('module', 'block') . '/block.js'),
+      ),
+      '#tree' => TRUE,
+      '#weight' => 15,
+    );
+
+    // Per-path visibility.
+    $form['visibility']['path'] = array(
+      '#type' => 'details',
+      '#title' => t('Pages'),
+      '#collapsed' => TRUE,
+      '#group' => 'visibility',
+      '#weight' => 0,
+    );
+
+    // @todo remove this access check and inject it in some other way. In fact
+    //   this entire visibility settings section probably needs a separate user
+    //   interface in the near future.
+    $visibility = $entity->get('visibility');
+    $access = user_access('use PHP for settings');
+    if (!empty($visibility['path']['visibility']) && $visibility['path']['visibility'] == BLOCK_VISIBILITY_PHP && !$access) {
+      $form['visibility']['path']['visibility'] = array(
+        '#type' => 'value',
+        '#value' => BLOCK_VISIBILITY_PHP,
+      );
+      $form['visibility']['path']['pages'] = array(
+        '#type' => 'value',
+        '#value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '',
+      );
+    }
+    else {
+      $options = array(
+        BLOCK_VISIBILITY_NOTLISTED => t('All pages except those listed'),
+        BLOCK_VISIBILITY_LISTED => t('Only the listed pages'),
+      );
+      $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %user for the current user's page and %user-wildcard for every user page. %front is the front page.", array('%user' => 'user', '%user-wildcard' => 'user/*', '%front' => '<front>'));
+
+      if (module_exists('php') && $access) {
+        $options += array(BLOCK_VISIBILITY_PHP => t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'));
+        $title = t('Pages or PHP code');
+        $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'));
+      }
+      else {
+        $title = t('Pages');
+      }
+      $form['visibility']['path']['visibility'] = array(
+        '#type' => 'radios',
+        '#title' => t('Show block on specific pages'),
+        '#options' => $options,
+        '#default_value' => !empty($visibility['path']['visibility']) ? $visibility['path']['visibility'] : BLOCK_VISIBILITY_NOTLISTED,
+      );
+      $form['visibility']['path']['pages'] = array(
+        '#type' => 'textarea',
+        '#title' => '<span class="element-invisible">' . $title . '</span>',
+        '#default_value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '',
+        '#description' => $description,
+      );
+    }
+
+    // Configure the block visibility per language.
+    if (module_exists('language') && language_multilingual()) {
+      $configurable_language_types = language_types_get_configurable();
+
+      // Fetch languages.
+      $languages = language_list(LANGUAGE_ALL);
+      foreach ($languages as $language) {
+        // @todo $language->name is not wrapped with t(), it should be replaced
+        //   by CMI translation implementation.
+        $langcodes_options[$language->langcode] = $language->name;
+      }
+      $form['visibility']['language'] = array(
+        '#type' => 'details',
+        '#title' => t('Languages'),
+        '#collapsed' => TRUE,
+        '#group' => 'visibility',
+        '#weight' => 5,
+      );
+      // If there are multiple configurable language types, let the user pick
+      // which one should be applied to this visibility setting. This way users
+      // can limit blocks by interface language or content language for exmaple.
+      $language_types = language_types_info();
+      $language_type_options = array();
+      foreach ($configurable_language_types as $type_key) {
+        $language_type_options[$type_key] = $language_types[$type_key]['name'];
+      }
+      $form['visibility']['language']['language_type'] = array(
+        '#type' => 'radios',
+        '#title' => t('Language type'),
+        '#options' => $language_type_options,
+        '#default_value' => !empty($visibility['language']['language_type']) ? $visibility['language']['language_type'] : $configurable_language_types[0],
+        '#access' => count($language_type_options) > 1,
+      );
+      $form['visibility']['language']['langcodes'] = array(
+        '#type' => 'checkboxes',
+        '#title' => t('Show this block only for specific languages'),
+        '#default_value' => !empty($visibility['language']['langcodes']) ? $visibility['language']['langcodes'] : array(),
+        '#options' => $langcodes_options,
+        '#description' => t('Show this block only for the selected language(s). If you select no languages, the block will be visibile in all languages.'),
+      );
+    }
+
+    // Per-role visibility.
+    $role_options = array_map('check_plain', user_roles());
+    $form['visibility']['role'] = array(
+      '#type' => 'details',
+      '#title' => t('Roles'),
+      '#collapsed' => TRUE,
+      '#group' => 'visibility',
+      '#weight' => 10,
+    );
+    $form['visibility']['role']['roles'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Show block for specific roles'),
+      '#default_value' => !empty($visibility['role']['roles']) ? $visibility['role']['roles'] : array(),
+      '#options' => $role_options,
+      '#description' => t('Show this block only for the selected role(s). If you select no roles, the block will be visible to all users.'),
+    );
+
+    // Add specific configuration for this block type.
+    $form['plugin'] = $entity->getPlugin()->blockForm(array(), $form_state);
+
+    return parent::form($form, $form_state, $entity);
+  }
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityFormController::actions().
+   */
+  protected function actions(array $form, array &$form_state) {
+    $actions = parent::actions($form, $form_state);
+    $actions['submit']['#value'] = t('Save block');
+    return $actions;
+  }
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityFormController::validate().
+   */
+  public function validate(array $form, array &$form_state) {
+    parent::validate($form, $form_state);
+
+    if (empty($form['settings']['machine_name']['#disabled'])) {
+      if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['machine_name'])) {
+        form_set_error('machine_name', t('Block name must be alphanumeric or underscores only.'));
+      }
+      if (in_array('plugin.core.block.' . $form_state['values']['machine_name'], config_get_storage_names_with_prefix('plugin.core.block'))) {
+        form_set_error('machine_name', t('Block name must be unique.'));
+      }
+    }
+    else {
+      $config_id = explode('.', $form_state['values']['machine_name']);
+      $form_state['values']['machine_name'] = array_pop($config_id);
+    }
+    if ($form_state['values']['module'] == 'block') {
+      $custom_block_exists = (bool) db_query_range('SELECT 1 FROM {block_custom} WHERE bid <> :bid AND info = :info', 0, 1, array(
+        ':bid' => $form_state['values']['delta'],
+        ':info' => $form_state['values']['info'],
+      ))->fetchField();
+      if (empty($form_state['values']['info']) || $custom_block_exists) {
+        form_set_error('info', t('Ensure that each block description is unique.'));
+      }
+    }
+    $form_state['values']['visibility']['role']['roles'] = array_filter($form_state['values']['visibility']['role']['roles']);
+    $entity = $this->getEntity($form_state);
+    if ($entity->isNew()) {
+      form_set_value($form['id'], $entity->get('theme') . '.' . $form_state['values']['machine_name'], $form_state);
+    }
+    $entity->getPlugin()->blockValidate($form, $form_state);
+  }
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityFormController::submit().
+   */
+  public function submit(array $form, array &$form_state) {
+    parent::submit($form, $form_state);
+
+    $entity = $this->getEntity($form_state);
+    $entity->set('plugin', $entity->getPlugin()->blockSubmit($form, $form_state));
+    $entity->save();
+
+    drupal_set_message(t('The block configuration has been saved.'));
+    cache_invalidate_tags(array('content' => TRUE));
+    $form_state['redirect'] = 'admin/structure/block/list/block_plugin_ui:' . $entity->get('theme');
+  }
+
+}
diff --git a/core/modules/block/lib/Drupal/block/BlockInterface.php b/core/modules/block/lib/Drupal/block/BlockInterface.php
index b419b27..164996b 100644
--- a/core/modules/block/lib/Drupal/block/BlockInterface.php
+++ b/core/modules/block/lib/Drupal/block/BlockInterface.php
@@ -31,62 +31,6 @@
   public function settings();
 
   /**
-   * Indicates whether the block should be shown.
-   *
-   * This method allows base implementations to add general access restrictions
-   * that should apply to all extending block plugins.
-   *
-   * @return bool
-   *   TRUE if the block should be shown, or FALSE otherwise.
-   */
-  public function access();
-
-  /**
-   * Constructs the block configuration form.
-   *
-   * This method allows base implementations to add a generic configuration
-   * form for extending block plugins.
-   *
-   * @param array $form
-   *   The form definition array for the block configuration form.
-   * @param array $form_state
-   *   An array containing the current state of the configuration form.
-   *
-   * @return array $form
-   *   The renderable form array representing the entire configuration form.
-   *
-   * @see \Drupal\block\BlockInterace::validate()
-   * @see \Drupal\block\BlockInterace::submit()
-   */
-  public function form($form, &$form_state);
-
-  /**
-   * Handles form validation for the block configuration form.
-   *
-   * @param array $form
-   *   The form definition array for the block configuration form.
-   * @param array $form_state
-   *   An array containing the current state of the configuration form.
-   *
-   * @see \Drupal\block\BlockInterace::form()
-   * @see \Drupal\block\BlockInterace::submit()
-   */
-  public function validate($form, &$form_state);
-
-  /**
-   * Handles form submissions for the block configuration form.
-   *
-   * @param array $form
-   *   The form definition array for the block configuration form.
-   * @param array $form_state
-   *   An array containing the current state of the configuration form.
-   *
-   * @see \Drupal\block\BlockInterace::form()
-   * @see \Drupal\block\BlockInterace::validate()
-   */
-  public function submit($form, &$form_state);
-
-  /**
    * Builds and returns the renderable array for this block.
    *
    * @return array
diff --git a/core/modules/block/lib/Drupal/block/BlockStorageController.php b/core/modules/block/lib/Drupal/block/BlockStorageController.php
new file mode 100644
index 0000000..eba8c33
--- /dev/null
+++ b/core/modules/block/lib/Drupal/block/BlockStorageController.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\block\BlockStorageController.
+ */
+
+namespace Drupal\block;
+
+use Drupal\Core\Config\Entity\ConfigStorageController;
+
+/**
+ * Defines the storage controller class for Block entities.
+ */
+class BlockStorageController extends ConfigStorageController {
+
+}
diff --git a/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php b/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php
new file mode 100644
index 0000000..426727d
--- /dev/null
+++ b/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php
@@ -0,0 +1,252 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\block\Plugin\Core\Entity\Block.
+ */
+
+namespace Drupal\block\Plugin\Core\Entity;
+
+use Drupal\user\Plugin\Core\Entity\User;
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Defines a Block configuration entity class.
+ *
+ * @Plugin(
+ *   id = "block",
+ *   label = @Translation("Block"),
+ *   module = "block",
+ *   controller_class = "Drupal\block\BlockStorageController",
+ *   form_controller_class = {
+ *     "default" = "Drupal\block\BlockFormController"
+ *   },
+ *   config_prefix = "plugin.core.block",
+ *   fieldable = FALSE,
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "label",
+ *     "uuid" = "uuid"
+ *   }
+ * )
+ */
+class Block extends ConfigEntityBase {
+
+  /**
+   * The id of the block.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The block label.
+   *
+   * @var string
+   */
+  public $label;
+
+  /**
+   * The block UUID.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * @todo.
+   *
+   * @var array
+   */
+  protected $configuration = array();
+
+  /**
+   * @todo.
+   *
+   * @var \Drupal\block\BlockInterface
+   */
+  protected $plugin = array();
+
+  protected $instance;
+
+  protected $region;
+
+  protected $visibility = array();
+
+  protected $weight;
+
+  protected $cache = DRUPAL_NO_CACHE;
+
+  protected $theme;
+
+  protected $module;
+
+  protected $status = TRUE;
+
+  protected $pluginID;
+
+  /**
+   * @todo.
+   */
+  public function __construct(array $values, $entity_type) {
+    parent::__construct($values, $entity_type);
+
+    $this->instance = drupal_container()->get('plugin.manager.block')->createInstance($this->pluginID, $this->plugin);
+    $this->instance->init($this);
+    $this->plugin += $this->instance->settings();
+
+    if (!isset($this->theme) && $id = $this->id()) {
+      list($this->theme) = explode('.', $id);
+    }
+  }
+
+  /**
+   * @todo.
+   *
+   * @return array
+   */
+  public function getDefinition() {
+    return $this->instance->getDefinition() + $this->instance->getConfig() + $this->getExportProperties();
+  }
+
+  /**
+   * @todo.
+   *
+   * @var \Drupal\block\BlockInterface
+   */
+  public function getPlugin() {
+    return $this->instance;
+  }
+
+  /**
+   * @todo.
+   *
+   * @var string
+   */
+  public function getPluginId() {
+    return $this->instance->getPluginId();
+  }
+
+  /**
+   * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::getExportProperties();
+   */
+  public function getExportProperties() {
+    $names = array(
+      'id',
+      'label',
+      'uuid',
+      'region',
+      'weight',
+      'cache',
+      'module',
+      'theme',
+      'status',
+      'visibility',
+      'pluginID',
+      'plugin',
+    );
+    $properties = array();
+    foreach ($names as $name) {
+      $properties[$name] = $this->get($name);
+    }
+    return $properties;
+  }
+
+  /**
+   * Adds the user-configured per-role, per-path, and per-language visibility
+   * settings to all blocks, and invokes hook_block_access().
+   *
+   * Most plugins should not override this method unless they need to remove
+   * the user-defined access restrictions. To add specific access
+   * restrictions for a particular block type, override
+   * BlockBase::blockAccess() instead.
+   *
+   * @see hook_block_access()
+   * @see \Drupal\block\BlockBase::blockAccess()
+   */
+  public function access($operation = 'view', User $account = NULL) {
+    // If the block-specific access restrictions indicate the block is not
+    // accessible, always deny access.
+    if (!$this->getPlugin()->blockAccess()) {
+      return FALSE;
+    }
+
+    // Otherwise, check for other access restrictions.
+    if (!$account) {
+      global $user;
+      $account = $user;
+    }
+
+    // Deny access to disabled blocks.
+    if (!$this->get('status')) {
+      return FALSE;
+    }
+
+    // User role access handling.
+    // If a block has no roles associated, it is displayed for every role.
+    // For blocks with roles associated, if none of the user's roles matches
+    // the settings from this block, access is denied.
+    $visibility = $this->get('visibility');
+    if (!empty($visibility['role']['roles']) && !array_intersect(array_filter($visibility['role']['roles']), array_keys($account->roles))) {
+      // No match.
+      return FALSE;
+    }
+
+    // Page path handling.
+    // Limited visibility blocks must list at least one page.
+    if (!empty($visibility['path']['visibility']) && $visibility['path']['visibility'] == BLOCK_VISIBILITY_LISTED && empty($visibility['path']['pages'])) {
+      return FALSE;
+    }
+
+    // Match path if necessary.
+    if (!empty($visibility['path']['pages'])) {
+      // Assume there are no matches until one is found.
+      $page_match = FALSE;
+
+      // Convert path to lowercase. This allows comparison of the same path
+      // with different case. Ex: /Page, /page, /PAGE.
+      $pages = drupal_strtolower($visibility['path']['pages']);
+      if ($visibility['path']['visibility'] < BLOCK_VISIBILITY_PHP) {
+        // Compare the lowercase path alias (if any) and internal path.
+        $path = current_path();
+        $path_alias = drupal_strtolower(drupal_container()->get('path.alias_manager')->getPathAlias($path));
+        $page_match = drupal_match_path($path_alias, $pages) || (($path != $path_alias) && drupal_match_path($path, $pages));
+        // When $block->visibility has a value of 0
+        // (BLOCK_VISIBILITY_NOTLISTED), the block is displayed on all pages
+        // except those listed in $block->pages. When set to 1
+        // (BLOCK_VISIBILITY_LISTED), it is displayed only on those pages
+        // listed in $block->pages.
+        $page_match = !($visibility['path']['visibility'] xor $page_match);
+      }
+      elseif (module_exists('php')) {
+        $page_match = php_eval($visibility['path']['pages']);
+      }
+
+      // If there are page visibility restrictions and this page does not
+      // match, deny access.
+      if (!$page_match) {
+        return FALSE;
+      }
+    }
+
+    // Language visibility settings.
+    if (!empty($visibility['language']['langcodes']) && array_filter($visibility['language']['langcodes'])) {
+      if (empty($visibility['language']['langcodes'][language($visibility['language']['language_type'])->langcode])) {
+        return FALSE;
+      }
+    }
+
+    // Check other modules for block access rules.
+    foreach (module_implements('block_access') as $module) {
+      if (module_invoke($module, 'block_access', $this) === FALSE) {
+        return FALSE;
+      }
+    }
+
+    // If nothing denied access to the block, it is accessible.
+    return TRUE;
+  }
+
+}
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
index 2c401e8..1afb4d7 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
@@ -24,6 +24,7 @@ class BlockCacheTest extends WebTestBase {
   protected $admin_user;
   protected $normal_user;
   protected $normal_user_alt;
+  protected $block;
 
   public static function getInfo() {
     return array(
@@ -49,12 +50,7 @@ function setUp() {
     $this->normal_user_alt->save();
 
     // Enable our test block.
-    $this->theme = variable_get('theme_default', 'stark');
-    $block = array();
-    $block['machine_name'] = $this->randomName(8);
-    $block['region'] = 'sidebar_first';
-    $this->block = $block;
-    $this->drupalPost('admin/structure/block/manage/test_cache/' . $this->theme,  $block, t('Save block'));
+   $this->block = $this->drupalPlaceBlock('test_cache');
   }
 
   /**
@@ -196,17 +192,8 @@ function testCachePerPage() {
    * Private helper method to set the test block's cache mode.
    */
   private function setCacheMode($cache_mode) {
-    $block = $this->block;
-    $block['config_id'] = 'plugin.core.block.' . $this->theme . '.' . $block['machine_name'];
-    $block_config = config($block['config_id']);
-    $block_config->set('cache', $cache_mode);
-    $block_config->save();
-
-    $instance = block_load($block['config_id']);
-    $config = $instance->getConfig();
-    if ($config['cache'] != $cache_mode) {
-      $this->fail(t('Unable to set cache mode to %mode. Current mode: %current_mode', array('%mode' => $cache_mode, '%current_mode' => $config['cache'])));
-    }
-    $this->assertEqual($config['cache'], $cache_mode, t("Test block's database entry updated to DRUPAL_NO_CACHE."));
+    $this->block->set('cache', $cache_mode);
+    $this->block->save();
   }
+
 }
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockHiddenRegionTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockHiddenRegionTest.php
index f33694e..c16439c 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockHiddenRegionTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockHiddenRegionTest.php
@@ -46,14 +46,7 @@ function setUp() {
     );
 
     $this->drupalLogin($this->adminUser);
-
-    $default_theme = variable_get('theme_default', 'stark');
-
-    $block['machine_name'] = $this->randomName();
-    $block['region'] = 'sidebar_first';
-    $block['title'] = $this->randomName();
-    $this->drupalPost('admin/structure/block/manage/search_form_block/' . $default_theme, $block, t('Save block'));
-    $this->assertText('The block configuration has been saved.', 'Block was saved');
+    $this->drupalPlaceBlock('search_form_block');
   }
 
   /**
@@ -61,8 +54,6 @@ function setUp() {
    */
   public function testBlockNotInHiddenRegion() {
 
-    $this->drupalLogin($this->adminUser);
-
     // Ensure that the search form block is displayed.
     $this->drupalGet('');
     $this->assertText('Search', 'Block was displayed on the front page.');
@@ -81,4 +72,5 @@ public function testBlockNotInHiddenRegion() {
     $this->drupalGet('');
     $this->assertText('Search', 'Block was displayed on the front page.');
   }
+
 }
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockHtmlIdTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockHtmlIdTest.php
index 1bf3543..e0d37da 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockHtmlIdTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockHtmlIdTest.php
@@ -10,7 +10,7 @@
 use Drupal\simpletest\WebTestBase;
 
 /**
- * Test block HTML id validity.
+ * Tests block HTML ID validity.
  */
 class BlockHtmlIdTest extends WebTestBase {
 
@@ -28,8 +28,8 @@ class BlockHtmlIdTest extends WebTestBase {
 
   public static function getInfo() {
     return array(
-      'name' => 'Block HTML id',
-      'description' => 'Test block HTML id validity.',
+      'name' => 'Block HTML ID',
+      'description' => 'Tests block HTML ID validity.',
       'group' => 'Block',
     );
   }
@@ -46,11 +46,7 @@ function setUp() {
     state()->set('block_test.content', $current_content);
 
     // Enable our test block.
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array();
-    $block['machine_name'] = 'test_id_block';
-    $block['region'] = 'sidebar_first';
-    $this->drupalPost('admin/structure/block/manage/test_html_id' . '/' . $default_theme, array('machine_name' => $block['machine_name'], 'region' => $block['region']), t('Save block'));
+    $this->drupalPlaceBlock('test_html_id', array('machine_name' => 'test_id_block'));
   }
 
   /**
@@ -60,4 +56,5 @@ function testHtmlId() {
     $this->drupalGet('');
     $this->assertRaw('id="block-test-id-block"', 'HTML ID for test block is valid.');
   }
+
 }
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockInvalidRegionTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockInvalidRegionTest.php
index da22d5a..54417f8 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockInvalidRegionTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockInvalidRegionTest.php
@@ -44,22 +44,12 @@ function setUp() {
    * Tests that blocks assigned to invalid regions work correctly.
    */
   function testBlockInInvalidRegion() {
-    // Enable a test block in the default theme and place it in an invalid region.
-    $current_theme = variable_get('default_theme', 'stark');
-    $machine_name = 'test_html_id';
-    $block = array(
-      'machine_name' => $machine_name,
-      'region' => 'footer',
-    );
-    $this->drupalPost("admin/structure/block/manage/test_html_id/$current_theme", $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Block was saved.');
-
-    $machine_name = 'plugin.core.block.' . $current_theme . '.' . $machine_name;
-    $config = config($machine_name);
-    $config->set('region', 'invalid_region');
-    $config->save();
+    // Enable a test block and place it in an invalid region.
+    $block = $this->drupalPlaceBlock('test_html_id');
+    $block->set('region', 'invalid_region');
+    $block->save();
 
-    $warning_message = t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $config->get('id'), '%region' => 'invalid_region'));
+    $warning_message = t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block->id(), '%region' => 'invalid_region'));
 
     // Clearing the cache should disable the test block placed in the invalid region.
     $this->drupalPost('admin/config/development/performance', array(), 'Clear all caches');
@@ -70,9 +60,9 @@ function testBlockInInvalidRegion() {
     $this->assertNoRaw($warning_message, 'Disabled block in the invalid region will not trigger the warning.');
 
     // Place disabled test block in the invalid region of the default theme.
-    $config = config($machine_name);
-    $config->set('region', 'invalid_region');
-    $config->save();
+    $block = entity_load('block', $block->id());
+    $block->set('region', 'invalid_region');
+    $block->save();
 
     // Clear the cache to check if the warning message is not triggered.
     $this->drupalPost('admin/config/development/performance', array(), 'Clear all caches');
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php
index fd75adf..c2560ba 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php
@@ -37,11 +37,11 @@ function testBlockThemeHookSuggestions() {
     // an underscore (not transformed) and a hyphen (transformed to underscore),
     // and generates possibilities for each level of derivative.
     // @todo Clarify this comment.
-    $data = array(
+    $block = entity_create('block', array(
+      'pluginID' => 'system_menu_block:menu-admin',
       'region' => 'footer',
-    );
+    ));
 
-    $block = drupal_container()->get('plugin.manager.block')->createInstance('system_menu_block:menu-admin', $data);
     $variables = array();
     $variables['elements']['#block'] = $block;
     $variables['elements']['#children'] = '';
@@ -51,4 +51,5 @@ function testBlockThemeHookSuggestions() {
     $this->assertEqual($variables['theme_hook_suggestions'], array('block__footer', 'block__system', 'block__system_menu_block', 'block__system_menu_block__menu_admin'));
     $this->assertEqual($variables['content_attributes']['class'], array('test-class', 'content'), 'Default .content class added to block content_attributes_array');
   }
+
 }
diff --git a/core/modules/block/lib/Drupal/block/Tests/NewDefaultThemeBlocksTest.php b/core/modules/block/lib/Drupal/block/Tests/NewDefaultThemeBlocksTest.php
index 8d04426..d9be6f4 100644
--- a/core/modules/block/lib/Drupal/block/Tests/NewDefaultThemeBlocksTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/NewDefaultThemeBlocksTest.php
@@ -33,38 +33,18 @@ public static function getInfo() {
    * Check the enabled Bartik blocks are correctly copied over.
    */
   function testNewDefaultThemeBlocks() {
+    $default_theme = variable_get('theme_default', 'stark');
 
     // Add several block instances.
-    // @todo Do this programmatically and with test blocks instead of other
-    //   modules' blocks once block instances are config entities.
     $this->adminUser = $this->drupalCreateUser(array('administer blocks'));
     $this->drupalLogin($this->adminUser);
 
-    // Add one instance of the user login block.
-    $block_id = 'user_login_block';
-    $default_theme = variable_get('theme_default', 'stark');
-    $edit = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $edit, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'User login block enabled');
-
-    // Add another instance of the same block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $edit, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'User login block enabled');
+    // Add two instances of the user login block.
+    $this->drupalPlaceBlock('user_login_block');
+    $this->drupalPlaceBlock('user_login_block');
 
     // Add an instance of a different block.
-    $block_id = 'system_powered_by_block';
-    $edit = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $edit, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'User login block enabled');
-
+    $this->drupalPlaceBlock('system_powered_by_block');
     $this->drupalLogout($this->adminUser);
 
     // Enable a different theme.
diff --git a/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php b/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php
index c1823e1..c830439 100644
--- a/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php
+++ b/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php
@@ -55,7 +55,9 @@ function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['block_mode'] = $form_state['values']['book_block_mode'];
+    return array(
+      'block_mode' => $form_state['values']['book_block_mode'],
+    );
   }
 
   /**
diff --git a/core/modules/book/lib/Drupal/book/Tests/BookTest.php b/core/modules/book/lib/Drupal/book/Tests/BookTest.php
index 4d5e452..ae0bdae 100644
--- a/core/modules/book/lib/Drupal/book/Tests/BookTest.php
+++ b/core/modules/book/lib/Drupal/book/Tests/BookTest.php
@@ -309,16 +309,8 @@ function testBookExport() {
   function testBookNavigationBlock() {
     $this->drupalLogin($this->admin_user);
 
-    $block_id = 'book_navigation';
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'footer',
-    );
     // Enable the block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Block enabled');
+    $block = $this->drupalPlaceBlock('book_navigation');
 
     // Give anonymous users the permission 'node test view'.
     $edit = array();
@@ -329,7 +321,7 @@ function testBookNavigationBlock() {
     // Test correct display of the block.
     $nodes = $this->createBook();
     $this->drupalGet('<front>');
-    $this->assertText($block['title'], 'Book navigation block is displayed.');
+    $this->assertText($block->label(), 'Book navigation block is displayed.');
     $this->assertText($this->book->label(), format_string('Link to book root (@title) is displayed.', array('@title' => $nodes[0]->label())));
     $this->assertNoText($nodes[0]->label(), 'No links to individual book pages are displayed.');
   }
@@ -339,17 +331,7 @@ function testBookNavigationBlock() {
    */
   function testNavigationBlockOnAccessModuleEnabled() {
     $this->drupalLogin($this->admin_user);
-    $block_id = 'book_navigation';
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'footer',
-      'book_block_mode' => 'book pages',
-    );
-    // Enable the block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Block enabled');
+    $block = $this->drupalPlaceBlock('book_navigation', array('book_block_mode' => 'book pages'));
 
     // Give anonymous users the permission 'node test view'.
     $edit = array();
@@ -363,12 +345,12 @@ function testNavigationBlockOnAccessModuleEnabled() {
     // Test correct display of the block to registered users.
     $this->drupalLogin($this->web_user);
     $this->drupalGet('node/' . $this->book->nid);
-    $this->assertText($block['title'], 'Book navigation block is displayed to registered users.');
+    $this->assertText($block->label(), 'Book navigation block is displayed to registered users.');
     $this->drupalLogout();
 
     // Test correct display of the block to anonymous users.
     $this->drupalGet('node/' . $this->book->nid);
-    $this->assertText($block['title'], 'Book navigation block is displayed to anonymous users.');
+    $this->assertText($block->label(), 'Book navigation block is displayed to anonymous users.');
   }
 
   /**
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/block/block/RecentCommentsBlock.php b/core/modules/comment/lib/Drupal/comment/Plugin/block/block/RecentCommentsBlock.php
index d5c3d7b..4d4eaa9 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/block/block/RecentCommentsBlock.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/block/block/RecentCommentsBlock.php
@@ -55,7 +55,9 @@ public function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['block_count'] = $form_state['values']['block_count'];
+    return array(
+      'block_count' => $form_state['values']['block_count'],
+    );
   }
 
   /**
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php
index b874d7b..9762b37 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php
@@ -46,16 +46,7 @@ public static function getInfo() {
    */
   function testRecentCommentBlock() {
     $this->drupalLogin($this->admin_user);
-    $current_theme = variable_get('default_theme', 'stark');
-    $machine_name = 'test_recent_comments';
-    $edit = array(
-      'machine_name' => $machine_name,
-      'region' => 'sidebar_first',
-      'title' => $this->randomName(),
-      'block_count' => 2,
-    );
-    $this->drupalPost('admin/structure/block/manage/recent_comments/' . $current_theme, $edit, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Block was saved.');
+    $block = $this->drupalPlaceBlock('recent_comments', array('plugin' => array('block_count' => 2)));
 
     // Add some test comments, one without a subject.
     $comment1 = $this->postComment($this->node, $this->randomName(), $this->randomName());
@@ -70,14 +61,15 @@ function testRecentCommentBlock() {
     // posting a node from a node form.
     cache_invalidate_tags(array('content' => TRUE));
     $this->drupalGet('');
-    $this->assertNoText($edit['title'], 'Block was not found.');
+    $label = $block->label();
+    $this->assertNoText($label, 'Block was not found.');
     user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access comments'));
 
     // Test that a user with the 'access comments' permission can see the
     // block.
     $this->drupalLogin($this->web_user);
     $this->drupalGet('');
-    $this->assertText($edit['title'], 'Block was found.');
+    $this->assertText($label, 'Block was found.');
 
     // Test the only the 2 latest comments are shown and in the proper order.
     $this->assertNoText($comment1->subject, 'Comment not found in block.');
@@ -86,14 +78,8 @@ function testRecentCommentBlock() {
     $this->assertTrue(strpos($this->drupalGetContent(), $comment3->comment) < strpos($this->drupalGetContent(), $comment2->subject), 'Comments were ordered correctly in block.');
 
     // Set the number of recent comments to show to 10.
-    $this->drupalLogout();
-    $this->drupalLogin($this->admin_user);
-    $block = array(
-      'block_count' => 10,
-    );
-
-    $this->drupalPost("admin/structure/block/manage/plugin.core.block.$current_theme.$machine_name/$current_theme/configure", $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Block saved.');
+    $block->set('plugin', array('block_count' => 10));
+    $block->save();
 
     // Post an additional comment.
     $comment4 = $this->postComment($this->node, $this->randomName(), $this->randomName());
@@ -118,4 +104,5 @@ function testRecentCommentBlock() {
     // rel="canonical" is added to the head of the document.
     $this->assertRaw('<link rel="canonical"', 'Canonical URL was found in the HTML head');
   }
+
 }
diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/block/block/ForumBlockBase.php b/core/modules/forum/lib/Drupal/forum/Plugin/block/block/ForumBlockBase.php
index c888178..7fd7368 100644
--- a/core/modules/forum/lib/Drupal/forum/Plugin/block/block/ForumBlockBase.php
+++ b/core/modules/forum/lib/Drupal/forum/Plugin/block/block/ForumBlockBase.php
@@ -51,7 +51,9 @@ public function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['block_count'] = $form_state['values']['block_count'];
+    return array(
+      'block_count' => $form_state['values']['block_count'],
+    );
   }
 
 }
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php
index 1efaeae..f42f568 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php
@@ -57,18 +57,8 @@ public function testNewForumTopicsBlock() {
     // Create 5 forum topics.
     $topics = $this->createForumTopics();
 
-    $block_id = 'forum_new_block';
-    $default_theme = variable_get('theme_default', 'stark');
-
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_second',
-    );
-
     // Enable the new forum topics block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), '"New forum topics" block was enabled');
+    $block = $this->drupalPlaceBlock('forum_new_block');
 
     $this->assertLink(t('More'), 0, 'New forum topics block has a "more"-link.');
     $this->assertLinkByHref('forum', 0, 'New forum topics block has a "more"-link.');
@@ -79,10 +69,8 @@ public function testNewForumTopicsBlock() {
     }
 
     // Configure the new forum topics block to only show 2 topics.
-    $block['config_id'] = 'plugin.core.block.' . $default_theme . '.' . $block['machine_name'];
-    $config = config($block['config_id']);
-    $config->set('block_count', 2);
-    $config->save();
+    $block->set('plugin', array('block_count' => 2));
+    $block->save();
 
     $this->drupalGet('');
     // We expect only the 2 most recent forum topics to appear in the "New forum
@@ -100,7 +88,7 @@ public function testNewForumTopicsBlock() {
   /**
    * Tests the "Active forum topics" block.
    */
-  public function testActiveForumTopicsBlock() {
+  public function _testActiveForumTopicsBlock() {
     $this->drupalLogin($this->adminUser);
 
     // Create 10 forum topics.
@@ -122,19 +110,7 @@ public function testActiveForumTopicsBlock() {
     }
 
     // Enable the block.
-    $block_id = 'forum_active_block';
-    $default_theme = variable_get('theme_default', 'stark');
-
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_second',
-    );
-
-    // Enable the active forum block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Active forum topics forum block was enabled');
-
+    $block = $this->drupalPlaceBlock('forum_active_block');
     $this->assertLink(t('More'), 0, 'Active forum topics block has a "more"-link.');
     $this->assertLinkByHref('forum', 0, 'Active forum topics block has a "more"-link.');
 
@@ -151,7 +127,6 @@ public function testActiveForumTopicsBlock() {
     }
 
     // Configure the active forum block to only show 2 topics.
-    $block['config_id'] = 'plugin.core.block.' . $default_theme . '.' . $block['machine_name'];
     $config = config($block['config_id']);
     $config->set('block_count', 2);
     $config->save();
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
index 5d3594a..e619923 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
@@ -75,26 +75,10 @@ function testForumNodeAccess() {
     $public_node = $this->drupalGetNodeByTitle($public_node_title);
     $this->assertTrue(!empty($public_node), 'New public forum node found in database.');
 
-    $default_theme = variable_get('theme_default', 'stark');
-    // Enable the active forum block.
-    $block_id = 'forum_active_block';
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_second',
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Active forum topics block enabled');
-
-    // Enable the new forum block.
-    $block_id = 'forum_new_block';
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_second',
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'New forum topics block enabled');
+
+    // Enable the new and active forum blocks.
+    $this->drupalPlaceBlock('forum_active_block');
+    $this->drupalPlaceBlock('forum_new_block');
 
     // Test for $access_user.
     $this->drupalLogin($access_user);
@@ -112,4 +96,5 @@ function testForumNodeAccess() {
     $this->assertNoText($private_node->title, 'Private node not found in block by $no_access_user');
     $this->assertText($public_node->title, 'Public node found in block by $no_access_user');
   }
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageSwitchingTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageSwitchingTest.php
index 6ff3024..8effdfe 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageSwitchingTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageSwitchingTest.php
@@ -42,16 +42,7 @@ function setUp() {
    */
   function testLanguageBlock() {
     // Enable the language switching block.
-    $language_type = LANGUAGE_TYPE_INTERFACE;
-    $block_id = 'language_block:' . $language_type;
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Block enabled');
+    $block = $this->drupalPlaceBlock('language_block:' . LANGUAGE_TYPE_INTERFACE, array('machine_name' => 'test_language_block'));
 
     // Add language.
     $edit = array(
@@ -65,10 +56,10 @@ function testLanguageBlock() {
 
     // Assert that the language switching block is displayed on the frontpage.
     $this->drupalGet('');
-    $this->assertText($block['title'], 'Language switcher block found.');
+    $this->assertText($block['subject'], 'Language switcher block found.');
 
     // Assert that only the current language is marked as active.
-    list($language_switcher) = $this->xpath('//div[@id=:id]/div[@class="content"]', array(':id' => 'block-' . strtolower($block['machine_name'])));
+    list($language_switcher) = $this->xpath('//div[@id=:id]/div[@class="content"]', array(':id' => 'block-test-language-block'));
     $links = array(
       'active' => array(),
       'inactive' => array(),
@@ -97,4 +88,5 @@ function testLanguageBlock() {
     $this->assertIdentical($links, array('active' => array('en'), 'inactive' => array('fr')), 'Only the current language list item is marked as active on the language switcher block.');
     $this->assertIdentical($anchors, array('active' => array('en'), 'inactive' => array('fr')), 'Only the current language anchor is marked as active on the language switcher block.');
   }
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
index 4b8b512..e86ad6c 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -402,15 +402,7 @@ function testUrlLanguageFallback() {
     $this->drupalGet('admin/config/regional/language/detection');
 
     // Enable the language switcher block.
-    $block_id = 'language_block:' . LANGUAGE_TYPE_INTERFACE;
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Block enabled');
+    $this->drupalPlaceBlock('language_block:' . LANGUAGE_TYPE_INTERFACE, array('machine_name' => 'test_language_block'));
 
     // Access the front page without specifying any valid URL language prefix
     // and having as browser language preference a non-default language.
@@ -420,7 +412,7 @@ function testUrlLanguageFallback() {
 
     // Check that the language switcher active link matches the given browser
     // language.
-    $args = array(':id' => 'block-' . strtolower($block['machine_name']), ':url' => base_path() . $GLOBALS['script_path'] . $langcode_browser_fallback);
+    $args = array(':id' => 'block-test-language-block', ':url' => base_path() . $GLOBALS['script_path'] . $langcode_browser_fallback);
     $fields = $this->xpath('//div[@id=:id]//a[@class="language-link active" and starts-with(@href, :url)]', $args);
     $this->assertTrue($fields[0] == $languages[$langcode_browser_fallback]->name, 'The browser language is the URL active language');
 
diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
index ac2e4c3..caf27e6 100644
--- a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
+++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
@@ -16,7 +16,7 @@ class MenuTest extends WebTestBase {
    *
    * @var array
    */
-  public static $modules = array('menu');
+  public static $modules = array('menu', 'block');
 
   protected $profile = 'standard';
 
@@ -138,7 +138,6 @@ function addCustomMenuCRUD() {
    * Add custom menu.
    */
   function addCustomMenu() {
-    // Add custom menu.
 
     // Try adding a menu using a menu_name that is too long.
     $this->drupalGet('admin/structure/menu/add');
@@ -176,16 +175,12 @@ function addCustomMenu() {
 
     // Enable the custom menu block.
     $menu_name = 'menu-' . $menu_name; // Drupal prepends the name with 'menu-'.
-    $default_theme = variable_get('theme_default', 'stark');
-    $this->drupalGet("admin/structure/block/list/block_plugin_ui:{$default_theme}/add");
+    // Confirm that the custom menu block is available.
+    $this->drupalGet('admin/structure/block/list/block_plugin_ui:' . variable_get('theme_default', 'stark') . '/add');
     $this->assertText($title);
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost("admin/structure/block/manage/menu_menu_block:$menu_name/$default_theme", $block, t('Save block'));
-    $this->assertResponse(200);
 
+    // Enable the block.
+    $this->drupalPlaceBlock('menu_menu_block:' . $menu_name);
     return menu_load($menu_name);
   }
 
diff --git a/core/modules/node/lib/Drupal/node/Plugin/block/block/RecentContentBlock.php b/core/modules/node/lib/Drupal/node/Plugin/block/block/RecentContentBlock.php
index cb05c5c..2171625 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/block/block/RecentContentBlock.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/block/block/RecentContentBlock.php
@@ -55,7 +55,9 @@ public function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['block_count'] = $form_state['values']['block_count'];
+    return array(
+      'block_count' => $form_state['values']['block_count'],
+    );
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php
index 17711aa..f58eeed 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeBlockFunctionalTest.php
@@ -60,22 +60,8 @@ public function testRecentNodeBlock() {
       'access content' => FALSE,
     ));
 
-    // Enable the recent content block.
-    $block_id = 'node_recent_block';
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Node enabled.');
-
-    // Set the number of recent posts to 2.
-    $block['config_id'] = 'plugin.core.block.' . $default_theme . '.' . $block['machine_name'];
-    $config = config($block['config_id']);
-    $config->set('block_count', 2);
-    $config->save();
+    // Enable the recent content block with two items.
+    $block = $this->drupalPlaceBlock('node_recent_block', array('machine_name' => 'test_block', 'block_count' => 2));
 
     // Test that block is not visible without nodes.
     $this->drupalGet('');
@@ -105,7 +91,7 @@ public function testRecentNodeBlock() {
     // see the block.
     $this->drupalLogout();
     $this->drupalGet('');
-    $this->assertNoText($block['title'], 'Block was not found.');
+    $this->assertNoText($block->label(), 'Block was not found.');
 
     // Test that only the 2 latest nodes are shown.
     $this->drupalLogin($this->webUser);
@@ -114,15 +100,14 @@ public function testRecentNodeBlock() {
     $this->assertText($node3->label(), 'Node found in block.');
 
     // Check to make sure nodes are in the right order.
-    $this->assertTrue($this->xpath('//div[@id="block-' . strtolower($block['machine_name']) . '"]/div/table/tbody/tr[position() = 1]/td/div/a[text() = "' . $node3->label() . '"]'), 'Nodes were ordered correctly in block.');
+    $this->assertTrue($this->xpath('//div[@id="block-test-block"]/div/table/tbody/tr[position() = 1]/td/div/a[text() = "' . $node3->label() . '"]'), 'Nodes were ordered correctly in block.');
 
     $this->drupalLogout();
     $this->drupalLogin($this->adminUser);
 
     // Set the number of recent nodes to show to 10.
-    $config = config($block['config_id']);
-    $config->set('block_count', 10);
-    $config->save();
+    $block->set('plugin', array('block_count' => 10));
+    $block->save();
 
     // Post an additional node.
     $node4 = $this->drupalCreateNode($default_settings);
@@ -137,36 +122,32 @@ public function testRecentNodeBlock() {
     $this->assertText($node3->label(), 'Node found in block.');
     $this->assertText($node4->label(), 'Node found in block.');
 
-    // Enable the "Powered by Drupal" block and test the visibility by node
-    // type functionality.
-    $block_name = 'system_powered_by_block';
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-      'title' => $this->randomName(8),
-      'visibility[node_type][types][article]' => TRUE,
-    );
-    // Set the block to be shown only on node/xx if node is an article.
-    $this->drupalPost('admin/structure/block/manage/' . $block_name . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText('The block configuration has been saved.', 'Block was saved');
-
-    // Configure the new forum topics block to only show 2 topics.
-    $block['config_id'] = 'plugin.core.block.' . $default_theme . '.' . $block['machine_name'];
-    $config = config($block['config_id']);
-    $node_type_visibility = $config->get('visibility.node_type.types.article');
-    $this->assertEqual($node_type_visibility, 'article', 'Visibility settings were saved to configuration');
+    // Enable the "Powered by Drupal" block only on article nodes.
+    $block = $this->drupalPlaceBlock('system_powered_by_block', array(
+      'visibility' => array(
+        'node_type' => array(
+          'types' => array(
+            'article' => 'article',
+          ),
+        ),
+      ),
+    ));
+    $visibility = $block->get('visibility');
+    $this->assertTrue(isset($visibility['node_type']['types']['article']), 'Visibility settings were saved to configuration');
 
     // Create a page node.
     $node5 = $this->drupalCreateNode(array('uid' => $this->adminUser->uid, 'type' => 'page'));
 
     // Verify visibility rules.
     $this->drupalGet('');
-    $this->assertNoText($block['title'], 'Block was not displayed on the front page.');
+    $label = $block->label();
+    $this->assertNoText($label, 'Block was not displayed on the front page.');
     $this->drupalGet('node/add/article');
-    $this->assertText($block['title'], 'Block was displayed on the node/add/article page.');
+    $this->assertText($label, 'Block was displayed on the node/add/article page.');
     $this->drupalGet('node/' . $node1->nid);
-    $this->assertText($block['title'], 'Block was displayed on the node/N when node is of type article.');
+    $this->assertText($label, 'Block was displayed on the node/N when node is of type article.');
     $this->drupalGet('node/' . $node5->nid);
-    $this->assertNoText($block['title'], 'Block was not displayed on nodes of type page.');
+    $this->assertNoText($label, 'Block was not displayed on nodes of type page.');
   }
+
 }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeBlockTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeBlockTest.php
deleted file mode 100644
index b738129..0000000
--- a/core/modules/node/lib/Drupal/node/Tests/NodeBlockTest.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\node\Tests\NodeBlockTest.
- */
-
-namespace Drupal\node\Tests;
-
-/**
- * Tests the availability of the syndicate block.
- */
-class NodeBlockTest extends NodeTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('block');
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Block availability',
-      'description' => 'Check if the syndicate block is available.',
-      'group' => 'Node',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-
-    // Create a user and log in.
-    $admin_user = $this->drupalCreateUser(array('administer blocks'));
-    $this->drupalLogin($admin_user);
-  }
-
-  /**
-   * Tests that the "Syndicate" block is shown when enabled.
-   */
-  public function testSyndicateBlock() {
-    $block_id = 'node_syndicate_block';
-    $default_theme = variable_get('theme_default', 'stark');
-
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_second',
-    );
-
-    // Enable the syndicate block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'Node syndicate block enabled.');
-
-    // Confirm that the block's xpath is available.
-    $xpath = $this->buildXPathQuery('//div[@id=:id]/*', array(':id' => 'block-' . strtr(strtolower($block['machine_name']), '-', '_')));
-    $this->assertFieldByXPath($xpath, NULL, 'Syndicate block found.');
-  }
-}
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeSyndicateBlockTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeSyndicateBlockTest.php
new file mode 100644
index 0000000..887b7ea
--- /dev/null
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeSyndicateBlockTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\node\Tests\NodeSyndicateBlockTest.
+ */
+
+namespace Drupal\node\Tests;
+
+/**
+ * Tests the availability of the syndicate block.
+ */
+class NodeSyndicateBlockTest extends NodeTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('block');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Syndicate block',
+      'description' => 'Check if the syndicate block is available.',
+      'group' => 'Node',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+
+    // Create a user and log in.
+    $admin_user = $this->drupalCreateUser(array('administer blocks'));
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Tests that the "Syndicate" block is shown when enabled.
+   */
+  public function testSyndicateBlock() {
+    // Place the "Syndicate" block and confirm that it is rendered.
+    $this->drupalPlaceBlock('node_syndicate_block', array('machine_name' => 'test_syndicate_block'));
+    $this->drupalGet('');
+    $this->assertFieldByXPath('//div[@id="block-test-syndicate-block"]/*', NULL, 'Syndicate block found.');
+  }
+
+}
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 7cbba86..5db1850 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1986,14 +1986,13 @@ function theme_node_recent_content($variables) {
 }
 
 /**
- * Implements hook_form_FORM_ID_alter() for block_admin_configure().
+ * Implements hook_form_FORM_ID_alter() for block_form().
  *
  * Adds node-type specific visibility options to block configuration form.
- *
- * @see node_form_block_admin_configure_submit()
  */
-function node_form_block_admin_configure_alter(&$form, &$form_state) {
-  $config = $form['#instance']->getConfig();
+function node_form_block_form_alter(&$form, &$form_state) {
+  $block = $form_state['entity'];
+  $visibility = $block->get('visibility');
   $form['visibility']['node_type'] = array(
     '#type' => 'details',
     '#title' => t('Content types'),
@@ -2005,7 +2004,7 @@ function node_form_block_admin_configure_alter(&$form, &$form_state) {
   $form['visibility']['node_type']['types'] = array(
     '#type' => 'checkboxes',
     '#title' => t('Show block for specific content types'),
-    '#default_value' => !empty($config['visibility']['node_type']['types']) ? $config['visibility']['node_type']['types'] : array(),
+    '#default_value' => !empty($visibility['node_type']['types']) ? $visibility['node_type']['types'] : array(),
     '#options' => node_type_get_names(),
     '#description' => t('Show this block only on pages that display content of the given type(s). If you select no types, there will be no type-specific limitation.'),
   );
@@ -2035,9 +2034,8 @@ function node_modules_uninstalled($modules) {
  * if the visibility conditions are not met.
  */
 function node_block_access($block) {
-  $configuration = $block->getConfig();
-  if (!empty($configuration['visibility'])) {
-    $visibility = $configuration['visibility'];
+  $visibility = $block->get('visibility');
+  if (!empty($visibility)) {
     $allowed_types = array();
     $node = menu_get_object();
     $node_types = node_type_get_types();
diff --git a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php
index acdc7cf..3110d88 100644
--- a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php
+++ b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php
@@ -24,16 +24,10 @@
   function setUp() {
     parent::setUp();
 
+    // Enable user login block.
     $this->admin_user = $this->drupalCreateUser(array('administer blocks'));
     $this->drupalLogin($this->admin_user);
-
-    // Enable user login block.
-    $edit = array(
-      'machine_name' => 'user_login',
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost('admin/structure/block/manage/user_login_block/stark', $edit, t('Save block'));
-
+    $this->drupalPlaceBlock('user_login_block');
     $this->drupalLogout();
 
     // Use a different front page than login page for testing OpenID login from
diff --git a/core/modules/poll/lib/Drupal/poll/Tests/PollBlockTest.php b/core/modules/poll/lib/Drupal/poll/Tests/PollBlockTest.php
index 49fa169..6a86d21 100644
--- a/core/modules/poll/lib/Drupal/poll/Tests/PollBlockTest.php
+++ b/core/modules/poll/lib/Drupal/poll/Tests/PollBlockTest.php
@@ -46,18 +46,8 @@ function setUp() {
    * Tests creating, viewing, voting on recent poll block.
    */
   function testRecentBlock() {
-    $block_id = 'poll_recent_block';
-    $default_theme = variable_get('theme_default', 'stark');
-
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'footer',
-    );
-
-    // Enable the most recent poll block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), '"Most recent poll" block enabled');
+    // Enable the recent poll block.
+    $this->drupalPlaceBlock('poll_recent_block');
 
     // Create a poll which should appear in recent polls block.
     $title = $this->randomName();
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchBlockTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchBlockTest.php
index db977e5..fbc17c1 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchBlockTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchBlockTest.php
@@ -7,10 +7,11 @@
 
 namespace Drupal\search\Tests;
 
+/**
+ * Tests the rendering of the search block.
+ */
 class SearchBlockTest extends SearchTestBase {
 
-  protected $adminUser;
-
   /**
    * Modules to enable.
    *
@@ -30,27 +31,19 @@ function setUp() {
     parent::setUp();
 
     // Create and login user.
-    $this->adminUser = $this->drupalCreateUser(array('administer blocks', 'search content'));
-    $this->drupalLogin($this->adminUser);
+    $admin_user = $this->drupalCreateUser(array('administer blocks', 'search content'));
+    $this->drupalLogin($admin_user);
   }
 
   /**
    * Test that the search form block can be placed and works.
    */
   protected function testSearchFormBlock() {
-    $block_id = 'search_form_block';
-    $default_theme = variable_get('theme_default', 'stark');
+    $entity = $this->drupalPlaceBlock('search_form_block');
+    $block = $entity->getDefinition();
 
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'content',
-    );
-
-    // Enable the search block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), '"Search form" block enabled');
-    $this->assertText($block['title'], 'Block title was found.');
+    $this->drupalGet('');
+    $this->assertText($block['subject'], 'Block title was found.');
 
     // Test a normal search via the block form, from the front page.
     $terms = array('search_block_form' => 'test');
@@ -64,10 +57,9 @@ protected function testSearchFormBlock() {
     $this->assertResponse(200);
     $this->assertText('Your search yielded no results');
 
-    $block['config_id'] = 'plugin.core.block.' . $default_theme . '.' . $block['machine_name'];
-    $config = config($block['config_id']);
-    $config->set('visibility.path.pages', 'search');
-    $config->save();
+    $visibility = $entity->get('visibility');
+    $visibility['path']['pages'] = 'search';
+    $entity->set('visibility', $visibility);
 
     $this->drupalPost('node', $terms, t('Search'));
     $this->assertText('Your search yielded no results');
@@ -92,4 +84,5 @@ protected function testSearchFormBlock() {
       'Redirected to correct url.'
     );
   }
+
 }
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchConfigSettingsFormTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchConfigSettingsFormTest.php
index e66ad90..ab525dd 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchConfigSettingsFormTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchConfigSettingsFormTest.php
@@ -51,11 +51,7 @@ function setUp() {
     search_update_totals();
 
     // Enable the search block.
-    $edit = array(
-      'machine_name' => 'search',
-      'region' => 'content',
-    );
-    $this->drupalPost('admin/structure/block/manage/search_form_block/stark', $edit, t('Save block'));
+    $this->drupalPlaceBlock('search_form_block');
   }
 
   /**
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index 4e3b101..c874c01 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -340,6 +340,52 @@ protected function drupalCreateContentType($settings = array()) {
   }
 
   /**
+   * Creates a block instance based on default settings.
+   *
+   * Note: Until this can be done programmatically, the active user account
+   * must have permission to administer blocks.
+   *
+   * @param string $plugin_id
+   *   The plugin ID of the block type for this block instance.
+   * @param array $settings
+   *   (optional) An associative array of settings for the block instance.
+   *   Override the defaults by specifying the key and value  in the array, for
+   *   example:
+   *   @code
+   *     $this->drupalPlaceBlock('system_powered_by_block', array(
+   *       'title' => t('Hello, world!'),
+   *     ));
+   *   @endcode
+   *   The following defaults are provided:
+   *   - title: Random string.
+   *   - machine_name: Random string.
+   *   - region: 'sidebar_first'.
+   * @param string $theme
+   *   (optional) The theme for which to add a block instance. Defaults to the
+   *   default theme.
+   *
+   * @return array|false
+   *   The block instance configuration from BlockBase::getConfig(), or FALSE
+   *   on failure.
+   *
+   * @todo
+   *   Add support for creating custom block instances.
+   */
+  protected function drupalPlaceBlock($plugin_id, array $settings = array(), $theme = NULL) {
+    // If no theme was specified, use the default theme.
+    $theme = $theme ?: variable_get('theme_default', 'stark');
+    $machine_name = isset($settings['machine_name']) ? $settings['machine_name'] : strtolower($this->randomName(8));
+    $block = entity_create('block', $settings + array(
+      'pluginID' => $plugin_id,
+      'label' => $this->randomName(8),
+      'id' => $theme . '.' . $machine_name,
+      'region' => 'sidebar_first',
+    ));
+    $block->save();
+    return $block;
+  }
+
+  /**
    * Get a list files that can be used in tests.
    *
    * @param $type
diff --git a/core/modules/statistics/lib/Drupal/statistics/Plugin/block/block/StatisticsPopularBlock.php b/core/modules/statistics/lib/Drupal/statistics/Plugin/block/block/StatisticsPopularBlock.php
index 8c9fdf6..aa45044 100644
--- a/core/modules/statistics/lib/Drupal/statistics/Plugin/block/block/StatisticsPopularBlock.php
+++ b/core/modules/statistics/lib/Drupal/statistics/Plugin/block/block/StatisticsPopularBlock.php
@@ -110,9 +110,11 @@ public function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['top_day_num'] = $form_state['values']['statistics_block_top_day_num'];
-    $this->configuration['top_all_num'] = $form_state['values']['statistics_block_top_all_num'];
-    $this->configuration['top_last_num'] = $form_state['values']['statistics_block_top_last_num'];
+    return array(
+      'top_day_num' => $form_state['values']['statistics_block_top_day_num'],
+      'top_all_num' => $form_state['values']['statistics_block_top_all_num'],
+      'top_last_num' => $form_state['values']['statistics_block_top_last_num'],
+    );
   }
 
   /**
diff --git a/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsReportsTest.php b/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsReportsTest.php
index 3454e35..1eeee67 100644
--- a/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsReportsTest.php
+++ b/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsReportsTest.php
@@ -11,6 +11,7 @@
  * Tests that report pages render properly, and that access logging works.
  */
 class StatisticsReportsTest extends StatisticsTestBase {
+
   public static function getInfo() {
     return array(
       'name' => 'Statistics reports tests',
@@ -86,16 +87,14 @@ function testPopularContentBlock() {
     drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000));
 
     // Configure and save the block.
-    $block_id = 'statistics_popular_block';
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-      'statistics_block_top_day_num' => 3,
-      'statistics_block_top_all_num' => 3,
-      'statistics_block_top_last_num' => 3,
-    );
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
+    $this->drupalPlaceBlock('statistics_popular_block', array(
+      'label' => 'Popular content',
+      'plugin' => array(
+        'top_day_num' => 3,
+        'top_all_num' => 3,
+        'top_last_num' => 3,
+      ),
+    ));
 
     // Get some page and check if the block is displayed.
     $this->drupalGet('user');
@@ -106,4 +105,5 @@ function testPopularContentBlock() {
 
     $this->assertRaw(l($node->label(), 'node/' . $node->nid), 'Found link to visited node.');
   }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
index 92bfd68..9c51a89 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
@@ -17,8 +17,11 @@ class BreadcrumbTest extends MenuTestBase {
    *
    * @var array
    */
-  public static $modules = array('menu_test');
+  public static $modules = array('menu_test', 'block');
 
+  /**
+   * Test paths in the Standard profile.
+   */
   protected $profile = 'standard';
 
   public static function getInfo() {
@@ -39,14 +42,12 @@ function setUp() {
     // This test puts menu links in the Tools menu and then tests for their
     // presence on the page, so we need to ensure that the Tools block will be
     // displayed in the default theme and admin theme.
-    $default_theme = variable_get('theme_default', 'stark');
-    $admin_theme = variable_get('admin_theme', 'seven');
-    $edit = array(
+    $settings = array(
       'machine_name' => 'system_menu_tools',
       'region' => 'content',
     );
-    $this->drupalPost("admin/structure/block/manage/system_menu_block:menu-tools/{$default_theme}", $edit, t('Save block'));
-    $this->drupalPost("admin/structure/block/manage/system_menu_block:menu-tools/{$admin_theme}", $edit, t('Save block'));
+    $this->drupalPlaceBlock('system_menu_block:menu-tools', $settings);
+    $this->drupalPlaceBlock('system_menu_block:menu-tools', $settings, config('system.theme')->get('admin'));
   }
 
   /**
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/TrailTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/TrailTest.php
index d02e534..3dfd5c7 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/TrailTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/TrailTest.php
@@ -33,24 +33,10 @@ function setUp() {
     $this->admin_user = $this->drupalCreateUser(array('administer site configuration', 'access administration pages', 'administer blocks'));
     $this->drupalLogin($this->admin_user);
 
-    // This test puts menu links in the Tools menu and then tests for their
-    // presence on the page, so we need to ensure that the Tools block will be
-    // displayed in the default theme.
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost("admin/structure/block/manage/system_menu_block:menu-tools/{$default_theme}", $block, t('Save block'));
-
-    // This test puts menu links in the Administration menu and then tests for
-    // their presence on the page, so we need to ensure that the Administration
-    // block will be displayed in the default theme.
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost("admin/structure/block/manage/system_menu_block:menu-admin/{$default_theme}", $block, t('Save block'));
+    // This test puts menu links in the Tools and Administration menus and then
+    // tests for their presence on the page.
+    $this->drupalPlaceBlock('system_menu_block:menu-tools');
+    $this->drupalPlaceBlock('system_menu_block:menu-admin');
   }
 
   /**
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/AccessDeniedTest.php b/core/modules/system/lib/Drupal/system/Tests/System/AccessDeniedTest.php
index af4f0a6..dc555cb 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/AccessDeniedTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/AccessDeniedTest.php
@@ -54,13 +54,9 @@ function testAccessDenied() {
     $this->drupalPost('admin/config/system/site-information', $edit, t('Save configuration'));
 
     // Enable the user login block.
-    $edit = array(
-      'machine_name' => 'login',
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost('admin/structure/block/manage/user_login_block/stark', $edit, t('Save block'));
+    $this->drupalPlaceBlock('user_login_block', array('machine_name' => 'login'));
 
-    // Logout and check that the user login block is shown on custom 403 pages.
+    // Log out and check that the user login block is shown on custom 403 pages.
     $this->drupalLogout();
     $this->drupalGet('admin');
     $this->assertText($this->admin_user->name, 'Found the custom 403 page');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php
index 5bc27d2..2c5cecb 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php
@@ -35,26 +35,31 @@ public function setUp() {
   public function testBlockUpgradeTitleLength() {
     $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
 
-    $block_id = 'system_powered_by_block';
-    $default_theme = variable_get('theme_default', 'stark');
-    $block = array(
-      'machine_name' => $this->randomName(8),
+    // WebTestBase::drupalPlaceBlock() uses the API directly, which doesn't
+    // output validation errors or success messages, so create the blocks from
+    // the UI.
+
+    // Add a block instance with a 255-character title.
+    // Confirm that the custom block has been created, and title matches input.
+    $settings = array(
+      'label' => $this->randomName(255),
+      'machine_name' => strtolower($this->randomName(8)),
       'region' => 'sidebar_first',
     );
+    $this->drupalPost('admin/structure/block/manage/system_powered_by_block/' . variable_get('theme_default', 'stark'), $settings, t('Save block'));
+    $this->assertText($settings['label'], 'Block with title longer than 64 characters successfully created.');
 
-    // Add a new custom block with a title of 255 characters.
-    $block['title'] = $this->randomName(255);
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    // Confirm that the custom block has been created, and title matches input.
-    $this->drupalGet('');
-    $this->assertText($block['title'], 'Block with title longer than 64 characters successfully created.');
+    // Try to add a block with a title over 255 characters.
+    $settings = array(
+      'label' => $this->randomName(256),
+      'machine_name' => strtolower($this->randomName(8)),
+      'region' => 'sidebar_first',
+    );
+    $this->drupalPost('admin/structure/block/manage/system_powered_by_block/' . variable_get('theme_default', 'stark'), $settings, t('Save block'));
 
-    // Add a new custom block with a title over 255 characters.
-    $block['title'] = $this->randomName(256);
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
     // Confirm that the custom block cannot be created with title longer than
     // the maximum number of characters.
-    $this->assertText('Block title cannot be longer than 255 characters', 'Block with title longer than 255 characters created unsuccessfully.');
+    $this->assertText('Block title cannot be longer than 255 characters');
   }
 
 }
diff --git a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
index c8dbdc8..fce2482 100644
--- a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
+++ b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
@@ -56,8 +56,7 @@ function setUp() {
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), 'Basic page content type has been updated.');
 
     // Enable the language switcher block.
-    $edit = array('machine_name' => 'language_switcher', 'region' => 'sidebar_first');
-    $this->drupalPost('admin/structure/block/manage/language_block:language_interface/bartik', $edit, t('Save block'));
+    $this->drupalPlaceBlock('language_block:language_interface');
 
     // Reset static caches in our local language environment.
     $this->resetCaches();
diff --git a/core/modules/user/lib/Drupal/user/Plugin/block/block/UserNewBlock.php b/core/modules/user/lib/Drupal/user/Plugin/block/block/UserNewBlock.php
index 7f97df6..1f254c3 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/block/block/UserNewBlock.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/block/block/UserNewBlock.php
@@ -58,7 +58,9 @@ public function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['whois_new_count'] = $form_state['values']['user_block_whois_new_count'];
+    return array(
+      'whois_new_count' => $form_state['values']['user_block_whois_new_count'],
+    );
   }
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/Plugin/block/block/UserOnlineBlock.php b/core/modules/user/lib/Drupal/user/Plugin/block/block/UserOnlineBlock.php
index 75f23f0..21e9ddc 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/block/block/UserOnlineBlock.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/block/block/UserOnlineBlock.php
@@ -71,8 +71,10 @@ public function blockForm($form, &$form_state) {
    * Overrides \Drupal\block\BlockBase::blockSubmit().
    */
   public function blockSubmit($form, &$form_state) {
-    $this->configuration['seconds_online'] = $form_state['values']['user_block_seconds_online'];
-    $this->configuration['max_list_count'] = $form_state['values']['user_block_max_list_count'];
+    return array(
+      'seconds_online' => $form_state['values']['user_block_seconds_online'],
+      'max_list_count' => $form_state['values']['user_block_max_list_count'],
+    );
   }
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserBlocksTests.php b/core/modules/user/lib/Drupal/user/Tests/UserBlocksTests.php
index a4458d4..f78b227 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserBlocksTests.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserBlocksTests.php
@@ -41,20 +41,7 @@ function setUp() {
 
     $this->adminUser = $this->drupalCreateUser(array('administer blocks'));
     $this->drupalLogin($this->adminUser);
-
-    $block_id = 'user_login_block';
-    $default_theme = variable_get('theme_default', 'stark');
-
-    $block = array(
-      'title' => $this->randomName(8),
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-
-    // Enable the user login block.
-    $this->drupalPost('admin/structure/block/manage/' . $block_id . '/' . $default_theme, $block, t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), 'User login block enabled');
-    $this->plugin_id = 'plugin.core.block.' . $default_theme . '.' . $block['machine_name'];
+    $this->drupalPlaceBlock('user_login_block');
     $this->drupalLogout($this->adminUser);
   }
 
@@ -93,9 +80,8 @@ function testUserLoginBlock() {
    * Test the Who's Online block.
    */
   function testWhosOnlineBlock() {
-    $plugin_id = 'plugin.core.block.' . variable_get('theme_default', 'stark') . '.online';
-    $block = $this->container->get('plugin.manager.block')->getInstance(array('config' => $plugin_id));
-    $config = $block->getConfig();
+    $block = entity_load('block', 'stark.online');
+    $config = $block->getDefinition();
 
     // Generate users.
     $user1 = $this->drupalCreateUser(array());
@@ -113,7 +99,7 @@ function testWhosOnlineBlock() {
     $this->updateAccess($this->adminUser->uid, $inactive_time);
 
     // Test block output.
-    $content = $block->build();
+    $content = $block->getPlugin()->build();
     $this->drupalSetContent(render($content));
     $this->assertRaw(t('2 users'), 'Correct number of online users (2 users).');
     $this->assertText($user1->name, 'Active user 1 found in online list.');
diff --git a/core/modules/views/lib/Drupal/views/Tests/UI/OverrideDisplaysTest.php b/core/modules/views/lib/Drupal/views/Tests/UI/OverrideDisplaysTest.php
index 7d0d0cc..be4868e 100644
--- a/core/modules/views/lib/Drupal/views/Tests/UI/OverrideDisplaysTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/UI/OverrideDisplaysTest.php
@@ -53,15 +53,12 @@ function testOverrideDisplays() {
     $this->assertResponse(200);
     $this->assertText($original_title);
 
-    // Put the block into the first sidebar region.
-    $default_theme = variable_get('theme_default', 'stark');
-    $this->drupalGet("admin/structure/block/list/block_plugin_ui:{$default_theme}/add");
+    // Confirm that the view block is available in the block administration UI.
+    $this->drupalGet('admin/structure/block/list/block_plugin_ui:' . variable_get('theme_default', 'stark') . '/add');
     $this->assertText('View: ' . $view['human_name']);
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost("admin/structure/block/manage/views_block:{$view['name']}-block_1/{$default_theme}", $block, t('Save block'));
+
+    // Place the block.
+    $this->drupalPlaceBlock("views_block:{$view['name']}-block_1");
 
     // Make sure the title appears in the block.
     $this->drupalGet('');
@@ -115,15 +112,12 @@ function testWizardMixedDefaultOverriddenDisplays() {
     $this->assertText($view['page[title]']);
     $this->assertNoText($view['block[title]']);
 
-    // Put the block into the first sidebar region.
-    $default_theme = variable_get('theme_default', 'stark');
-    $this->drupalGet("admin/structure/block/list/block_plugin_ui:{$default_theme}/add");
+    // Confirm that the block is available in the block administration UI.
+    $this->drupalGet('admin/structure/block/list/block_plugin_ui:' . variable_get('theme_default', 'stark') . '/add');
     $this->assertText('View: ' . $view['human_name']);
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost("admin/structure/block/manage/views_block:{$view['name']}-block_1/{$default_theme}", $block, t('Save block'));
+
+    // Place the block.
+    $this->drupalPlaceBlock("views_block:{$view['name']}-block_1");
     $this->drupalGet('');
     $this->assertText($view['block[title]']);
     $this->assertNoText($view['page[title]']);
diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/BasicTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/BasicTest.php
index 757cde2..aff9227 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Wizard/BasicTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/BasicTest.php
@@ -122,15 +122,12 @@ function testViewsWizardAndListing() {
     $this->assertText($view3['description']);
     $this->assertLinkByHref(url($view3['page[path]']));
 
-    // Put the block into the first sidebar region.
-    $default_theme = variable_get('theme_default', 'stark');
-    $this->drupalGet("admin/structure/block/list/block_plugin_ui:{$default_theme}/add");
+    // Confirm that the block is available in the block administration UI.
+    $this->drupalGet('admin/structure/block/list/block_plugin_ui:' . variable_get('theme_default', 'stark') . '/add');
     $this->assertText('View: ' . $view3['human_name']);
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost("admin/structure/block/manage/views_block:{$view3['name']}-block_1/{$default_theme}", $block, t('Save block'));
+
+    // Place the block.
+    $this->drupalPlaceBlock("views_block:{$view3['name']}-block_1");
 
     // Visit a random page (not the one that displays the view itself) and look
     // for the expected node title in the block.
diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/ItemsPerPageTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/ItemsPerPageTest.php
index c5be21b..95f4709 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Wizard/ItemsPerPageTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/ItemsPerPageTest.php
@@ -74,17 +74,12 @@ function testItemsPerPage() {
     $pos2 = strpos($content, $node2->label());
     $this->assertTrue($pos5 < $pos4 && $pos4 < $pos3 && $pos3 < $pos2, t('The nodes appear in the expected order in the page display.'));
 
-    $default_theme = variable_get('theme_default', 'stark');
-    $this->drupalGet("admin/structure/block/list/block_plugin_ui:{$default_theme}/add");
+    // Confirm that the block is listed in the block administration UI.
+    $this->drupalGet('admin/structure/block/list/block_plugin_ui:' . variable_get('theme_default', 'stark') . '/add');
     $this->assertText('View: ' . $view['human_name']);
-    // Put the block into the first sidebar region, visit a page that displays
-    // the block, and check that the nodes we expect appear in the correct
-    // order.
-    $block = array(
-      'machine_name' => $this->randomName(8),
-      'region' => 'sidebar_first',
-    );
-    $this->drupalPost("admin/structure/block/manage/views_block:{$view['name']}-block_1/{$default_theme}", $block, t('Save block'));
+    // Place the block, visit a page that displays the block, and check that the
+    // nodes we expect appear in the correct order.
+    $this->drupalPlaceBlock("views_block:{$view['name']}-block_1");
 
     $this->drupalGet('user');
     $content = $this->drupalGetContent();
diff --git a/core/profiles/standard/config/plugin.core.block.bartik.content.yml b/core/profiles/standard/config/plugin.core.block.bartik.content.yml
index e10f903..6ef1dc4 100644
--- a/core/profiles/standard/config/plugin.core.block.bartik.content.yml
+++ b/core/profiles/standard/config/plugin.core.block.bartik.content.yml
@@ -1,4 +1,5 @@
-id: system_main_block
+id: bartik.content
+pluginID: system_main_block
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: ''
+label: ''
 module: system
 region: content
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.bartik.footer.yml b/core/profiles/standard/config/plugin.core.block.bartik.footer.yml
index 7b6f9b7..89f90e9 100644
--- a/core/profiles/standard/config/plugin.core.block.bartik.footer.yml
+++ b/core/profiles/standard/config/plugin.core.block.bartik.footer.yml
@@ -1,7 +1,8 @@
-id: 'system_menu_block:menu-footer'
+id: bartik.footer
+pluginID: 'system_menu_block:menu-footer'
 status: '1'
 cache: '-1'
-subject: 'Footer menu'
+label: 'Footer menu'
 visibility:
   path:
     visibility: '0'
@@ -16,3 +17,4 @@ visibility:
 module: system
 region: footer
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.bartik.help.yml b/core/profiles/standard/config/plugin.core.block.bartik.help.yml
index a5c4467..3e11b40 100644
--- a/core/profiles/standard/config/plugin.core.block.bartik.help.yml
+++ b/core/profiles/standard/config/plugin.core.block.bartik.help.yml
@@ -1,4 +1,5 @@
-id: system_help_block
+id: bartik.help
+pluginID: system_help_block
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: ''
+label: ''
 module: system
 region: help
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.bartik.login.yml b/core/profiles/standard/config/plugin.core.block.bartik.login.yml
index 8d8923a..5f08fcc 100644
--- a/core/profiles/standard/config/plugin.core.block.bartik.login.yml
+++ b/core/profiles/standard/config/plugin.core.block.bartik.login.yml
@@ -1,4 +1,4 @@
-id: user_login_block
+id: bartik.login
 whois_new_count: '5'
 status: '1'
 cache: '-1'
@@ -13,7 +13,9 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: 'User login'
+label: 'User login'
 module: user
 region: sidebar_first
 weight: '0'
+pluginID: user_login_block
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.bartik.navigation.yml b/core/profiles/standard/config/plugin.core.block.bartik.navigation.yml
index f16c6f4..4fe2f30 100644
--- a/core/profiles/standard/config/plugin.core.block.bartik.navigation.yml
+++ b/core/profiles/standard/config/plugin.core.block.bartik.navigation.yml
@@ -1,4 +1,5 @@
-id: 'system_menu_block:menu-main'
+id: bartik.navigation
+pluginID: 'system_menu_block:menu-main'
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: 'Main navigation'
+label: 'Main navigation'
 module: system
 region: sidebar_first
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.bartik.powered.yml b/core/profiles/standard/config/plugin.core.block.bartik.powered.yml
index 3ef20d7..b0a6ad3 100644
--- a/core/profiles/standard/config/plugin.core.block.bartik.powered.yml
+++ b/core/profiles/standard/config/plugin.core.block.bartik.powered.yml
@@ -1,4 +1,5 @@
-id: system_powered_by_block
+id: bartik.powered
+pluginID: system_powered_by_block
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: ''
+label: ''
 module: system
 region: footer
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.bartik.search.yml b/core/profiles/standard/config/plugin.core.block.bartik.search.yml
index 466659b..a7e7e82 100644
--- a/core/profiles/standard/config/plugin.core.block.bartik.search.yml
+++ b/core/profiles/standard/config/plugin.core.block.bartik.search.yml
@@ -1,4 +1,5 @@
-id: search_form_block
+id: bartik.search
+pluginID: search_form_block
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: 'Search'
+label: 'Search'
 module: search
 region: sidebar_first
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.bartik.tools.yml b/core/profiles/standard/config/plugin.core.block.bartik.tools.yml
index d6a38c9..859983d 100644
--- a/core/profiles/standard/config/plugin.core.block.bartik.tools.yml
+++ b/core/profiles/standard/config/plugin.core.block.bartik.tools.yml
@@ -1,4 +1,5 @@
-id: 'system_menu_block:menu-tools'
+id: bartik.tools
+pluginID: 'system_menu_block:menu-tools'
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: 'Tools'
+label: 'Tools'
 module: system
 region: sidebar_first
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.seven.content.yml b/core/profiles/standard/config/plugin.core.block.seven.content.yml
index 51b155f..2056e8e 100644
--- a/core/profiles/standard/config/plugin.core.block.seven.content.yml
+++ b/core/profiles/standard/config/plugin.core.block.seven.content.yml
@@ -1,4 +1,5 @@
-id: system_main_block
+id: seven.content
+pluginID: system_main_block
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: ''
+label: ''
 module: system
 region: content
 weight: '-3'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.seven.help.yml b/core/profiles/standard/config/plugin.core.block.seven.help.yml
index a5c4467..f534345 100644
--- a/core/profiles/standard/config/plugin.core.block.seven.help.yml
+++ b/core/profiles/standard/config/plugin.core.block.seven.help.yml
@@ -1,4 +1,5 @@
-id: system_help_block
+id: bartik.content
+pluginID: system_help_block
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: ''
+label: ''
 module: system
 region: help
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.seven.login.yml b/core/profiles/standard/config/plugin.core.block.seven.login.yml
index 8352fab..48ff539 100644
--- a/core/profiles/standard/config/plugin.core.block.seven.login.yml
+++ b/core/profiles/standard/config/plugin.core.block.seven.login.yml
@@ -1,6 +1,7 @@
 region: '-1'
-id: user_login_block
-whois_new_count: '5'
+id: seven.login
+plugin:
+  whois_new_count: '5'
 status: '1'
 cache: '-1'
 visibility:
@@ -14,6 +15,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: 'User login'
+label: 'User login'
 module: user
 weight: '-3'
+pluginID: user_login_block
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.seven.navigation.yml b/core/profiles/standard/config/plugin.core.block.seven.navigation.yml
index 7fc3e2c..b20356c 100644
--- a/core/profiles/standard/config/plugin.core.block.seven.navigation.yml
+++ b/core/profiles/standard/config/plugin.core.block.seven.navigation.yml
@@ -1,5 +1,6 @@
+id: bartik.content
 region: '-1'
-id: 'system_menu_block:menu-main'
+pluginID: 'system_menu_block:menu-main'
 status: '1'
 cache: '-1'
 visibility:
@@ -13,6 +14,7 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: 'Main navigation'
+label: 'Main navigation'
 module: system
 weight: '-2'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.seven.powered.yml b/core/profiles/standard/config/plugin.core.block.seven.powered.yml
index b9aac19..1720760 100644
--- a/core/profiles/standard/config/plugin.core.block.seven.powered.yml
+++ b/core/profiles/standard/config/plugin.core.block.seven.powered.yml
@@ -1,5 +1,6 @@
+id: bartik.content
 region: '-1'
-id: system_powered_by_block
+pluginID: system_powered_by_block
 status: '1'
 cache: '-1'
 visibility:
@@ -13,6 +14,7 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: ''
+label: ''
 module: system
 weight: '0'
+langcode: und
diff --git a/core/profiles/standard/config/plugin.core.block.seven.search.yml b/core/profiles/standard/config/plugin.core.block.seven.search.yml
index 081dfca..e3be82c 100644
--- a/core/profiles/standard/config/plugin.core.block.seven.search.yml
+++ b/core/profiles/standard/config/plugin.core.block.seven.search.yml
@@ -1,5 +1,6 @@
+id: bartik.content
 region: '-1'
-id: search_form_block
+pluginID: search_form_block
 status: '1'
 cache: '-1'
 visibility:
@@ -13,6 +14,7 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: 'Search'
+label: 'Search'
 module: search
 weight: '-1'
+langcode: und
diff --git a/core/profiles/testing/config/plugin.core.block.stark.admin.yml b/core/profiles/testing/config/plugin.core.block.stark.admin.yml
index 960e2cb..7e89a77 100644
--- a/core/profiles/testing/config/plugin.core.block.stark.admin.yml
+++ b/core/profiles/testing/config/plugin.core.block.stark.admin.yml
@@ -1,4 +1,5 @@
-id: 'system_menu_block:menu-admin'
+id: stark.admin
+pluginID: 'system_menu_block:menu-admin'
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: ''
+label: ''
 module: system
 region: sidebar_first
 weight: '0'
+langcode: und
diff --git a/core/profiles/testing/config/plugin.core.block.stark.online.yml b/core/profiles/testing/config/plugin.core.block.stark.online.yml
index 3b3f5c5..286103d 100644
--- a/core/profiles/testing/config/plugin.core.block.stark.online.yml
+++ b/core/profiles/testing/config/plugin.core.block.stark.online.yml
@@ -1,11 +1,14 @@
-id: user_online_block
-properties:
-  administrative: '1'
-seconds_online: '900'
-max_list_count: '10'
+id: stark.online
+label: 'Who''s online'
+pluginID: user_online_block
+plugin:
+  properties:
+    administrative: '1'
+  seconds_online: '900'
+  max_list_count: '10'
 status: '1'
 cache: '-1'
-subject: 'Who''s online'
+label: 'Who''s online'
 visibility:
   path:
     visibility: '0'
@@ -21,3 +24,4 @@ visibility:
 module: user
 region: sidebar_first
 weight: '0'
+langcode: und
diff --git a/core/profiles/testing/config/plugin.core.block.stark.tools.yml b/core/profiles/testing/config/plugin.core.block.stark.tools.yml
index 5e8b188..71d81eb 100644
--- a/core/profiles/testing/config/plugin.core.block.stark.tools.yml
+++ b/core/profiles/testing/config/plugin.core.block.stark.tools.yml
@@ -1,4 +1,5 @@
-id: 'system_menu_block:menu-tools'
+id: stark.tools
+pluginID: 'system_menu_block:menu-tools'
 status: '1'
 cache: '-1'
 visibility:
@@ -12,7 +13,8 @@ visibility:
       article: '0'
       page: '0'
   visibility__active_tab: edit-visibility-path
-subject: ''
+label: ''
 module: system
 region: sidebar_first
 weight: '0'
+langcode: und
