diff --git a/core/includes/form.inc b/core/includes/form.inc
index 3ebaca1..532c52d 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -2737,26 +2737,20 @@ function form_process_select($element) {
 }
 
 /**
- * Returns HTML for a select form element.
+ * Prepares variables for select element templates.
  *
- * It is possible to group options together; to do this, change the format of
- * $options to an associative array in which the keys are group labels, and the
- * values are associative arrays in the normal $options format.
+ * Default template: select.html.twig,
  *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
  *     Properties used: #title, #value, #options, #description, #extra,
  *     #multiple, #required, #name, #attributes, #size.
- *
- * @ingroup themeable
  */
-function theme_select($variables) {
+function template_preprocess_select(&$variables) {
   $element = $variables['element'];
-  element_set_attributes($element, array('id', 'name', 'size'));
-  _form_set_attributes($element, array('form-select'));
-
-  return '<select' . new Attribute($element['#attributes']) . '>' . form_select_options($element) . '</select>';
+  $variables['options'] = form_select_options($element);
+  $variables['attributes'] = new Attribute($element['#attributes']);
 }
 
 /**
@@ -2858,90 +2852,74 @@ function form_get_options($element, $key) {
 }
 
 /**
- * Returns HTML for a fieldset form element and its children.
+ * Prepares variables for fieldset templates.
+ *
+ * Default template: fieldset.html.twig.
  *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
- *     Properties used: #attributes, #children, #collapsed, #description, #id,
- *     #title, #value.
- *
- * @ingroup themeable
+ *     Properties used: #attributes, #id, #title, #description, #children,
+ *       #value.
  */
-function theme_fieldset($variables) {
+function template_preprocess_fieldset(&$variables) {
   $element = $variables['element'];
-  element_set_attributes($element, array('id'));
-  _form_set_attributes($element, array('form-wrapper'));
-
-  if (!empty($element['#description'])) {
-    $description_id = $element['#attributes']['id'] . '--description';
-    $element['#attributes']['aria-describedby'] = $description_id;
-  }
 
-  $legend_attributes = array();
-  if (isset($element['#title_display']) && $element['#title_display'] == 'invisible') {
-    $legend_attributes['class'][] = 'element-invisible';
-  }
+  $variables['attributes'] = new Attribute($element['#attributes']);
 
-  $output = '<fieldset' . new Attribute($element['#attributes']) . '>';
   if (!empty($element['#title'])) {
-    // Always wrap fieldset legends in a SPAN for CSS positioning.
-    $output .= '<legend' . new Attribute($legend_attributes) . '><span class="fieldset-legend">' . $element['#title'] . '</span></legend>';
+    $variables['title'] = $element['#title'];
+    $variables['title_attributes'] = new Attribute(array());
+    if (isset($element['#title_display']) && $element['#title_display'] == 'invisible') {
+      $variables['title_attributes']['class'] = array('element-invisible');
+    }
   }
-  $output .= '<div class="fieldset-wrapper">';
-  if (!empty($element['#description'])) {
-    $attributes = array('class' => 'fieldset-description', 'id' => $description_id);
-    $output .= '<div' . new Attribute($attributes) . '>' . $element['#description'] . '</div>';
 
+  if (!empty($element['#description'])) {
+    $variables['description'] = $element['#description'];
+    $description_id = $element['#attributes']['id'] . '--description';
+    $variables['description_attributes'] = new Attribute(array(
+      'id' => $description_id,
+      'class' => array('fieldset-description'),
+      'aria-describedby' => $description_id,
+    ));
   }
-  $output .= $element['#children'];
-  if (isset($element['#value'])) {
-    $output .= $element['#value'];
-  }
-  $output .= '</div>';
-  $output .= "</fieldset>\n";
-  return $output;
+
+  $variables['children'] = $element['#children'];
+  $variables['value'] = (isset($element['#value'])) ? $element['#value'] : NULL;
 }
 
 /**
- * Returns HTML for a details form element and its children.
+ * Prepares variables for details form element templates.
+ *
+ * Default template: details.html.twig.
  *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
- *     Properties used: #attributes, #children, #collapsed, #description, #id,
- *     #title, #value.
+ *     Properties used: #attributes, #children, #collapsed, #collapsible,
+ *     #description, #id, #title, #value.
  *
  * @ingroup themeable
  */
-function theme_details($variables) {
+function template_preprocess_details(&$variables) {
   $element = $variables['element'];
-  element_set_attributes($element, array('id'));
-  _form_set_attributes($element, array('form-wrapper'));
 
-  $output = '<details' . new Attribute($element['#attributes']) . '>';
+  $variables['attributes'] = new Attribute($element['#attributes']);
+  $variables['summary_attributes'] = new Attribute(array());
   if (!empty($element['#title'])) {
-    $summary_attributes = new Attribute(array(
-      'role' => 'button',
-    ));
+    $variables['summary_attributes']['role'] = 'button';
     if (!empty($element['#attributes']['id'])) {
-      $summary_attributes['aria-controls'] = $element['#attributes']['id'];
+      $variables['summary_attributes']['aria-controls'] = $element['#attributes']['id'];
     }
-    $summary_attributes['aria-expanded'] = empty($element['#attributes']['open']) ? FALSE : TRUE;
-    $summary_attributes['aria-pressed'] = $summary_attributes['aria-expanded'];
-    $output .= '<summary' . $summary_attributes . '>' . $element['#title'] . '</summary>';
+    $variables['summary_attributes']['aria-expanded'] = empty($element['#attributes']['open']) ? FALSE : TRUE;
+    $variables['summary_attributes']['aria-pressed'] = $variables['summary_attributes']['aria-expanded'];
   }
-  $output .= '<div class="details-wrapper">';
-  if (!empty($element['#description'])) {
-    $output .= '<div class="details-description">' . $element['#description'] . '</div>';
-  }
-  $output .= $element['#children'];
-  if (isset($element['#value'])) {
-    $output .= $element['#value'];
-  }
-  $output .= '</div>';
-  $output .= "</details>\n";
-  return $output;
+
+  $variables['title'] = !empty($element['#title']) ? $element['#title'] : NULL;
+  $variables['description'] = !empty($element['#description']) ? $element['#description'] : NULL;
+  $variables['children'] = isset($element['#children']) ? $element['#children'] : NULL;
+  $variables['value'] = isset($element['#value']) ? $element['#value'] : NULL;
 }
 
 /**
@@ -2972,30 +2950,28 @@ function form_pre_render_radio($element) {
 }
 
 /**
- * Returns HTML for a set of radio button form elements.
+ * Prepares variables for radios templates.
+ *
+ * Default template: radios.html.twig.
  *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
- *     Properties used: #title, #value, #options, #description, #required,
- *     #attributes, #children.
- *
- * @ingroup themeable
+ *     Properties used: #attributes, #id, #children.
  */
-function theme_radios($variables) {
+function template_preprocess_radios(&$variables) {
   $element = $variables['element'];
-  $attributes = array();
+  $variables['attributes'] = new Attribute(array());
   if (isset($element['#id'])) {
-    $attributes['id'] = $element['#id'];
-  }
-  $attributes['class'] = 'form-radios';
-  if (!empty($element['#attributes']['class'])) {
-    $attributes['class'] .= ' ' . implode(' ', $element['#attributes']['class']);
+    $variables['attributes']['id'] = $element['#id'];
   }
+  $variables['attributes']['class'] = (!empty($element['#attributes']['class'])) ? $element['#attributes']['class'] : array();
+  $variables['attributes']['class'][] = 'form-radios';
   if (isset($element['#attributes']['title'])) {
-    $attributes['title'] = $element['#attributes']['title'];
+    $variables['attributes']['title'] = $element['#attributes']['title'];
   }
-  return '<div' . new Attribute($attributes) . '>' . (!empty($element['#children']) ? $element['#children'] : '') . '</div>';
+
+  $variables['children'] = !empty($element['#children']) ? $element['#children'] : '';
 }
 
 /**
@@ -3052,29 +3028,30 @@ function password_confirm_validate($element, &$element_state) {
 }
 
 /**
- * Returns HTML for an #date form element.
- *
+ * Prepares a #type 'date' render element for theme('input').
+ *`
  * Supports HTML5 types of 'date', 'datetime', 'datetime-local', and 'time'.
  * Falls back to a plain textfield. Used as a sub-element by the datetime
  * element type.
  *
- * @param array $variables
- *   An associative array containing:
- *   - element: An associative array containing the properties of the element.
- *     Properties used: #title, #value, #options, #description, #required,
- *     #attributes, #id, #name, #type, #min, #max, #step, #value, #size.
+ * @param array $element
+ *   An associative array containing the properties of the element.
+ *   Properties used: #title, #value, #options, #description, #required,
+ *   #attributes, #id, #name, #type, #min, #max, #step, #value, #size.
  *
- * @ingroup themeable
+ * Note: The input "name" attribute needs to be sanitized before output, which
+ *       is currently done by initializing Drupal\Core\Template\Attribute with
+ *       all the attributes.
+ *
+ * @return array
+ *   The $element with prepared variables ready for theme_input().
  */
-function theme_date($variables) {
-  $element = $variables['element'];
-  if (empty($element['attribute']['type'])) {
-    $element['attribute']['type'] = 'date';
-  }
-  element_set_attributes($element, array('id', 'name', 'type', 'min', 'max', 'step', 'value', 'size'));
-  _form_set_attributes($element, array('form-' . $element['attribute']['type']));
+function form_pre_render_date($element) {
+  $element['#attributes']['type'] = 'date';
+  element_set_attributes($element, array('id', 'name', 'min', 'max', 'step', 'value', 'size'));
+  _form_set_attributes($element, array('form-date'));
 
-  return '<input' . new Attribute($element['#attributes']) . ' />';
+  return $element;
 }
 
 /**
@@ -3150,7 +3127,7 @@ function form_pre_render_checkbox($element) {
 }
 
 /**
- * Returns HTML for a set of checkbox form elements.
+ * Prepares variables for a set of checkbox form elements.
  *
  * @param $variables
  *   An associative array containing:
@@ -3159,20 +3136,28 @@ function form_pre_render_checkbox($element) {
  *
  * @ingroup themeable
  */
-function theme_checkboxes($variables) {
+function template_preprocess_checkboxes(&$variables) {
   $element = $variables['element'];
-  $attributes = array();
+
   if (isset($element['#id'])) {
-    $attributes['id'] = $element['#id'];
+    $variables['attributes']['id'] = $element['#id'];
   }
-  $attributes['class'][] = 'form-checkboxes';
+  $variables['attributes']['class'] = array();
+  $variables['attributes']['class'][] = 'form-checkboxes';
   if (!empty($element['#attributes']['class'])) {
-    $attributes['class'] = array_merge($attributes['class'], $element['#attributes']['class']);
+    if (is_array($element['#attributes']['class'])) {
+      foreach ($element['#attributes']['class'] as $class) {
+        $variables['attributes']['class'][] = $class;
+      }
+    }
+    else {
+      $variables['attributes']['class'][] = $element['#attributes']['class'];
+    }
   }
   if (isset($element['#attributes']['title'])) {
-    $attributes['title'] = $element['#attributes']['title'];
+    $variables['attributes']['title'] = $element['#attributes']['title'];
   }
-  return '<div' . new Attribute($attributes) . '>' . (!empty($element['#children']) ? $element['#children'] : '') . '</div>';
+  $variables['children'] = !empty($element['#children']) ? $element['#children'] : '';
 }
 
 /**
@@ -3410,11 +3395,9 @@ function form_process_container($element, &$form_state) {
 }
 
 /**
- * Returns HTML to wrap child elements in a container.
+ * Prepares variables for container templates.
  *
- * Used for grouped form items. Can also be used as a #theme_wrapper for any
- * renderable element, to surround it with a <div> and add attributes such as
- * classes or an HTML id.
+ * Default template: container.html.twig.
  *
  * @param $variables
  *   An associative array containing:
@@ -3423,7 +3406,7 @@ function form_process_container($element, &$form_state) {
  *
  * @ingroup themeable
  */
-function theme_container($variables) {
+function template_preprocess_container(&$variables) {
   $element = $variables['element'];
 
   // Special handling for form elements.
@@ -3436,11 +3419,12 @@ function theme_container($variables) {
     $element['#attributes']['class'][] = 'form-wrapper';
   }
 
-  return '<div' . new Attribute($element['#attributes']) . '>' . $element['#children'] . '</div>';
+  $variables['children'] = $element['#children'];
+  $variables['attributes'] = new Attribute($element['#attributes']);
 }
 
 /**
- * Returns HTML for a table with radio buttons or checkboxes.
+ * Prepares variables for a table with radio buttons or checkboxes.
  *
  * @param $variables
  *   An associative array containing:
@@ -3478,11 +3462,8 @@ function theme_container($variables) {
  *       '#empty' => t('No content available.'),
  *     );
  *     @endcode
- *
- * @ingroup themeable
  */
-function theme_tableselect($variables) {
-  $element = $variables['element'];
+function form_pre_render_tableselect(array $element) {
   $rows = array();
   $header = $element['#header'];
   if (!empty($element['#options'])) {
@@ -3522,7 +3503,7 @@ function theme_tableselect($variables) {
     // checkboxes/radios in the first table column.
     if ($element['#js_select']) {
       // Add a "Select all" checkbox.
-      drupal_add_library('system', 'drupal.tableselect');
+      $element['#attached']['library'][] = array('system', 'drupal.tableselect');
       array_unshift($header, array('class' => array('select-all')));
     }
     else {
@@ -3531,7 +3512,11 @@ function theme_tableselect($variables) {
       array_unshift($header, '');
     }
   }
-  return theme('table', array('header' => $header, 'rows' => $rows, 'empty' => $element['#empty'], 'attributes' => $element['#attributes']));
+  // This is all we really change.
+  $element['#header'] = $header;
+  $element['#rows'] = $rows;
+
+  return $element;
 }
 
 /**
@@ -3922,11 +3907,13 @@ function form_process_group(&$element, &$form_state) {
  *   The modified element.
  */
 function form_pre_render_details($element) {
-  // The .form-wrapper class is required for #states to treat details like
-  // containers.
+  element_set_attributes($element, array('id'));
   if (!isset($element['#attributes']['class'])) {
     $element['#attributes']['class'] = array();
   }
+  // The .form-wrapper class is required for #states to treat details like
+  // containers.
+  _form_set_attributes($element, array('form-wrapper'));
 
   // Collapsible details.
   $element['#attached']['library'][] = array('system', 'drupal.collapse');
@@ -4060,18 +4047,17 @@ function form_pre_render_vertical_tabs($element) {
 }
 
 /**
- * Returns HTML for an element's children details as vertical tabs.
+ * Preapres an element's children details for vertical tabs templates.
+ *
+ * Default template: vertical-tabs.html.twig.
  *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties and children of
  *     the details element. Properties used: #children.
- *
- * @ingroup themeable
  */
-function theme_vertical_tabs($variables) {
-  $element = $variables['element'];
-  return '<div class="vertical-tabs-panes">' . $element['#children'] . '</div>';
+function template_preprocess_vertical_tabs(&$variables) {
+  $variables['children'] = $variables['element']['#children'];
 }
 
 /**
@@ -4113,33 +4099,17 @@ function form_process_autocomplete($element, &$form_state) {
 }
 
 /**
- * Preprocesses variables for theme_input().
+ * Prepares variables for input templates.
  *
- * @param array $variables
- *   An associative array containing:
- *   - element: An associative array containing the properties of the element.
- *
- * @ingroup themeable
- */
-function template_preprocess_input(&$variables) {
-  $element = $variables['element'];
-  $variables['attributes'] = new Attribute($element['#attributes']);
-}
-
-/**
- * Returns HTML for an input form element.
+ * Default template: input.html.twig.
  *
  * @param array $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
- *     Properties used: #attributes.
- *
- * @ingroup themeable
  */
-function theme_input($variables) {
-  $element = $variables['element'];
-  $attributes = $variables['attributes'];
-  return '<input' . $attributes . ' />' . drupal_render_children($element);
+function template_preprocess_input(&$variables) {
+  $variables['attributes'] = new Attribute($variables['element']['#attributes']);
+  $variables['children'] = drupal_render_children($variables['element']);
 }
 
 /**
@@ -4247,6 +4217,23 @@ function form_pre_render_textfield($element) {
 }
 
 /**
+ * Prepares a #type 'textarea' render element for theme('textarea').
+ *
+ * @param array $element
+ *   An associative array containing the properties of the element.
+ *   Properties used: #id, #name, #rows, #cols, #placeholder.
+ *
+ * @return array
+ *   The $element with prepared variables ready for theme('textarea').
+ */
+function form_pre_render_textarea($element) {
+  element_set_attributes($element, array('id', 'name', 'rows', 'cols', 'placeholder'));
+  _form_set_attributes($element, array('form-textarea'));
+
+  return $element;
+}
+
+/**
  * Prepares a #type 'email' render element for theme_input().
  *
  * @param array $element
@@ -4445,6 +4432,23 @@ function form_pre_render_search($element) {
 }
 
 /**
+ * Prepares a #type 'select' render element for theme('select').
+ *
+ * @param array $element
+ *   An associative array containing the properties of the element.
+ *   Properties used: #id, #name, #size.
+ *
+ * @return array
+ *   The $element with prepared variables ready for theme('select').
+ */
+function form_pre_render_select($element) {
+  element_set_attributes($element, array('id', 'name', 'size'));
+  _form_set_attributes($element, array('form-select'));
+
+  return $element;
+}
+
+/**
  * Form element validation handler for #type 'url'.
  *
  * Note that #maxlength and #required is validated by _form_validate() already.
@@ -4499,7 +4503,9 @@ function form_pre_render_color($element) {
 }
 
 /**
- * Returns HTML for a form.
+ * Prepares variables for form templates.
+ *
+ * Default template: form.html.twig.
  *
  * @param $variables
  *   An associative array containing:
@@ -4508,48 +4514,37 @@ function form_pre_render_color($element) {
  *
  * @ingroup themeable
  */
-function theme_form($variables) {
+function template_preprocess_form(&$variables) {
   $element = $variables['element'];
   if (isset($element['#action'])) {
     $element['#attributes']['action'] = drupal_strip_dangerous_protocols($element['#action']);
   }
-  element_set_attributes($element, array('method', 'id'));
   if (empty($element['#attributes']['accept-charset'])) {
     $element['#attributes']['accept-charset'] = "UTF-8";
   }
-  // Anonymous DIV to satisfy XHTML compliance.
-  return '<form' . new Attribute($element['#attributes']) . '><div>' . $element['#children'] . '</div></form>';
+  $variables['attributes'] = new Attribute($element['#attributes']);
+  $variables['children'] = $element['#children'];
 }
 
 /**
- * Returns HTML for a textarea form element.
+ * Prepares variables for textarea templates.
+ *
+ * Default template: textarea.html.twig.
  *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
  *     Properties used: #title, #value, #description, #rows, #cols,
  *     #placeholder, #required, #attributes, #resizable
- *
- * @ingroup themeable
  */
-function theme_textarea($variables) {
+function template_preprocess_textarea(&$variables) {
   $element = $variables['element'];
-  element_set_attributes($element, array('id', 'name', 'rows', 'cols', 'placeholder'));
-  _form_set_attributes($element, array('form-textarea'));
-
-  $wrapper_attributes = array(
-    'class' => array('form-textarea-wrapper'),
-  );
-
-  // Add resizable behavior.
   if (!empty($element['#resizable'])) {
     $element['#attributes']['class'][] = 'resize-' . $element['#resizable'];
   }
 
-  $output = '<div' . new Attribute($wrapper_attributes) . '>';
-  $output .= '<textarea' . new Attribute($element['#attributes']) . '>' . check_plain($element['#value']) . '</textarea>';
-  $output .= '</div>';
-  return $output;
+  $variables['attributes'] = new Attribute($element['#attributes']);
+  $variables['value'] = check_plain($element['#value']);
 }
 
 /**
@@ -4599,6 +4594,22 @@ function form_process_weight($element) {
 }
 
 /**
+ * Prepares a #type 'form' render element for theme('form').
+ *
+ * @param array $element
+ *   An associative array containing the properties of the element.
+ *   Properties used: #id, #method.
+ *
+ * @return array
+ *   The $element with prepared variables ready for theme('form').
+ */
+function form_pre_render_form($element) {
+  element_set_attributes($element, array('method', 'id'));
+
+  return $element;
+}
+
+/**
  * Prepares a #type 'file' render element for theme_input().
  *
  * For assistance with handling the uploaded file correctly, see the API
@@ -4621,7 +4632,26 @@ function form_pre_render_file($element) {
 }
 
 /**
- * Returns HTML for a form element.
+ * Prepares a #type 'fieldset' render element for theme('fieldset').
+ *
+ * @param array $element
+ *   An associative array containing the properties of the element.
+ *   Properties used: #id.
+ *
+ * @return array
+ *   The $element with prepared variables ready for theme('fieldset').
+ */
+function form_pre_render_fieldset($element) {
+  element_set_attributes($element, array('id'));
+  _form_set_attributes($element, array('form-wrapper'));
+
+  return $element;
+}
+
+/**
+ * Prepares variables for form element templates.
+ *
+ * Default template: form-element.html.twig.
  *
  * Each form element is wrapped in a DIV container having the following CSS
  * classes:
@@ -4663,102 +4693,77 @@ function form_pre_render_file($element) {
  *   - element: An associative array containing the properties of the element.
  *     Properties used: #title, #title_display, #description, #id, #required,
  *     #children, #type, #name.
- *
- * @ingroup themeable
  */
-function theme_form_element($variables) {
-  $element = &$variables['element'];
+function template_preprocess_form_element(&$variables) {
+  $element = $variables['element'];
 
   // This function is invoked as theme wrapper, but the rendered form element
   // may not necessarily have been processed by form_builder().
   $element += array(
     '#title_display' => 'before',
   );
-
+  // If #title is not set, we don't display any label or required marker.
+  if (!isset($element['#title'])) {
+    $element['#title_display'] = 'none';
+  }
+  // We call it a label, though.
+  $variables['label_display'] = $element['#title_display'];
+  // Label returns empty tring in some cases.
+  $variables['label'] = theme('form_element_label', $variables);
   // Take over any #wrapper_attributes defined by the element.
   // @todo Temporary hack for #type 'item'.
   // @see http://drupal.org/node/1829202
-  if (isset($element['#wrapper_attributes'])) {
-    $attributes = $element['#wrapper_attributes'];
-  }
-  // Add element #id for #type 'item'.
-  if (isset($element['#markup']) && !empty($element['#id'])) {
-    $attributes['id'] = $element['#id'];
-  }
+  $variables['wrapper_attributes'] = new Attribute((isset($element['#wrapper_attributes'])) ? $element['#wrapper_attributes'] : array('class' => array()));
   // Add element's #type and #name as class to aid with JS/CSS selectors.
-  $attributes['class'][] = 'form-item';
+  $variables['wrapper_attributes']['class'][] = 'form-item';
   if (!empty($element['#type'])) {
-    $attributes['class'][] = 'form-type-' . strtr($element['#type'], '_', '-');
+    $variables['wrapper_attributes']['class'][] = 'form-type-' . strtr($element['#type'], '_', '-');
   }
   if (!empty($element['#name'])) {
-    $attributes['class'][] = 'form-item-' . strtr($element['#name'], array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
+    $variables['wrapper_attributes']['class'][] = 'form-item-' . strtr($element['#name'], array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
   }
   // Add a class for disabled elements to facilitate cross-browser styling.
   if (!empty($element['#attributes']['disabled'])) {
-    $attributes['class'][] = 'form-disabled';
+    $variables['wrapper_attributes']['class'][] = 'form-disabled';
   }
-  $output = '<div' . new Attribute($attributes) . '>' . "\n";
-
-  // If #title is not set, we don't display any label or required marker.
-  if (!isset($element['#title'])) {
-    $element['#title_display'] = 'none';
-  }
-  $prefix = isset($element['#field_prefix']) ? '<span class="field-prefix">' . $element['#field_prefix'] . '</span> ' : '';
-  $suffix = isset($element['#field_suffix']) ? ' <span class="field-suffix">' . $element['#field_suffix'] . '</span>' : '';
-
-  switch ($element['#title_display']) {
-    case 'before':
-    case 'invisible':
-      $output .= ' ' . theme('form_element_label', $variables);
-      $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
-      break;
-
-    case 'after':
-      $output .= ' ' . $prefix . $element['#children'] . $suffix;
-      $output .= ' ' . theme('form_element_label', $variables) . "\n";
-      break;
-
-    case 'none':
-    case 'attribute':
-      // Output no label and no required marker, only the children.
-      $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
-      break;
-  }
-
-  if (!empty($element['#description'])) {
-    $attributes = array('class' => 'description');
+  // Add element #id for #type 'item'.
+  if (isset($element['#markup']) && !empty($element['#id'])) {
+    $variables['wrapper_attributes']['id'] = $element['#id'];
+  }
+  $variables['prefix'] = isset($element['#field_prefix']) ? $element['#field_prefix'] : NULL;
+  $variables['suffix'] = isset($element['#field_suffix']) ? $element['#field_suffix'] : NULL;
+  $variables['children'] = isset($element['#children']) ? $element['#children'] : NULL;
+  $variables['description'] = !empty($element['#description']) ? $element['#description'] : NULL;
+  if ($variables['description']) {
+    $variables['description_attributes'] = new Attribute(array('class' => 'description'));
     if (!empty($element['#id'])) {
-      $attributes['id'] = $element['#id'] . '--description';
+      $variables['description_attributes']['id'] = $element['#id'] . '--description';
     }
-    $output .= '<div' . new Attribute($attributes) . '>' . $element['#description'] . "</div>\n";
   }
-
-  $output .= "</div>\n";
-
-  return $output;
 }
 
 /**
- * Returns HTML for a marker for required form elements.
+ * Prepares variables for form element required marker templates.
+ *
+ * Default template: form-element-required.html.twig.
  *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
- *
- * @ingroup themeable
  */
-function theme_form_required_marker($variables) {
+function template_preprocess_form_required_marker(&$variables) {
   // This is also used in the installer, pre-database setup.
   $t = get_t();
-  $attributes = array(
+  $variables['attributes'] = new Attribute(array(
     'class' => 'form-required',
     'title' => $t('This field is required.'),
-  );
-  return '<abbr' . new Attribute($attributes) . '>*</abbr>';
+  ));
 }
 
 /**
- * Returns HTML for a form element label and required marker.
+ * Prepares variables for form element label templates.
+ *
+ * Default template: form-label.html.twig.
  *
  * Form element labels include the #title and a #required marker. The label is
  * associated with the element itself by the element #id. Labels may appear
@@ -4777,39 +4782,40 @@ function theme_form_required_marker($variables) {
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
  *     Properties used: #required, #title, #id, #value, #description.
- *
- * @ingroup themeable
  */
-function theme_form_element_label($variables) {
+function template_preprocess_form_element_label(&$variables) {
   $element = $variables['element'];
   // This is also used in the installer, pre-database setup.
   $t = get_t();
 
-  // If title and required marker are both empty, output no label.
-  if ((!isset($element['#title']) || $element['#title'] === '') && empty($element['#required'])) {
-    return '';
-  }
-
-  // If the element is required, a required marker is appended to the label.
-  $required = !empty($element['#required']) ? theme('form_required_marker', array('element' => $element)) : '';
-
-  $title = filter_xss_admin($element['#title']);
-
-  $attributes = array();
-  // Style the label as class option to display inline with the element.
-  if ($element['#title_display'] == 'after') {
-    $attributes['class'] = 'option';
-  }
-  // Show label only to screen readers to avoid disruption in visual flows.
-  elseif ($element['#title_display'] == 'invisible') {
-    $attributes['class'] = 'element-invisible';
+  // If title and required marker are both empty, prepare no label.
+  if (empty($element['#required']) && (!isset($element['#title']) || $element['#title'] === '')) {
+    $variables['label'] = FALSE;
+    $variables['required'] = FALSE;
+    return;
   }
-
-  if (!empty($element['#id'])) {
-    $attributes['for'] = $element['#id'];
+  else {
+    // If the element is required, a required marker is appended to the label.
+    $variables['label'] = (isset($element['#title'])) ? filter_xss_admin($element['#title']) : NULL;
+    $variables['required'] = (!empty($element['#required'])) ? array('#theme' => 'form_required_marker', '#element' => $element) : '';
+    $variables['attributes'] = new Attribute(array('class' => array()));
+    // Associate the label with the field it is for.
+    if (!empty($element['#id'])) {
+      $variables['attributes']['for'] = $element['#id'];
+    }
+    // Add label positioning classes.
+    if (!empty($element['#title_display'])) {
+      // Style the label as class 'option' to display inline with the element.
+      // @todo: Use a more semantic class name like 'layout-inline-after'?
+      if ($element['#title_display'] == 'after') {
+        $variables['attributes']['class'][] = 'option';
+      }
+      // Show label only to screen readers to avoid disruption in visual flows.
+      elseif ($element['#title_display'] == 'invisible') {
+        $variables['attributes']['class'][] = 'element-invisible';
+      }
+    }
   }
-
-  return '<label' . new Attribute($attributes) . '>' . $t('!title!required', array('!title' => $title, '!required' => $required)) . '</label>';
 }
 
 /**
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index d2e461e..05c9f69 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -7,6 +7,7 @@
 
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 
@@ -374,6 +375,31 @@ function install_begin_request(&$install_state) {
       ))
       ->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)'));
 
+    // Register the Twig theme engine.
+    $container->register('twig.loader.filesystem', 'Twig_Loader_Filesystem')
+      ->addArgument(DRUPAL_ROOT);
+    $container->register('twig', 'Drupal\Core\Template\TwigEnvironment')
+      ->addArgument(new Reference('twig.loader.filesystem'))
+      ->addArgument(array(
+        // Twig templates are saved / loaded via drupal_php_storage().
+        // All files can be refreshed by clearing caches.
+        // @todo ensure garbage collection of expired files.
+        'cache' => TRUE,
+        'base_template_class' => 'Drupal\Core\Template\TwigTemplate',
+        // @todo Implement Twig autoescape.
+        // @see http://drupal.org/node/1712444.
+        'autoescape' => FALSE,
+        // @todo Decide on strict variables option.
+        // @see http://drupal.org/node/1806538.
+        'strict_variables' => FALSE,
+        'debug' => FALSE,
+        'auto_reload' => FALSE,
+      ))
+      ->addMethodCall('addExtension', array(new Definition('Drupal\Core\Template\TwigExtension')))
+      // @todo Figure out what to do about debugging functions.
+      // @see http://drupal.org/node/1804998
+      ->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug')));
+
     Drupal::setContainer($container);
   }
 
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 1ed2caa..2d18766 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -3271,51 +3271,58 @@ function drupal_common_theme() {
     // From form.inc.
     'input' => array(
       'render element' => 'element',
+      'template' => 'input',
     ),
     'select' => array(
       'render element' => 'element',
+      'template' => 'select',
     ),
     'fieldset' => array(
       'render element' => 'element',
+      'template' => 'fieldset',
     ),
     'details' => array(
       'render element' => 'element',
+      'template' => 'details',
     ),
     'radios' => array(
       'render element' => 'element',
-    ),
-    'date' => array(
-      'render element' => 'element',
+      'template' => 'radios',
     ),
     'exposed_filters' => array(
       'render element' => 'form',
     ),
     'checkboxes' => array(
       'render element' => 'element',
+      'template' => 'checkboxes',
     ),
     'form' => array(
       'render element' => 'element',
+      'template' => 'form',
     ),
     'textarea' => array(
       'render element' => 'element',
-    ),
-    'tableselect' => array(
-      'render element' => 'element',
+      'template' => 'textarea',
     ),
     'form_element' => array(
       'render element' => 'element',
+      'template' => 'form-element',
     ),
     'form_required_marker' => array(
       'render element' => 'element',
+      'template' => 'form-required-marker',
     ),
     'form_element_label' => array(
       'render element' => 'element',
+      'template' => 'form-element-label',
     ),
     'vertical_tabs' => array(
       'render element' => 'element',
+      'template' => 'vertical-tabs',
     ),
     'container' => array(
       'render element' => 'element',
+      'template' => 'container',
     ),
   );
 }
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 81b9715..7e87d29 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -231,6 +231,9 @@ function language_element_info_alter(&$type) {
     if (!isset($type['language_select']['#process'])) {
       $type['language_select']['#process'] = array();
     }
+    if (!isset($type['language_select']['#pre_render'])) {
+      $type['language_select']['#pre_render'] = array('form_pre_render_select');
+    }
     if (!isset($type['language_select']['#theme_wrappers'])) {
       $type['language_select']['#theme_wrappers'] = array();
     }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/FormTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/FormTest.php
index 07591f5..2a727fb 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Form/FormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/FormTest.php
@@ -94,7 +94,7 @@ function testRequiredFields() {
     $elements['file']['empty_values'] = $empty_strings;
 
     // Regular expression to find the expected marker on required elements.
-    $required_marker_preg = '@<label.*<abbr class="form-required" title="This field is required\.">\*</abbr></label>@';
+    $required_marker_preg = '@<label.*<abbr class="form-required" title="This field is required\.">\*</abbr>\s*?</label>@';
 
     // Go through all the elements and all the empty values for them.
     foreach ($elements as $type => $data) {
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 2c51ae0..d6d23a8 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -255,6 +255,7 @@ function system_element_info() {
   $types['form'] = array(
     '#method' => 'post',
     '#action' => request_uri(),
+    '#pre_render' => array('form_pre_render_form'),
     '#theme_wrappers' => array('form'),
   );
   $types['page'] = array(
@@ -299,7 +300,7 @@ function system_element_info() {
     '#limit_validation_errors' => FALSE,
     '#process' => array('form_process_button', 'ajax_process_form'),
     '#pre_render' => array('form_pre_render_button'),
-    '#theme_wrappers' => array('input__submit'),
+    '#theme' => 'input__submit',
   );
   $types['button'] = array(
     '#input' => TRUE,
@@ -309,7 +310,7 @@ function system_element_info() {
     '#limit_validation_errors' => FALSE,
     '#process' => array('form_process_button', 'ajax_process_form'),
     '#pre_render' => array('form_pre_render_button'),
-    '#theme_wrappers' => array('input__button'),
+    '#theme' => 'input__button',
   );
   $types['image_button'] = array(
     '#input' => TRUE,
@@ -321,7 +322,7 @@ function system_element_info() {
     '#has_garbage_value' => TRUE,
     '#src' => NULL,
     '#pre_render' => array('form_pre_render_image_button'),
-    '#theme_wrappers' => array('input__image_button'),
+    '#theme' => 'input__image_button',
   );
   $types['textfield'] = array(
     '#input' => TRUE,
@@ -436,6 +437,7 @@ function system_element_info() {
     '#cols' => 60,
     '#rows' => 5,
     '#resizable' => 'vertical',
+    '#pre_render' => array('form_pre_render_textarea'),
     '#process' => array('ajax_process_form'),
     '#theme' => 'textarea',
     '#theme_wrappers' => array('form_element'),
@@ -473,6 +475,7 @@ function system_element_info() {
   $types['select'] = array(
     '#input' => TRUE,
     '#multiple' => FALSE,
+    '#pre_render' => array('form_pre_render_select'),
     '#process' => array('form_process_select', 'ajax_process_form'),
     '#theme' => 'select',
     '#theme_wrappers' => array('form_element'),
@@ -490,7 +493,8 @@ function system_element_info() {
   );
   $types['date'] = array(
     '#input' => TRUE,
-    '#theme' => 'date',
+    '#theme' => 'input__date',
+    '#pre_render' => array('form_pre_render_date'),
     '#theme_wrappers' => array('form_element'),
   );
   $types['file'] = array(
@@ -504,10 +508,11 @@ function system_element_info() {
     '#input' => TRUE,
     '#js_select' => TRUE,
     '#multiple' => TRUE,
+    '#pre_render' => array('form_pre_render_tableselect'),
     '#process' => array('form_process_tableselect'),
     '#options' => array(),
     '#empty' => '',
-    '#theme' => 'tableselect',
+    '#theme' => 'table__tableselect',
   );
 
   // Form structure.
diff --git a/core/modules/system/templates/checkboxes.html.twig b/core/modules/system/templates/checkboxes.html.twig
new file mode 100644
index 0000000..689b7a1
--- /dev/null
+++ b/core/modules/system/templates/checkboxes.html.twig
@@ -0,0 +1,18 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a 'checkboxes' #type form element.
+ *
+ * Available variables
+ * - attributes: HTML attributes for the checkboxes wrapper element.
+ * - children: HTML markup for the child checkboxes.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_checkboxes()
+ *
+ * @ingroup themeable
+ */
+ @todo: remove this file once http://drupal.org/node/1819284 is resolved.
+ This is identical to core/themes/stark/templates/form.inc/container.html.twig
+#}
+<div class="{{ attributes.class }}"{{ attributes }}>{{ children }}</div>
diff --git a/core/modules/system/templates/container.html.twig b/core/modules/system/templates/container.html.twig
new file mode 100644
index 0000000..9d4446e
--- /dev/null
+++ b/core/modules/system/templates/container.html.twig
@@ -0,0 +1,16 @@
+{#
+/**
+ * @file
+ * Default theme implementation of a container used to wrap child elements.
+ *
+ * Available variables:
+ * - attributes: Remaining html attributes for the containing element.
+ * - children: The rendered child elements of the container.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_container()
+ *
+ * @ingroup themeable
+ */
+#}
+<div{{ attributes }}>{{ children }}</div>
diff --git a/core/modules/system/templates/datetime.html.twig b/core/modules/system/templates/datetime.html.twig
index 5ea386e..f811f56 100644
--- a/core/modules/system/templates/datetime.html.twig
+++ b/core/modules/system/templates/datetime.html.twig
@@ -1,6 +1,7 @@
 {#
 /**
- * Returns HTML for a date / time.
+ * @file
+ * Default theme implementation for a date / time element.
  *
  * Available variables
  * - timestamp: (optional) A UNIX timestamp for the datetime attribute. If the
@@ -25,4 +26,4 @@
  */
 #}
 {# @todo Revisit once http://drupal.org/node/1825952 is resolved. #}
-<time class="{{ attributes.class }}" {{ attributes }}>{{ html ? text|raw : text|escape }}</time>
+<time class="{{ attributes.class }}"{{ attributes }}>{{ html ? text|raw : text|escape }}</time>
diff --git a/core/modules/system/templates/details.html.twig b/core/modules/system/templates/details.html.twig
new file mode 100644
index 0000000..2aa10b8
--- /dev/null
+++ b/core/modules/system/templates/details.html.twig
@@ -0,0 +1,34 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a details element.
+ *
+ * Available variables
+ *   - attributes: An array of HTML attributes for the details element.
+ *   - title: The title of the element, or NULL if not set.
+ *   - description: The description of the element, or NULL if not set.
+ *   - children: The children of the element, or NULL if not set.
+ *   - value: The value of the element, or NULL if not set.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_details()
+ *
+ * @ingroup themeable
+ */
+#}
+<details{{ attributes }}>
+  {% if title %}
+    <summary{{ summary_attributes }}>{{ title }}</summary>
+  {% endif %}
+  <div class="details-wrapper">
+    {% if description %}
+      <div class="details-description">{{ description }}</div>
+    {% endif %}
+    {% if children %}
+      {{ children }}
+    {% endif %}
+    {% if value %}
+      {{ value }}
+    {% endif %}
+  </div>
+</details>
diff --git a/core/modules/system/templates/fieldset.html.twig b/core/modules/system/templates/fieldset.html.twig
new file mode 100644
index 0000000..0a3f895
--- /dev/null
+++ b/core/modules/system/templates/fieldset.html.twig
@@ -0,0 +1,36 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a fieldset element and its children.
+ *
+ * Available variables:
+ * - attributes: An array of HTML attributes for the fieldset element.
+ * - title: Title of the fieldset, intended for use as the text of the legend.
+ * - title_attributes: An array of HTML attributes to apply to the legend.
+ * - description: The description of the fieldset.
+ * - description_attributes: An array of HTML attributes to apply to the
+ *    description container.
+ * - children: The rendered child elements of the fieldset.
+ * - value: The value of the fieldset.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_fieldset()
+ *
+ * @ingroup themeable
+ */
+#}
+<fieldset{{ attributes }}>
+  {% if title is defined %}
+    {# Always wrap fieldset legends in a SPAN for CSS positioning. #}
+    <legend{{ title_attributes }}><span class="fieldset-legend">{{ title }}</span></legend>
+  {% endif %}
+  <div class="fieldset-wrapper">
+    {% if description is defined %}
+      <div{{ description_attributes }}>{{ description }}</div>
+    {% endif %}
+    {{ children }}
+    {% if value %}
+      {{ value }}
+    {% endif %}
+  </div>
+</fieldset>
diff --git a/core/modules/system/templates/form-element-label.html.twig b/core/modules/system/templates/form-element-label.html.twig
new file mode 100644
index 0000000..2870872
--- /dev/null
+++ b/core/modules/system/templates/form-element-label.html.twig
@@ -0,0 +1,29 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a form element label.
+ *
+ * Available variables:
+ * - label: The text of the label, or FALSE if there is no title and the element
+ *    is not required.
+ * - required: A rendered marker indicating the field is required, or
+ *    an empty string if the field is not required.
+ * - attributes: An array of HTML attributes to apply to the label.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_form_label()
+ * @see form-required-marker.html.twig
+ *
+ * @ingroup themeable
+ */
+#}
+{% if (label is not empty) or (required is not empty) %}
+  <label{{ attributes }}>
+    {%- if label is not empty -%}
+      {{ label|t }}
+    {%- endif -%}
+    {%- if required is not empty -%}
+      {{ required|t }}
+    {%- endif -%}
+  </label>
+{% endif %}
diff --git a/core/modules/system/templates/form-element.html.twig b/core/modules/system/templates/form-element.html.twig
new file mode 100644
index 0000000..bb07a5e
--- /dev/null
+++ b/core/modules/system/templates/form-element.html.twig
@@ -0,0 +1,58 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a form element.
+ *
+ * Available variables:
+ * - wrapper_attributes: An array of HTML attributes to apply to the wrapper.
+ * - prefix: The form element prefix, or NULL.
+ * - suffix: The form element suffix, or NULL.
+ * - label: The rendered label. @see form-element-label.html.twig.
+ * - label_display: Label display setting. It can have these values:
+ *   - before: The label is output before the element. This is the default. The
+ *      label includes the #title and the required marker, if #required.
+ *   - after: The label is output after the element. For example, this is used
+ *      for radio and checkbox #type elements as set in system_element_info().
+ *      If the #title is empty but the field is #required, the label will
+ *      contain only the required marker.
+ *   - invisible: Labels are critical for screen readers to enable them to
+ *      properly navigate through forms but can be visually distracting. This
+ *      property hides the label for everyone except screen readers.
+ *   - attribute: Set the title attribute on the element to create a tooltip
+ *      but output no label element. This is supported only for checkboxes and
+ *      radios in form_pre_render_conditional_form_element(). It is used where
+ *      a visual label is not needed, such as a table of checkboxes where the
+ *      row and column provide the context. The tooltip will include the title
+ *      and required marker.
+ * - description: A description of the form element, or NULL if not set.
+ * - description_attributes: An array of HTML attributes to apply to the wrapper
+ *    of the description.  Will only be set when description is not NULL.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_form_element()
+ *
+ * @ingroup themeable
+ */
+#}
+<div{{ wrapper_attributes }}>
+  {% if (label is not empty) and (label_display in ['before', 'invisible']) %}
+    {{ label }}
+  {% endif %}
+  {% if prefix is not empty %}
+    <span class="field-prefix">{{ prefix }}</span>
+  {% endif %}
+  {% if children is not empty %}
+    {{ children }}
+  {% endif %}
+  {% if suffix is not empty %}
+    <span class="field-suffix">{{ suffix }}</span>
+  {% endif %}
+  {% if (label is not empty) and (label_display == 'after') %}
+    {{ label }}
+  {% endif %}
+  {% if description is not empty %}
+    <div{{ description_attributes }}>
+      {{ description }}
+    </div>
+  {% endif %}
+</div>
diff --git a/core/modules/system/templates/form-required-marker.html.twig b/core/modules/system/templates/form-required-marker.html.twig
new file mode 100644
index 0000000..2c26446
--- /dev/null
+++ b/core/modules/system/templates/form-required-marker.html.twig
@@ -0,0 +1,15 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a form element required marker.
+ *
+ * Available variables:
+ * - attributes: An array of HTML attributes for the label.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_form_required_marker()
+ *
+ * @ingroup themeable
+ */
+#}
+<abbr class="{{ attributes.class }}"{{ attributes }}>*</abbr>
diff --git a/core/modules/system/templates/form.html.twig b/core/modules/system/templates/form.html.twig
new file mode 100644
index 0000000..71fb632
--- /dev/null
+++ b/core/modules/system/templates/form.html.twig
@@ -0,0 +1,19 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a form.
+ *
+ * Available variables:
+ * - attributes: An array of HTML attributes for the form element.
+ * - children: Rendered child form elements.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_form()
+ *
+ * @ingroup themeable
+ */
+ @todo: remove the inner div once http://drupal.org/node/1822210 is resolved.
+#}
+<form{{ attributes }}>
+  <div>{{ children }}</div>
+</form>
diff --git a/core/modules/system/templates/input.html.twig b/core/modules/system/templates/input.html.twig
new file mode 100644
index 0000000..7e3b5a8
--- /dev/null
+++ b/core/modules/system/templates/input.html.twig
@@ -0,0 +1,34 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an input element.
+ *
+ * This covers input types:
+ * - button
+ * - checkbox
+ * - date
+ * - email
+ * - file
+ * - hidden
+ * - image_button
+ * - number
+ * - radio
+ * - range
+ * - password
+ * - tel
+ * - textfield
+ *
+ * Available variables:
+ * - attributes: An array of HTML attributes for the input element.
+ * - children: An array of child elements.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_input()
+ *
+ * @ingroup themeable
+ */
+#}
+<input class="{{ attributes.class }}"{{ attributes }}/>
+{% if children is not empty %}
+  {{ children }}
+{% endif %}
diff --git a/core/modules/system/templates/radios.html.twig b/core/modules/system/templates/radios.html.twig
new file mode 100644
index 0000000..4e44796
--- /dev/null
+++ b/core/modules/system/templates/radios.html.twig
@@ -0,0 +1,18 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a #type 'radios' form element.
+ *
+ * Available variables:
+ * - attributes: An array of HTML attributes for the container element.
+ * - children: An array of rendered child radio elements.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_radios()
+ *
+ * @ingroup themeable
+ */
+ @todo: remove this file once http://drupal.org/node/1819284 is resolved.
+ This is identical to core/themes/stark/templates/form.inc/container.html.twig
+#}
+<div class="{{ attributes.class }}"{{ attributes }}>{{ children }}</div>
diff --git a/core/modules/system/templates/select.html.twig b/core/modules/system/templates/select.html.twig
new file mode 100644
index 0000000..e8c6920
--- /dev/null
+++ b/core/modules/system/templates/select.html.twig
@@ -0,0 +1,16 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a select element.
+ *
+ * Available variables:
+ * - attributes: An array of HTML attributes for the select element.
+ * - options: The rendered list of select options.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_select()
+ *
+ * @ingroup themeable
+ */
+#}
+<select class="{{ attributes.class }}"{{ attributes }}>{{ options }}</select>
diff --git a/core/modules/system/templates/textarea.html.twig b/core/modules/system/templates/textarea.html.twig
new file mode 100644
index 0000000..98fdce7
--- /dev/null
+++ b/core/modules/system/templates/textarea.html.twig
@@ -0,0 +1,16 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a textarea element.
+ *
+ * Available variables:
+ * - attributes: An array of HTML attributes for the textarea element.
+ * - value: Plain text value of the textarea.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_textarea()
+ *
+ * @ingroup themeable
+ */
+#}
+<textarea class="{{ attributes.class }}"{{ attributes }}>{{ value }}</textarea>
diff --git a/core/modules/system/templates/vertical-tabs.html.twig b/core/modules/system/templates/vertical-tabs.html.twig
new file mode 100644
index 0000000..206081b
--- /dev/null
+++ b/core/modules/system/templates/vertical-tabs.html.twig
@@ -0,0 +1,15 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a set of vertical tabs.
+ *
+ * Available variables
+ * - children: The rendered child fieldsets elements.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_vertical_tabs()
+ *
+ * @ingroup themeable
+ */
+#}
+<div class="vertical-tabs-panes">{{ children }}</div>
