diff --git a/core/includes/common.inc b/core/includes/common.inc
index 1980f2f..fbfc99a 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -413,7 +413,9 @@ function drupal_add_feed($url = NULL, $title = '') {
  */
 function drupal_get_feeds($delimiter = "\n") {
   $feeds = drupal_add_feed();
-  return implode($feeds, $delimiter);
+  $string = implode($feeds, $delimiter);
+  $GLOBALS['safe_strings'][$string] = TRUE;
+  return $string;
 }
 
 /**
@@ -1366,7 +1368,9 @@ function l($text, $path, array $options = array()) {
   // Sanitize the link text if necessary.
   $text = $variables['options']['html'] ? $variables['text'] : check_plain($variables['text']);
 
-  return '<a href="' . $url . '"' . $attributes . '>' . $text . '</a>';
+  $string = ('<a href="' . $url . '"' . $attributes . '>' . $text . '</a>');
+  $GLOBALS['safe_strings'][$string] = TRUE;
+  return $string;
 }
 
 /**
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index da3df24..4819ae9 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1122,7 +1122,8 @@ function theme($hook, $variables = array()) {
 
   // restore path_to_theme()
   $theme_path = $temp;
-  return $output;
+  $GLOBALS['safe_strings'][$output] = TRUE;
+  return ($output);
 }
 
 /**
diff --git a/core/lib/Drupal/Component/Utility/String.php b/core/lib/Drupal/Component/Utility/String.php
index 3cd6472..182518c 100644
--- a/core/lib/Drupal/Component/Utility/String.php
+++ b/core/lib/Drupal/Component/Utility/String.php
@@ -29,7 +29,9 @@ class String {
    * @ingroup sanitization
    */
   public static function checkPlain($text) {
-    return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
+    $string = (htmlspecialchars($text, ENT_QUOTES, 'UTF-8'));
+    $GLOBALS['safe_strings'][$string] = TRUE;
+    return $string;
   }
 
   /**
@@ -105,7 +107,9 @@ public static function format($string, array $args = array()) {
           // Pass-through.
       }
     }
-    return strtr($string, $args);
+    $output = strtr($string, $args);
+    $GLOBALS['safe_strings'][$output] = TRUE;
+    return $output;
   }
 
   /**
diff --git a/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php
index 8d0d257..3600825 100644
--- a/core/lib/Drupal/Component/Utility/Xss.php
+++ b/core/lib/Drupal/Component/Utility/Xss.php
@@ -71,7 +71,7 @@ public static function filter($string, $allowed_tags = array('a', 'em', 'strong'
     // Named entities.
     $string = preg_replace('/&amp;([A-Za-z][A-Za-z0-9]*;)/', '&\1', $string);
 
-    return preg_replace_callback('%
+    $output = preg_replace_callback('%
       (
       <(?=[^a-zA-Z!/])  # a lone <
       |                 # or
@@ -81,6 +81,8 @@ public static function filter($string, $allowed_tags = array('a', 'em', 'strong'
       |                 # or
       >                 # just a >
       )%x', '\Drupal\Component\Utility\Xss::split', $string);
+    $GLOBALS['safe_strings'][$output] = TRUE;
+    return $output;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index a6cb957..36c7deb 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -118,9 +118,7 @@ public static function registerTwig(ContainerBuilder $container) {
         // files folder is writable.
         'cache' => drupal_installation_attempted() ? FALSE : settings()->get('twig_cache', TRUE),
         'base_template_class' => 'Drupal\Core\Template\TwigTemplate',
-        // @todo Remove in followup issue
-        // @see http://drupal.org/node/1712444.
-        'autoescape' => FALSE,
+        'autoescape' => TRUE,
         // @todo Remove in followup issue
         // @see http://drupal.org/node/1806538.
         'strict_variables' => FALSE,
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
index 130ee9d..6826359 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
@@ -137,6 +137,7 @@ public function translate($string, array $args = array(), array $options = array
     $string = $translation === FALSE ? $string : $translation;
 
     if (empty($args)) {
+      // @todo: Deliberately not marked as safe. Or should it be?
       return $string;
     }
     else {
diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php
index 9cd17b0..c8aff5b 100644
--- a/core/lib/Drupal/Core/Template/TwigExtension.php
+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -40,6 +40,8 @@ public function getFilters() {
       // @see TwigNodeTrans::compileString()
       'passthrough' => new \Twig_Filter_Function('twig_raw_filter'),
       'placeholder' => new \Twig_Filter_Function('twig_raw_filter'),
+      // Helper filter used to replace twig's original raw() filter.
+      'twig_raw' => new \Twig_Filter_Function('twig_raw'),
     );
   }
 
diff --git a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
index 710faa0..e14a311 100644
--- a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
+++ b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
@@ -58,6 +58,8 @@ function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) {
    * We use this to inject a call to render_var -> twig_render_var()
    * before anything is printed.
    *
+   * We also change the 'raw' filter to our own 'twig_raw' filter.
+   *
    * @see twig_render
    */
   function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) {
@@ -70,6 +72,10 @@ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) {
         $node->getLine()
       );
     }
