diff --git a/composer.json b/composer.json
index 7ce3db6abc410f2856951fcf42bbeba761d6c768..d6cdc7fea22db5f4c2d2121c277196a27ee8c782 100644
--- a/composer.json
+++ b/composer.json
@@ -13,7 +13,7 @@
     "symfony/http-foundation": "2.4.*",
     "symfony/http-kernel": "2.4.*",
     "symfony/routing": "2.4.*",
-    "symfony/serializer": "2.4.*",
+    "symfony/serializer": "2.5.*",
     "symfony/validator": "2.4.*",
     "symfony/yaml": "dev-master#e49a47d60348665261f6e279ba383241deb73cab",
     "twig/twig": "1.15.*",
diff --git a/composer.lock b/composer.lock
index fdc46fe565b4488113776c1ec05bc6c1464e662c..e1f9771ee0bfe99fe4da622932aaea84ac032e6e 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "e1a7eeed7d09f5c76f642f07b7a0a579",
+    "hash": "2b2309c748ec92230880579aaedfa1e6",
     "packages": [
         {
             "name": "doctrine/annotations",
@@ -2027,17 +2027,17 @@
         },
         {
             "name": "symfony/serializer",
-            "version": "v2.4.1",
+            "version": "v2.5.2",
             "target-dir": "Symfony/Component/Serializer",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Serializer.git",
-                "reference": "60c54346958604379392672a3a998650a169a7f4"
+                "reference": "33185b290310ab1fd8283fb8ed2a434cdb88b9b9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Serializer/zipball/60c54346958604379392672a3a998650a169a7f4",
-                "reference": "60c54346958604379392672a3a998650a169a7f4",
+                "url": "https://api.github.com/repos/symfony/Serializer/zipball/33185b290310ab1fd8283fb8ed2a434cdb88b9b9",
+                "reference": "33185b290310ab1fd8283fb8ed2a434cdb88b9b9",
                 "shasum": ""
             },
             "require": {
@@ -2046,7 +2046,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.4-dev"
+                    "dev-master": "2.5-dev"
                 }
             },
             "autoload": {
@@ -2061,7 +2061,9 @@
             "authors": [
                 {
                     "name": "Fabien Potencier",
-                    "email": "fabien@symfony.com"
+                    "email": "fabien@symfony.com",
+                    "homepage": "http://fabien.potencier.org",
+                    "role": "Lead Developer"
                 },
                 {
                     "name": "Symfony Community",
@@ -2070,7 +2072,7 @@
             ],
             "description": "Symfony Serializer Component",
             "homepage": "http://symfony.com",
-            "time": "2014-01-01 08:14:50"
+            "time": "2014-07-09 09:05:48"
         },
         {
             "name": "symfony/translation",
@@ -2423,12 +2425,8 @@
             "time": "2013-06-12 19:46:58"
         }
     ],
-    "packages-dev": [
-
-    ],
-    "aliases": [
-
-    ],
+    "packages-dev": [],
+    "aliases": [],
     "minimum-stability": "stable",
     "stability-flags": {
         "symfony/yaml": 20,
@@ -2438,10 +2436,9 @@
         "symfony-cmf/routing": 15,
         "phpunit/phpunit-mock-objects": 20
     },
+    "prefer-stable": false,
     "platform": {
         "php": ">=5.4.2"
     },
-    "platform-dev": [
-
-    ]
+    "platform-dev": []
 }
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 248c7954eeb7919212b457c21be329e2ddbb5459..89cdc53243d87d514e0d121414c24aabef4eb9ba 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1696,6 +1696,25 @@ function template_preprocess_table(&$variables) {
   }
 }
 
