diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 8bdfdc2..bab586b 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1230,6 +1230,89 @@ function hook_template_preprocess_default_variables_alter(&$variables) {
 }
 
 /**
+ * Declare a template file extension to be used with a theme engine
+ *
+ * This hook is used in a theme engine implementation in the format of
+ * ENGINE_extension()
+ *
+ * @return string
+ *  The file extension the theme engine will recognize
+ */
+function hook_extension() {
+  // Extension for template base names in Twig
+  return '.html.twig';
+}
+
+/**
+ * Renders a template using the theme engine.
+ *
+ * This hook is used in a theme engine implementation in the format of
+ * ENGINE_render_template()
+ * Here the theme engine takes care of rendering the contents of a template with the
+ * provided variables.
+ *
+ * @param $template_file
+ *   The file name of the template to render.
+ * @param $variables
+ *   A keyed array of variables that will appear in the output.
+ *
+ * @return string
+ *   The output generated by the template. In most cases this will be a string
+ *   containing HTML markup
+ */
+function hook_render_template($template_file, $variables) {
+  $twig_service = \Drupal::service('twig');
+  $output = array(
+    'debug_prefix'    => '',
+    'debug_info'      => '',
+    'rendered_markup' => $twig_service->loadTemplate($template_file)->render($variables),
+    'debug_suffix'    => '',
+  );
+  if ($twig_service->isDebug()) {
+    $output['debug_prefix'] .= "\n\n<!-- THEME DEBUG -->";
+    $output['debug_prefix'] .= "\n<!-- CALL: _theme('{$variables['theme_hook_original']}') -->";
+    // If there are theme suggestions, reverse the array so more specific
+    // suggestions are shown first.
+    if (!empty($variables['theme_hook_suggestions'])) {
+      $variables['theme_hook_suggestions'] = array_reverse($variables['theme_hook_suggestions']);
+    }
+    // Add debug output for directly called suggestions like
+    // '#theme' => 'comment__node__article'.
+    if (strpos($variables['theme_hook_original'], '__') !== FALSE) {
+      $derived_suggestions[] = $hook = $variables['theme_hook_original'];
+      while ($pos = strrpos($hook, '__')) {
+        $hook = substr($hook, 0, $pos);
+        $derived_suggestions[] = $hook;
+      }
+      // Get the value of the base hook (last derived suggestion) and append it
+      // to the end of all theme suggestions.
+      $base_hook = array_pop($derived_suggestions);
+      $variables['theme_hook_suggestions'] = array_merge($derived_suggestions, $variables['theme_hook_suggestions']);
+      $variables['theme_hook_suggestions'][] = $base_hook;
+    }
+    if (!empty($variables['theme_hook_suggestions'])) {
+      $extension = twig_extension();
+      $current_template = basename($template_file);
+      $suggestions = $variables['theme_hook_suggestions'];
+      // Only add the original theme hook if it wasn't a directly called
+      // suggestion.
+      if (strpos($variables['theme_hook_original'], '__') === FALSE) {
+        $suggestions[] = $variables['theme_hook_original'];
+      }
+      foreach ($suggestions as &$suggestion) {
+        $template = strtr($suggestion, '_', '-') . $extension;
+        $prefix = ($template == $current_template) ? 'x' : '*';
+        $suggestion = $prefix . ' ' . $template;
+      }
+      $output['debug_info'] .= "\n<!-- FILE NAME SUGGESTIONS:\n   " . implode("\n   ", $suggestions) . "\n-->";
+    }
+    $output['debug_info']   .= "\n<!-- BEGIN OUTPUT from '{$template_file}' -->\n";
+    $output['debug_suffix'] .= "\n<!-- END OUTPUT from '{$template_file}' -->\n\n";
+  }
+  return implode('', $output);
+}
+
+/**
  * Log an event message.
  *
  * This hook allows modules to route log events to custom destinations, such as
diff --git a/core/themes/engines/phptemplate/phptemplate.engine b/core/themes/engines/phptemplate/phptemplate.engine
index 0521092..a4eee49 100644
--- a/core/themes/engines/phptemplate/phptemplate.engine
+++ b/core/themes/engines/phptemplate/phptemplate.engine
@@ -31,6 +31,8 @@ function phptemplate_extension() {
 }
 
 /**
+ * Implements hook_render_template().
+ *
  * Renders a system default template, which is essentially a PHP template.
  *
  * @param $template_file
diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine
index d596715..3816343 100644
--- a/core/themes/engines/twig/twig.engine
+++ b/core/themes/engines/twig/twig.engine
@@ -18,6 +18,9 @@ function twig_theme($existing, $type, $theme, $path) {
 
 /**
  * Implements hook_extension().
+ *
+ * @return string
+ *  The file extension the Twig theme engine will recognize
  */
 function twig_extension() {
   return '.html.twig';
@@ -31,6 +34,8 @@ function twig_init(Extension $theme) {
 }
 
 /**
+ * Implements hook_render_template().
+ *
  * Renders a Twig template.
  *
  * If the Twig debug setting is enabled, HTML comments including _theme() call
@@ -41,7 +46,7 @@ function twig_init(Extension $theme) {
  * @param $variables
  *   A keyed array of variables that will appear in the output.
  *
- * @return
+ * @return string
  *   The output generated by the template, plus any debug information.
  */
 function twig_render_template($template_file, $variables) {