+    else if ($node instanceof \Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) {
+      // Use our own twig_raw filter that returns Twig_Markup
+      $node->getNode('filter')->setAttribute('value', 'twig_raw');
+    }
 
     if ($this->isReference) {
       if ($node instanceof \Twig_Node_Expression_Name) {
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 1a0d9d1..4ca3a13 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -711,7 +711,10 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE,
   if ($cache) {
     $cache_id = $format->format . ':' . $langcode . ':' . hash('sha256', $text);
     if ($cached = cache('filter')->get($cache_id)) {
-      return $cached->data;
+      // @todo: The caller is responsible that this is really safe.
+      $output = $cached->data;
+      $GLOBALS['safe_strings'][$output] = TRUE;
+      return $output;
     }
   }
 
@@ -752,6 +755,8 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE,
     cache('filter')->set($cache_id, $text, CacheBackendInterface::CACHE_PERMANENT, array('filter_format' => $format->format));
   }
 
+  // @todo: The caller is responsible that this is really safe.
+  $GLOBALS['safe_strings'][$text] = TRUE;
   return $text;
 }
 
diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine
index b541cdc..9891cd2 100644
--- a/core/themes/engines/twig/twig.engine
+++ b/core/themes/engines/twig/twig.engine
@@ -110,12 +110,20 @@ function twig_render_var($arg) {
     return NULL;
   }
 
-  // Keep Twig_Markup objects intact to prepare for later autoescaping support
+  // Keep Twig_Markup objects intact to support autoescaping.
   if ($arg instanceOf Twig_Markup) {
     return $arg;
   }
 
+  // For known objects with __toString() methods, return a Twig_Markup instance.
+  if ($arg instanceof \Drupal\Core\Template\RenderWrapper || $arg instanceof \Drupal\Core\Template\Attribute) {
+    return new Twig_Markup((string) $arg, 'UTF-8');
+  }
+
   if (is_scalar($arg)) {
+    if (isset($GLOBALS['safe_strings'][$arg])) {
+      return new Twig_Markup($arg, 'UTF-8');
+    }
     return $arg;
   }
 
@@ -127,7 +135,7 @@ function twig_render_var($arg) {
   }
 
   // This is a normal render array.
-  return render($arg);
+  return new Twig_Markup(render($arg), 'UTF-8');
 }
 
 /**
@@ -155,3 +163,20 @@ function twig_show($element) {
   }
   // @todo Add warning in else case
 }
+
+/**
+ * Replacement function for twig's raw filter
+ *
+ * This needs to be used, because the default raw
+ * filter gets optimized out.
+ *
+ * As we wrap everything that is printed in twig_render()
+ * we need to return Twig_Markup instead.
+ * This allows to hold the information that a value was
+ * marked 'raw' by the template author.
+ *
+ * @see TwigNodeVisitor
+ */
+function twig_raw($string) {
+  return new Twig_Markup($string, 'UTF-8');
+}
diff --git a/core/vendor/twig/twig/lib/Twig/Extension/Core.php b/core/vendor/twig/twig/lib/Twig/Extension/Core.php
index 26e7017..898eff4 100644
--- a/core/vendor/twig/twig/lib/Twig/Extension/Core.php
+++ b/core/vendor/twig/twig/lib/Twig/Extension/Core.php
@@ -847,6 +847,8 @@ function twig_in_filter($value, $compare)
  */
 function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
 {
+    // @todo Create upstream pull request to remove unneeded is_object() call
+    //   for speed. Would be nice to profile this as well.
     if ($autoescape && is_object($string) && $string instanceof Twig_Markup) {
         return $string;
     }