+/**
+ * Prepares variables for tablesort indicator templates.
+ *
+ * Default template: tablesort-indicator.html.twig.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - style: Set to either 'asc' or 'desc'. This determines which icon to show.
+ */
+function template_preprocess_tablesort_indicator(&$variables) {
+  // Provide the image attributes for an ascending or descending image.
+  if ($variables['style'] == 'asc') {
+    $variables['arrow_asc'] = file_create_url('core/misc/arrow-asc.png');
+  }
+  else {
+    $variables['arrow_desc'] = file_create_url('core/misc/arrow-desc.png');
+  }
+}
+
 /**
  * Prepares variables for item list templates.
  *
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 42c7deaeb6c66a339356ba51f1f46eb20b2f8042..34ad2589207bb5d874c31216c386c2cd97324a9a 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -84,6 +84,9 @@ public static function registerTwig(ContainerBuilder $container) {
       ->addArgument(DRUPAL_ROOT);
     $container->setAlias('twig.loader', 'twig.loader.filesystem');
 
+     $twig_extension = new Definition('Drupal\Core\Template\TwigExtension');
+     $twig_extension->addMethodCall('setGenerators', array(new Reference('url_generator')));
+
     $container->register('twig', 'Drupal\Core\Template\TwigEnvironment')
       ->addArgument(new Reference('twig.loader'))
       ->addArgument(array(
@@ -99,7 +102,7 @@ public static function registerTwig(ContainerBuilder $container) {
       ))
       ->addArgument(new Reference('module_handler'))
       ->addArgument(new Reference('theme_handler'))
-      ->addMethodCall('addExtension', array(new Definition('Drupal\Core\Template\TwigExtension')))
+      ->addMethodCall('addExtension', array($twig_extension))
       // @todo Figure out what to do about debugging functions.
       // @see http://drupal.org/node/1804998
       ->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug')))
diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php
index 69e0bb30465b0b97d718d0dfcbd22314c36ac4e4..05c739035cbcf1f83e383c24b710b4000ae7541b 100644
--- a/core/lib/Drupal/Core/Template/TwigExtension.php
+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -12,6 +12,8 @@
 
 namespace Drupal\Core\Template;
 
+use Drupal\Core\Routing\UrlGeneratorInterface;
+
 /**
  * A class providing Drupal Twig extensions.
  *
@@ -21,14 +23,36 @@
  */
 class TwigExtension extends \Twig_Extension {
 
+  /**
+   * The URL generator.
+   *
+   * @var \Drupal\Core\Routing\UrlGeneratorInterface
+   */
+  protected $urlGenerator;
+
+  /**
+   * Constructs \Drupal\Core\Template\TwigExtension.
+   *
+   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
+   *   The URL generator.
+   */
+  public function setGenerators(UrlGeneratorInterface $url_generator) {
+    $this->urlGenerator = $url_generator;
+    return $this;
+  }
+
   /**
    * {@inheritdoc}
    */
   public function getFunctions() {
     return array(
-      new \Twig_SimpleFunction('url', 'url'),
       // This function will receive a renderable array, if an array is detected.
       new \Twig_SimpleFunction('render_var', 'twig_render_var'),
+      // The url and path function are defined in close parallel to those found
+      // in \Symfony\Bridge\Twig\Extension\RoutingExtension
+      new \Twig_SimpleFunction('url', array($this, 'getUrl'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
+      new \Twig_SimpleFunction('path', array($this, 'getPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
+      new \Twig_SimpleFunction('url_from_path', array($this, 'getUrlFromPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
     );
   }
 
@@ -88,4 +112,101 @@ public function getName() {
     return 'drupal_core';
   }
 
+  /**
+   * Generates a URL path given a route name and parameters.
+   *
+   * @param $name
+   *   The name of the route.
+   * @param array $parameters
+   *   An associative array of route parameters names and values.
+   * @param array $options
+   *   (optional) An associative array of additional options. The 'absolute'
+   *   option is forced to be FALSE.
+   *   @see \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute().
+   *
+   * @return string
+   *   The generated URL path (relative URL) for the given route.
+   */
+  public function getPath($name, $parameters = array(), $options = array()) {
+    $options['absolute'] = FALSE;
+    return $this->urlGenerator->generateFromRoute($name, $parameters, $options);
+  }
+
+  /**
+   * Generates an absolute URL given a route name and parameters.
+   *
+   * @param $name
+   *   The name of the route.
+   * @param array $parameters
+   *   An associative array of route parameter names and values.
+   * @param array $options
+   *   (optional) An associative array of additional options. The 'absolute'
+   *   option is forced to be TRUE.
+   *
+   * @return string
+   *   The generated absolute URL for the given route.
+   *
+   * @todo Add an option for scheme-relative URLs.
+   */
+  public function getUrl($name, $parameters = array(), $options = array()) {
+    $options['absolute'] = TRUE;
+    return $this->urlGenerator->generateFromRoute($name, $parameters, $options);
+  }
+
+  /**
+   * Generates an absolute URL given a path.
+   *
+   * @param string $path
+   *   The path.
+   * @param array $options
+   *   (optional) An associative array of additional options. The 'absolute'
+   *   option is forced to be TRUE.
+   *
+   * @return string
+   *   The generated absolute URL for the given path.
+   */
+  public function getUrlFromPath($path, $options = array()) {
+    $options['absolute'] = TRUE;
+    return $this->urlGenerator->generateFromPath($path, $options);
+  }
+
+  /**
+   * Determines at compile time whether the generated URL will be safe.
+   *
+   * Saves the unneeded automatic escaping for performance reasons.
+   *
+   * The URL generation process percent encodes non-alphanumeric characters.
+   * Thus, the only character within an URL that must be escaped in HTML is the
+   * ampersand ("&") which separates query params. Thus we cannot mark
+   * the generated URL as always safe, but only when we are sure there won't be
+   * multiple query params. This is the case when there are none or only one
+   * constant parameter given. E.g. we know beforehand this will not need to
+   * be escaped:
+   * - path('route')
+   * - path('route', {'param': 'value'})
+   * But the following may need to be escaped:
+   * - path('route', var)
+   * - path('route', {'param': ['val1', 'val2'] }) // a sub-array
+   * - path('route', {'param1': 'value1', 'param2': 'value2'})
+   * If param1 and param2 reference placeholders in the route, it would not
+   * need to be escaped, but we don't know that in advance.
+   *
+   * @param \Twig_Node $args_node
+   *   The arguments of the path/url functions.
+   *
+   * @return array
+   *   An array with the contexts the URL is safe
+   */
+  public function isUrlGenerationSafe(\Twig_Node $args_node) {
+    // Support named arguments.
+    $parameter_node = $args_node->hasNode('parameters') ? $args_node->getNode('parameters') : ($args_node->hasNode(1) ? $args_node->getNode(1) : NULL);
+
+    if (!isset($parameter_node) || $parameter_node instanceof \Twig_Node_Expression_Array && count($parameter_node) <= 2 &&
+        (!$parameter_node->hasNode(1) || $parameter_node->getNode(1) instanceof \Twig_Node_Expression_Constant)) {
+      return array('html');
+    }
+
+    return array();
+  }
+
 }
diff --git a/core/modules/node/templates/node-add-list.html.twig b/core/modules/node/templates/node-add-list.html.twig
index 73238969e3febe13a609965c8ff51b5c8bfac343..258d3e631f73766882e5d3d644c8c2796b3677f0 100644
--- a/core/modules/node/templates/node-add-list.html.twig
+++ b/core/modules/node/templates/node-add-list.html.twig
@@ -24,7 +24,7 @@
   </dl>
 {% else %}
   <p>
-    {% set create_content = url('admin/structure/types/add') %}
+    {% set create_content = path('node.type_add') %}
     {% trans %}
       You have not created any content types yet. Go to the <a href="{{ create_content }}">content type creation page</a> to add a new content type.
     {% endtrans %}
diff --git a/core/modules/system/src/Tests/Theme/EngineTwigTest.php b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
index 2e89f47d2ad9f5bd9172c4cbbe42c174995f8b32..0f69878f3cc03e87d08affe45654858ab2f3330e 100644
--- a/core/modules/system/src/Tests/Theme/EngineTwigTest.php
+++ b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
@@ -41,4 +41,26 @@ function testTwigVariableDataTypes() {
     }
   }
 
+  /**
+   * Tests the url and url_generate Twig functions.
+   */
+  public function testTwigUrlGenerator() {
+    $this->drupalGet('twig-theme-test/url-generator');
+    // Find the absolute URL of the current site.
+    $url_generator = $this->container->get('url_generator');
+    $expected = array(
+      'path (as route) not absolute: ' . $url_generator->generateFromRoute('user.register'),
+      'url (as route) absolute: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE)),
+      'path (as route) not absolute with fragment: ' . $url_generator->generateFromRoute('user.register', array(), array('fragment' => 'bottom')),
+      'url (as route) absolute despite option: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE)),
+      'url (as route) absolute with fragment: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE, 'fragment' => 'bottom')),
+    );
+    // Make sure we got something.
+    $content = $this->drupalGetContent();
+    $this->assertFalse(empty($content), 'Page content is not empty');
+    foreach ($expected as $string) {
+      $this->assertRaw('<div>' . $string . '</div>');
+    }
+  }
+
 }
diff --git a/core/modules/system/templates/tablesort-indicator.html.twig b/core/modules/system/templates/tablesort-indicator.html.twig
index 1f0eb9d2a6d804c3f75726545309be0047e2cd4a..059805f1d41a285f49e18e803dd267248e9e258d 100644
--- a/core/modules/system/templates/tablesort-indicator.html.twig
+++ b/core/modules/system/templates/tablesort-indicator.html.twig
@@ -6,11 +6,13 @@
  * Available variables:
  * - style: Either 'asc' or 'desc', indicating the sorting direction.
  *
+ * @see template_preprocess_tablesort_indicator()
+ *
  * @ingroup themeable
  */
 #}
 {% if style == 'asc' -%}
-  <img src="{{ url('core/misc/arrow-asc.png') }}" width="13" height="13" alt="{{ 'sort ascending'|t }}" title="{{ 'sort ascending'|t }}" />
+  <img src="{{ arrow_asc }}" width="13" height="13" alt="{{ 'sort ascending'|t }}" title="{{ 'sort ascending'|t }}" />
 {% else -%}
-  <img src="{{ url('core/misc/arrow-desc.png') }}" width="13" height="13" alt="{{ 'sort descending'|t }}" title="{{ 'sort descending'|t }}" />
+  <img src="{{ arrow_desc }}" width="13" height="13" alt="{{ 'sort descending'|t }}" title="{{ 'sort descending'|t }}" />
 {% endif %}
diff --git a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
index 45654ea206dc8bfe27bf098ca434faccc62a886a..d454e5f30624ffc02a906f54b6fd39eeab965013 100644
--- a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
+++ b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
@@ -28,4 +28,13 @@ public function transBlockRender() {
     );
   }
 
+  /**
+   * Renders for testing url_generator functions in a Twig template.
+   */
+  public function urlGeneratorRender() {
+    return array(
+      '#theme' => 'twig_theme_test_url_generator',
+    );
+  }
+
 }
diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..131a6120ba402d16cb41eb75f16c33d499b81bfd
--- /dev/null
+++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig
@@ -0,0 +1,7 @@
+{# Test the url and path twig functions #}
+<div>path (as route) not absolute: {{ path('user.register') }}</div>
+<div>url (as route) absolute: {{ url('user.register') }}</div>
+
+<div>path (as route) not absolute with fragment: {{ path('user.register', {}, {'fragment': 'bottom' }) }}</div>
+<div>url (as route) absolute despite option: {{ url('user.register', {}, {'absolute': false }) }}</div>
+<div>url (as route) absolute with fragment: {{ url('user.register', {}, {'fragment': 'bottom' }) }}</div>
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
index 5874cca75482d8dcbee0012b19b8f2cafbea5e94..0497c7b9b802d812e28dd82b5710043478a21569 100644
--- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
+++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
@@ -23,6 +23,10 @@ function twig_theme_test_theme($existing, $type, $theme, $path) {
     'variables' => array('script' => ''),
     'template' => 'twig-raw-test',
   );
+  $items['twig_theme_test_url_generator'] = array(
+    'variables' => array(),
+    'template' => 'twig_theme_test.url_generator',
+  );
   return $items;
 }
 
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
index 96befd49a891d840f917bedff8bc13e23d6fd39d..75b9bbb11fbfaf7ff0336bb99ef9a209b4f875c9 100644
--- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
+++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
@@ -11,3 +11,10 @@ twig_theme_test.trans:
     _content: '\Drupal\twig_theme_test\TwigThemeTestController::transBlockRender'
   requirements:
     _access: 'TRUE'
+
+twig_theme_test_url_generator:
+  path: '/twig-theme-test/url-generator'
+  defaults:
+    _content: '\Drupal\twig_theme_test\TwigThemeTestController::urlGeneratorRender'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d528ee544539ea5607288866f8f1bffbfb4ab372
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Template\TwigExtensionTest.
+ */
+
+namespace Drupal\Tests\Core\Template;
+
+use Drupal\Core\Template\TwigExtension;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the twig extension.
+ *
+ * @group Template
+ *
+ * @coversDefaultClass \Drupal\Core\Template\TwigExtension
+ */
+class TwigExtensionTest extends UnitTestCase {
+
+  /**
+   * Tests the escaping
+   * @dataProvider providerTestEscaping
+   *
+   * @covers
+   */
+  public function testEscaping($template, $expected) {
+    $twig = new \Twig_Environment(NULL, array(
+      'debug' => TRUE,
+      'cache' => FALSE,
+      'autoescape' => TRUE,
+      'optimizations' => 0
+    ));
+    $twig->addExtension((new TwigExtension())->setGenerators($this->getMock('Drupal\Core\Routing\UrlGeneratorInterface')));
+
+    $nodes = $twig->parse($twig->tokenize($template));
+
+    $this->assertSame($expected, $nodes->getNode('body')
+        ->getNode(0)
+        ->getNode('expr') instanceof \Twig_Node_Expression_Filter);
+  }
+
+  /**
+   * Provides tests data for testEscaping
+   *
+   * @return array
+   *   An array of test data each containing of a twig template string and
+   *   a boolean expecting whether the path will be safe.
+   */
+  public function providerTestEscaping() {
+    return array(
+      array('{{ path("foo") }}', FALSE),
+      array('{{ path("foo", {}) }}', FALSE),
+      array('{{ path("foo", { foo: "foo" }) }}', FALSE),
+      array('{{ path("foo", foo) }}', TRUE),
+      array('{{ path("foo", { foo: foo }) }}', TRUE),
+      array('{{ path("foo", { foo: ["foo", "bar"] }) }}', TRUE),
+      array('{{ path("foo", { foo: "foo", bar: "bar" }) }}', TRUE),
+      array('{{ path(name = "foo", parameters = {}) }}', FALSE),
+      array('{{ path(name = "foo", parameters = { foo: "foo" }) }}', FALSE),
+      array('{{ path(name = "foo", parameters = foo) }}', TRUE),
+      array(
+        '{{ path(name = "foo", parameters = { foo: ["foo", "bar"] }) }}',
+        TRUE
+      ),
+      array('{{ path(name = "foo", parameters = { foo: foo }) }}', TRUE),
+      array(
+        '{{ path(name = "foo", parameters = { foo: "foo", bar: "bar" }) }}',
+        TRUE
+      ),
+    );
+  }
+
+}
diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme
index abf6c4f6dbbf11164b3fd02155c4f76e3a6c471a..8cdc9c1725e1b8e992235564aebeddf4a8a4948c 100644
--- a/core/themes/seven/seven.theme
+++ b/core/themes/seven/seven.theme
@@ -120,9 +120,6 @@ function seven_preprocess_node_add_list(&$variables) {
       $variables['types'][$type->type]['url'] = \Drupal::url('node.add', array('node_type' => $type->type));
     }
   }
-  else {
-    $variables['add_content_type_url'] = \Drupal::url('node.type_add');
-  }
 }
 
 /**
diff --git a/core/themes/seven/templates/node-add-list.html.twig b/core/themes/seven/templates/node-add-list.html.twig
index 4d5e020687cb54585d1b0bfea84540358807b788..897dd1ea13c3425a1bde7c52445b0d559e19fc76 100644
--- a/core/themes/seven/templates/node-add-list.html.twig
+++ b/core/themes/seven/templates/node-add-list.html.twig
@@ -8,7 +8,6 @@
  *   - url: Path to the add content of this type page.
  *   - label: The title of this type of content.
  *   - description: Description of this type of content.
- * - add_content_type_url: Path to the add content type page.
  *
  * @see template_preprocess_node_add_list()
  * @see seven_preprocess_node_add_list()
@@ -22,8 +21,9 @@
   </ul>
 {% else %}
   <p>
+    {% set create_content = path('node.type_add') %}
     {% trans %}
-      You have not created any content types yet. Go to the <a href="{{ add_content_type_url }}">content type creation page</a> to add a new content type.
+      You have not created any content types yet. Go to the <a href="{{ create_content }}">content type creation page</a> to add a new content type.
     {% endtrans %}
   </p>
 {% endif %}