Move the autoescape extension and with statement to be built-in
diff --git a/CHANGES b/CHANGES
index bd0dc75..afc6f76 100644
--- a/CHANGES
+++ b/CHANGES
@@ -40,6 +40,7 @@
   between the different include and import constructs.  Context is now always
   propagated the same way.  The only remaining differences is the defaults
   for `with context` and `without context`.
+- The `with` and `autoescape` tags are now built-in.
 
 Version 2.8.2
 -------------
diff --git a/docs/api.rst b/docs/api.rst
index 3b5bccd..b7c25d3 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -247,12 +247,14 @@
 Autoescaping
 ------------
 
-.. versionadded:: 2.4
+.. versionchanged:: 2.4
 
-As of Jinja 2.4 the preferred way to do autoescaping is to enable the
-:ref:`autoescape-extension` and to configure a sensible default for
-autoescaping.  This makes it possible to enable and disable autoescaping
-on a per-template basis (HTML versus text for instance).
+Jinja2 now comes with autoescaping support.  As of Jinja 2.9 the
+autoescape extension is removed and built-in.  However autoescaping is
+not yet enabled by default though this might change in the future.
+It's recommended to configure a sensible default for autoescaping.  This
+makes it possible to enable and disable autoescaping on a per-template
+basis (HTML versus text for instance).
 
 Here a recommended setup that enables autoescaping for templates ending
 in ``'.html'``, ``'.htm'`` and ``'.xml'`` and disabling it by default
@@ -265,8 +267,7 @@
         return ext in ('html', 'htm', 'xml')
 
     env = Environment(autoescape=guess_autoescape,
-                      loader=PackageLoader('mypackage'),
-                      extensions=['jinja2.ext.autoescape'])
+                      loader=PackageLoader('mypackage'))
 
 When implementing a guessing autoescape function, make sure you also
 accept `None` as valid template name.  This will be passed when generating
diff --git a/docs/extensions.rst b/docs/extensions.rst
index afdfb00..635d1e4 100644
--- a/docs/extensions.rst
+++ b/docs/extensions.rst
@@ -183,12 +183,9 @@
 
 **Import name:** `jinja2.ext.with_`
 
-.. versionadded:: 2.3
+.. versionchanged:: 2.9
 
-This extension adds support for the with keyword.  Using this keyword it
-is possible to enforce a nested scope in a template.  Variables can be
-declared directly in the opening block of the with statement or using a
-standard `set` statement directly within.
+This extension is now built-in and no longer does anything.
 
 .. _autoescape-extension:
 
@@ -197,12 +194,10 @@
 
 **Import name:** `jinja2.ext.autoescape`
 
-.. versionadded:: 2.4
+.. versionchanged:: 2.9
 
-The autoescape extension allows you to toggle the autoescape feature from
-within the template.  If the environment's :attr:`~Environment.autoescape`
-setting is set to `False` it can be activated, if it's `True` it can be
-deactivated.  The setting overriding is scoped.
+This extension was removed and is now built-in.  Enabling the extension
+no longer does anything.
 
 
 .. _writing-extensions:
diff --git a/docs/templates.rst b/docs/templates.rst
index 9c3e7d5..48f1894 100644
--- a/docs/templates.rst
+++ b/docs/templates.rst
@@ -1460,10 +1460,8 @@
 
 .. versionadded:: 2.3
 
-If the application enables the :ref:`with-extension`, it is possible to
-use the `with` keyword in templates.  This makes it possible to create
-a new inner scope.  Variables set within this scope are not visible
-outside of the scope.
+The with statement makes it possible to create a new inner scope.
+Variables set within this scope are not visible outside of the scope.
 
 With in a nutshell::
 
@@ -1486,15 +1484,20 @@
         {{ foo }}
     {% endwith %}
 
+.. admonition:: Extension
+
+   In older versions of Jinja (before 2.9) it was required to enable this
+   feature with an extension.  It's now enabled by default.
+
 .. _autoescape-overrides:
 
