diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index e49bb76..52917a4 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1103,20 +1103,6 @@ function theme($hook, $variables = array()) {
       template_preprocess($default_template_variables, $hook, $info);
       $variables += $default_template_variables;
     }
-    if (!isset($default_attributes)) {
-      $default_attributes = new Attribute();
-    }
-    foreach (array('attributes', 'title_attributes', 'content_attributes') as $key) {
-      if (isset($variables[$key]) && !($variables[$key] instanceof Attribute)) {
-        if ($variables[$key]) {
-          $variables[$key] = new Attribute($variables[$key]);
-        }
-        else {
-          // Create empty attributes.
-          $variables[$key] = clone $default_attributes;
-        }
-      }
-    }
 
     // Render the output using the template file.
     $template_file = $info['template'] . $extension;
@@ -2312,6 +2298,7 @@ function template_preprocess_feed_icon(&$variables) {
   $variables['attributes']['class'] = array('feed-icon');
   // Stripping tags because that's what l() used to do.
   $variables['attributes']['title'] = strip_tags($text);
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
@@ -2462,9 +2449,6 @@ function template_preprocess(&$variables, $hook, $info) {
 function _template_preprocess_default_variables() {
   // Variables that don't depend on a database connection.
   $variables = array(
-    'attributes' => array(),
-    'title_attributes' => array(),
-    'content_attributes' => array(),
     'title_prefix' => array(),
     'title_suffix' => array(),
     'db_is_active' => !defined('MAINTENANCE_MODE'),
@@ -2544,6 +2528,8 @@ function template_preprocess_html(&$variables) {
     $variables['attributes']['class'][] = drupal_html_class('node-type-' . $node->getType());
   }
 
+  $variables['attributes'] = new Attribute($variables['attributes']);
+
   // Initializes attributes which are specific to the html and body elements.
   $variables['html_attributes'] = new Attribute;
 
@@ -2930,6 +2916,8 @@ function template_preprocess_maintenance_page(&$variables) {
     $variables['attributes']['class'][] = 'sidebar-' . $variables['layout'];
   }
 
+  $variables['attributes'] = new Attribute($variables['attributes']);
+
   $variables['head'] = drupal_get_html_head();
 
   // While this code is used in the installer, the language module may not be
@@ -2994,6 +2982,8 @@ function template_preprocess_region(&$variables) {
 
   $variables['attributes']['class'][] = 'region';
   $variables['attributes']['class'][] = drupal_html_class('region-' . $variables['region']);
+
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module
index c2da795..32d9ae9 100644
--- a/core/modules/aggregator/aggregator.module
+++ b/core/modules/aggregator/aggregator.module
@@ -472,4 +472,5 @@ function aggregator_preprocess_block(&$variables) {
   if ($variables['configuration']['module'] == 'aggregator') {
     $variables['attributes']['role'] = 'complementary';
   }
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
diff --git a/core/modules/aggregator/aggregator.pages.inc b/core/modules/aggregator/aggregator.pages.inc
index a711c18..8b53a5c 100644
--- a/core/modules/aggregator/aggregator.pages.inc
+++ b/core/modules/aggregator/aggregator.pages.inc
@@ -247,4 +247,5 @@ function template_preprocess_aggregator_feed_source(&$variables) {
   }
 
   $variables['attributes']['class'][] = 'feed-source';
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index f1112d6..dc28595 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -7,6 +7,7 @@
 
 use Drupal\Component\Plugin\Exception\PluginException;
 use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Template\Attribute;
 
 /**
  * Denotes that a block is not enabled in any region and should not be shown.
@@ -552,6 +553,9 @@ function template_preprocess_block(&$variables) {
   // them through to the content's #theme function/template. This allows the
   // content to not require a function/template at all, or if it does use one,
   // to not require it to output an extra wrapping element.
+  if(!isset($variables['content_attributes'])) {
+    $variables['content_attributes'] = array();
+  }
   if (isset($variables['content']['#attributes'])) {
     $variables['content_attributes'] = NestedArray::mergeDeep($variables['content_attributes'], $variables['content']['#attributes']);
     unset($variables['content']['#attributes']);
@@ -559,6 +563,7 @@ function template_preprocess_block(&$variables) {
 
   // Add default class for block content.
   $variables['content_attributes']['class'][] = 'content';
+  $variables['content_attributes'] = new Attribute($variables['content_attributes']);
 
   // Create a valid HTML ID and make sure it is unique.
   if ($id = $variables['elements']['#block']->id()) {
@@ -566,6 +571,8 @@ function template_preprocess_block(&$variables) {
     $machine_name = array_pop($config_id);
     $variables['attributes']['id'] = drupal_html_id('block-' . $machine_name);
   }
+  $variables['title_attributes'] = '';
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index aef8a52..0613d82 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -665,6 +665,7 @@ function book_preprocess_block(&$variables) {
   if ($variables['configuration']['module'] == 'book') {
     $variables['attributes']['role'] = 'navigation';
   }
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 1081ed4..c33b91c 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -12,6 +12,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityChangedInterface;
+use Drupal\Core\Template\Attribute;
 use Drupal\comment\CommentInterface;
 use Drupal\comment\Entity\Comment;
 use Drupal\entity\Entity\EntityDisplay;
@@ -1424,6 +1425,7 @@ function comment_preprocess_block(&$variables) {
   if ($variables['configuration']['module'] == 'comment') {
     $variables['attributes']['role'] = 'navigation';
   }
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
@@ -1576,8 +1578,11 @@ function template_preprocess_comment(&$variables) {
 
   // Add comment author user ID. Necessary for the comment-by-viewer library.
   $variables['attributes']['data-comment-user-id'] = $comment->uid->value;
+  $variables['attributes'] = new Attribute($variables['attributes']);
 
   $variables['content_attributes']['class'][] = 'content';
+  $variables['content_attributes'] = new Attribute($variables['content_attributes']);
+
 }
 
 /**
@@ -1653,6 +1658,7 @@ function template_preprocess_comment_wrapper(&$variables) {
 
   // Add a comment wrapper class.
   $variables['attributes']['class'][] = 'comment-wrapper';
+  $variables['attributes'] = new Attribute($variables['attributes']);
 
   // Create separate variables for the comments and comment form.
   $variables['comments'] = $variables['content']['comments'];
diff --git a/core/modules/contextual/contextual.module b/core/modules/contextual/contextual.module
index 529fa5c..94fd61e 100644
--- a/core/modules/contextual/contextual.module
+++ b/core/modules/contextual/contextual.module
@@ -5,6 +5,8 @@
  * Adds contextual links to perform actions related to elements on a page.
  */
 
+use Drupal\Core\Template\Attribute;
+
 /**
  * Implements hook_menu().
  */
@@ -198,6 +200,7 @@ function contextual_preprocess(&$variables, $hook, $info) {
   if (isset($element) && is_array($element) && !empty($element['#contextual_links'])) {
     // Mark this element as potentially having contextual links attached to it.
     $variables['attributes']['class'][] = 'contextual-region';
+    $variables['attributes'] = new Attribute($variables['attributes']);
 
     // Renders a contextual links placeholder unconditionally, thus not breaking
     // the render cache. Although the empty placeholder is rendered for all
diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module
index c6d9af0..38ab8d9 100644
--- a/core/modules/datetime/datetime.module
+++ b/core/modules/datetime/datetime.module
@@ -242,7 +242,6 @@ function datetime_date_default_time($date) {
 function template_preprocess_datetime_form(&$variables) {
   $element = $variables['element'];
 
-  $variables['attributes'] = array();
   if (isset($element['#id'])) {
     $variables['attributes']['id'] = $element['#id'];
   }
@@ -251,6 +250,7 @@ function template_preprocess_datetime_form(&$variables) {
   }
   $variables['attributes']['class'][] = 'container-inline';
 
+  $variables['attributes'] = new Attribute($variables['attributes']);
   $variables['content'] = $element;
 }
 
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 84fd041..70d5db0 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -684,9 +684,9 @@ function template_preprocess_field(&$variables, $hook) {
   // below only get instantiated for template file implementations, and we need
   // Attribute objects for printing in both theme functions and template files.
   // For best performance, we only instantiate Attribute objects when needed.
-  $variables['attributes'] = isset($variables['attributes']) ? new Attribute($variables['attributes']) : clone $default_attributes;
-  $variables['title_attributes'] = isset($variables['title_attributes']) ? new Attribute($variables['title_attributes']) : clone($default_attributes);
-  $variables['content_attributes'] = isset($variables['content_attributes']) ? new Attribute($variables['content_attributes']) : clone($default_attributes);
+  $variables['attributes'] = clone $default_attributes;
+  $variables['title_attributes'] = clone($default_attributes);
+  $variables['content_attributes'] = clone($default_attributes);
 
   // Modules (e.g., rdf.module) can add field item attributes (to
   // $item->_attributes) within hook_entity_prepare_view(). Some field
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 4593c72..6c6e077 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -585,6 +585,7 @@ function forum_block_view_pre_render($elements) {
 function forum_preprocess_block(&$variables) {
   if ($variables['configuration']['module'] == 'forum') {
     $variables['attributes']['role'] = 'navigation';
+    $variables['attributes'] = new Attribute($variables['attributes']);
   }
 }
 
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 772481b9..03b3115 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -743,7 +743,9 @@ function template_preprocess_node(&$variables) {
   if (isset($variables['preview'])) {
     $variables['attributes']['class'][] = 'preview';
   }
+  $variables['attributes'] = new Attribute($variables['attributes']);
   $variables['content_attributes']['class'][] = 'content';
+  $variables['content_attributes'] = new Attribute($variables['content_attributes']);
 }
 
 /**
diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module
index 912e29d..1444cd4 100644
--- a/core/modules/overlay/overlay.module
+++ b/core/modules/overlay/overlay.module
@@ -5,6 +5,7 @@
  * Displays the Drupal administration interface in an overlay.
  */
 
+use Drupal\Core\Template\Attribute;
 use Drupal\Core\Template\RenderWrapper;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Response;
@@ -377,11 +378,14 @@ function template_preprocess_overlay(&$variables) {
   // Add attributes for the overlay container.
   $variables['attributes']['id'] = 'overlay';
   $variables['attributes']['class'][] = 'overlay';
+  $variables['attributes'] = new Attributes($variables['attributes']);
   // Add attributes for the overlay title.
   $variables['title_attributes']['id'] = 'overlay-title';
+  $variables['title_attributes'] = new Attributes($variables['title_attributes']);
   // Add attributes for the overlay content.
   $variables['content_attributes']['id'] = 'overlay-content';
   $variables['content_attributes']['class'][] = 'clearfix';
+  $variables['content_attributes'] = new Attributes($variables['content_attributes']);
 }
 
 /**
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 08cd24c..5dec24a 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -275,6 +275,7 @@ function rdf_preprocess_node(&$variables) {
   $bundle_mapping = $mapping->getPreparedBundleMapping('node', $bundle);
   $variables['attributes']['about'] = empty($variables['node_url']) ? NULL: $variables['node_url'];
   $variables['attributes']['typeof'] = empty($bundle_mapping['types']) ? NULL : $bundle_mapping['types'];
+  $variables['attributes'] = new Attribute($variables['attributes']);
 
   // Adds RDFa markup for the node title as metadata because wrapping the title
   // with markup is not reliable and the title output is different depdending on
@@ -362,6 +363,7 @@ function rdf_preprocess_user(&$variables) {
   if (!empty($bundle_mapping['types'])) {
     $variables['attributes']['typeof'] = $bundle_mapping['types'];
     $variables['attributes']['about'] = url($uri['path'], $uri['options']);
+    $variables['attributes'] = new Attribute($variables['attributes']);
   }
   // If we are on the user account page, add the relationship between the
   // sioc:UserAccount and the foaf:Person who holds the account.
@@ -438,7 +440,11 @@ function rdf_preprocess_username(&$variables) {
     $variables['link_options']['attributes'] = array_merge_recursive($variables['link_options']['attributes'], $attributes);
   }
   else {
+    if (!isset($variables['attributes'])) {
+      $variables['attributes'] = array();
+    }
     $variables['attributes'] = array_merge_recursive($variables['attributes'], $attributes);
+    $variables['attributes'] = new Attribute($variables['attributes']);
   }
 }
 
@@ -494,6 +500,7 @@ function rdf_preprocess_comment(&$variables) {
     // is a literal.
     $variables['title_attributes']['property'] = $title_mapping['properties'];
     $variables['title_attributes']['datatype'] = '';
+    $variables['title_attributes'] = new Attribute($variables['title_attributes']);
   }
 
   // Annotates the parent relationship between the current comment and the node
@@ -560,6 +567,7 @@ function rdf_preprocess_image(&$variables) {
   // to get 'foaf:Image' because image does not have its own entity type or
   // bundle.
   $variables['attributes']['typeof'] = array('foaf:Image');
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index c7bed06..3999618 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Template\Attribute;
 use Drupal\Component\Utility\Unicode;
 use Drupal\search\SearchExpression;
 use Drupal\search\Plugin\SearchInterface;
@@ -142,7 +143,9 @@ function search_permission() {
 function search_preprocess_block(&$variables) {
   if ($variables['plugin_id'] == 'search_form_block') {
     $variables['attributes']['role'] = 'search';
+    $variables['attributes'] = new Attribute($variables['attributes']);
     $variables['content_attributes']['class'][] = 'container-inline';
+    $variables['content_attributes'] = new Attribute($variables['content_attributes']);
   }
 }
 
diff --git a/core/modules/search/search.pages.inc b/core/modules/search/search.pages.inc
index 5b1e1a0..c1689e3 100644
--- a/core/modules/search/search.pages.inc
+++ b/core/modules/search/search.pages.inc
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Language\Language;
+use Drupal\Core\Template\Attribute;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 
 /**
@@ -140,7 +141,9 @@ function template_preprocess_search_result(&$variables) {
   $variables['title'] = check_plain($result['title']);
   if (isset($result['language']) && $result['language'] != $language_interface->id && $result['language'] != Language::LANGCODE_NOT_SPECIFIED) {
     $variables['title_attributes']['lang'] = $result['language'];
+    $variables['title_attributes'] = new Attribute($variables['title_attributes']);
     $variables['content_attributes']['lang'] = $result['language'];
+    $variables['content_attributes'] = new Attribute($variables['content_attributes']);
   }
 
   $info = array();
diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc
index 2977253..c931c00 100644
--- a/core/modules/user/user.pages.inc
+++ b/core/modules/user/user.pages.inc
@@ -10,6 +10,7 @@
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Drupal\Component\Utility\Crypt;
+use Drupal\Core\Template\Attribute;
 
 /**
  * Menu callback; process one time login link and redirects to the user page on success.
@@ -118,6 +119,7 @@ function template_preprocess_user(&$variables) {
 
   // Set up attributes.
   $variables['attributes']['class'][] = 'profile';
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index f8f9ff5..b4a469c 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -506,7 +506,7 @@ function views_preprocess_html(&$variables) {
   // remove the "contextual-region" class from the <body> tag here and add
   // JavaScript that will insert it back in the correct place.
   if (!empty($variables['page']['#views_contextual_links'])) {
-    $key = array_search('contextual-region', $variables['attributes']['class']);
+    $key = array_search('contextual-region', $variables['attributes']['class']->value());
     if ($key !== FALSE) {
       unset($variables['attributes']['class'][$key]);
       $variables['attributes']['data-views-page-contextual-id'] = $variables['title_suffix']['contextual_links']['#id'];
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 65f8ac4..48cd53d 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -147,6 +147,8 @@ function template_preprocess_views_view(&$variables) {
     }
     $variables['rows'] = $form;
   }
+
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
diff --git a/core/modules/views_ui/views_ui.theme.inc b/core/modules/views_ui/views_ui.theme.inc
index 38a8fe4..75da1b2 100644
--- a/core/modules/views_ui/views_ui.theme.inc
+++ b/core/modules/views_ui/views_ui.theme.inc
@@ -50,6 +50,8 @@ function template_preprocess_views_ui_display_tab_setting(&$variables) {
   if ($variables['description'] && $variables['description_separator']) {
     $variables['description'] .= t(':');
   }
+
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
diff --git a/core/themes/bartik/bartik.theme b/core/themes/bartik/bartik.theme
index 593923a..d7935a1 100644
--- a/core/themes/bartik/bartik.theme
+++ b/core/themes/bartik/bartik.theme
@@ -5,6 +5,7 @@
  * Functions to support theming in the Bartik theme.
  */
 
+use Drupal\Core\Template\Attribute;
 use Drupal\Core\Template\RenderWrapper;
 
 /**
@@ -29,6 +30,7 @@ function bartik_preprocess_html(&$variables) {
     || !empty($variables['page']['footer_fourthcolumn'])) {
     $variables['attributes']['class'][] = 'footer-columns';
   }
+  $variables['attributes'] = new Attribute($variables['attributes']);
 }
 
 /**
@@ -176,7 +178,7 @@ function bartik_field__taxonomy_term_reference($variables) {
 
   // Render the top-level DIV.
   $variables['attributes']['class'][] = 'clearfix';
-  $output = '<div ' . $variables['attributes'] . '>' . $output . '</div>';
+  $output = '<div ' . new Attribute($variables['attributes']) . '>' . $output . '</div>';
 
   return $output;
 }