-Autoescape Extension
+Autoescape Overrides
 --------------------
 
 .. versionadded:: 2.4
 
-If the application enables the :ref:`autoescape-extension`, one can
-activate and deactivate the autoescaping from within the templates.
+If you want you can activate and deactivate the autoescaping from within
+the templates.
 
 Example::
 
@@ -1507,3 +1510,8 @@
     {% endautoescape %}
 
 After an `endautoescape` the behavior is reverted to what it was before.
+
+.. admonition:: Extension
+
+   In older versions of Jinja (before 2.9) it was required to enable this
+   feature with an extension.  It's now enabled by default.
diff --git a/jinja2/ext.py b/jinja2/ext.py
index 562ab50..2735dbb 100644
--- a/jinja2/ext.py
+++ b/jinja2/ext.py
@@ -411,38 +411,11 @@
 
 
 class WithExtension(Extension):
-    """Adds support for a django-like with block."""
-    tags = set(['with'])
-
-    def parse(self, parser):
-        node = nodes.Scope(lineno=next(parser.stream).lineno)
-        assignments = []
-        while parser.stream.current.type != 'block_end':
-            lineno = parser.stream.current.lineno
-            if assignments:
-                parser.stream.expect('comma')
-            target = parser.parse_assign_target()
-            parser.stream.expect('assign')
-            expr = parser.parse_expression()
-            assignments.append(nodes.Assign(target, expr, lineno=lineno))
-        node.body = assignments + \
-            list(parser.parse_statements(('name:endwith',),
-                                         drop_needle=True))
-        return node
+    pass
 
 
 class AutoEscapeExtension(Extension):
-    """Changes auto escape rules for a scope."""
-    tags = set(['autoescape'])
-
-    def parse(self, parser):
-        node = nodes.ScopedEvalContextModifier(lineno=next(parser.stream).lineno)
-        node.options = [
-            nodes.Keyword('autoescape', parser.parse_expression())
-        ]
-        node.body = parser.parse_statements(('name:endautoescape',),
-                                            drop_needle=True)
-        return nodes.Scope([node])
+    pass
 
 
 def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS,
diff --git a/jinja2/parser.py b/jinja2/parser.py
index 00e0558..8c3cd5b 100644
--- a/jinja2/parser.py
+++ b/jinja2/parser.py
@@ -16,7 +16,7 @@
 
 _statement_keywords = frozenset(['for', 'if', 'block', 'extends', 'print',
                                  'macro', 'include', 'from', 'import',
-                                 'set'])
+                                 'set', 'with', 'autoescape'])
 _compare_operators = frozenset(['eq', 'ne', 'lt', 'lteq', 'gt', 'gteq'])
 
 _math_nodes = {
@@ -224,6 +224,31 @@
             break
         return result
 
+    def parse_with(self):
+        node = nodes.Scope(lineno=next(self.stream).lineno)
+        assignments = []
+        while self.stream.current.type != 'block_end':
+            lineno = self.stream.current.lineno
+            if assignments:
+                self.stream.expect('comma')
+            target = self.parse_assign_target()
+            self.stream.expect('assign')
+            expr = self.parse_expression()
+            assignments.append(nodes.Assign(target, expr, lineno=lineno))
+        node.body = assignments + \
+            list(self.parse_statements(('name:endwith',),
+                                         drop_needle=True))
+        return node
+
+    def parse_autoescape(self):
+        node = nodes.ScopedEvalContextModifier(lineno=next(self.stream).lineno)
+        node.options = [
+            nodes.Keyword('autoescape', self.parse_expression())
+        ]
+        node.body = self.parse_statements(('name:endautoescape',),
+                                            drop_needle=True)
+        return nodes.Scope([node])
+
     def parse_block(self):
         node = nodes.Block(lineno=next(self.stream).lineno)
         node.name = self.stream.expect('name').value