Index: django/utils/text.py
===================================================================
--- django/utils/text.py	(revision 6980)
+++ django/utils/text.py	(working copy)
@@ -196,7 +196,9 @@
     return str(ustring_re.sub(fix, s))
 javascript_quote = allow_lazy(javascript_quote, unicode)
 
-smart_split_re = re.compile('("(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'(?:[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'|[^\\s]+)')
+smart_split_re = re.compile('([^"\\\\ ]*"(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"[^"\\\\ ]*'
+                            "|[^'\\\\ ]*'(?:[^'\\\\]*(?:\\\\.[^'\\\\]*)*)'[^'\\\\ ]*"
+                            '|[^\\s]+)')
 def smart_split(text):
     """
     Generator that splits a string by spaces, leaving quoted phrases together.
Index: django/template/defaulttags.py
===================================================================
--- django/template/defaulttags.py	(revision 6980)
+++ django/template/defaulttags.py	(working copy)
@@ -160,7 +160,7 @@
     def __init__(self, nodelist, *varlist):
         self.nodelist = nodelist
         self._last_seen = None
-        self._varlist = map(Variable, varlist)
+        self._varlist = varlist
 
     def render(self, context):
         if 'forloop' in context and context['forloop']['first']:
@@ -611,7 +611,7 @@
         ==========================  ================================================
 
     """
-    bits = token.contents.split()
+    bits = token.split_contents()
     if len(bits) < 4:
         raise TemplateSyntaxError("'for' statements should have at least four"
                                   " words: %s" % token.contents)
@@ -635,7 +635,7 @@
 do_for = register.tag("for", do_for)
 
 def do_ifequal(parser, token, negate):
-    bits = list(token.split_contents())
+    bits = token.split_contents()
     if len(bits) != 3:
         raise TemplateSyntaxError, "%r takes two arguments" % bits[0]
     end_tag = 'end' + bits[0]
@@ -799,10 +799,10 @@
                 {% endifchanged %}
             {% endfor %}
     """
-    bits = token.contents.split()
+    bits = token.split_contents()
     nodelist = parser.parse(('endifchanged',))
     parser.delete_first_token()
-    return IfChangedNode(nodelist, *bits[1:])
+    return IfChangedNode(nodelist, *[parser.compile_filter(bit) for bit in bits[1:]])
 ifchanged = register.tag(ifchanged)
 
 #@register.tag
@@ -923,7 +923,7 @@
         {% regroup people|dictsort:"gender" by gender as grouped %}
 
     """
-    bits = token.contents.split()
+    bits = token.split_contents()
     if len(bits) != 6:
         raise TemplateSyntaxError, "'regroup' tag takes five arguments"
     target = parser.compile_filter(bits[1])
@@ -1088,7 +1088,7 @@
             {{ total }} object{{ total|pluralize }}
         {% endwith %}
     """
-    bits = list(token.split_contents())
+    bits = token.split_contents()
     if len(bits) != 4 or bits[2] != "as":
         raise TemplateSyntaxError("%r expected format is 'value as name'" %
                                   bits[0])
Index: tests/regressiontests/templates/tests.py
===================================================================
--- tests/regressiontests/templates/tests.py	(revision 6980)
+++ tests/regressiontests/templates/tests.py	(working copy)
@@ -8,7 +8,7 @@
 
 import os
 import unittest
-from datetime import datetime, timedelta
+from datetime import datetime, date
 
 from django import template
 from django.template import loader
@@ -922,6 +922,50 @@
             # implementation details (fortunately, the (no)autoescape block
             # tags can be used in those cases)
             'autoescape-filtertag01': ("{{ first }}{% filter safe %}{{ first }} x<y{% endfilter %}", {"first": "<a>"}, template.TemplateSyntaxError),
+            
+            ### Tags using a filtered argument that is passed an argument #####
+            ### with a space (see #6271). #####################################
+            'argfilter01': ('{% regroup data by bar|date:"F Y" as grouped %}' + \
+                            '{% for group in grouped %}' + \
+                                '{{ group.grouper }}:' + \
+                                '{% for item in group.list %}' + \
+                                    '{{ item.foo }}' + \
+                                '{% endfor %},' + \
+                            '{% endfor %}',
+                            {'data': [{'foo':'c', 'bar':datetime(2000,1,1)}, 
+                                      {'foo':'d', 'bar':datetime(2000,1,1)}, 
+                                      {'foo':'a', 'bar':datetime(2000,2,1)}, 
+                                      {'foo':'b', 'bar':datetime(2000,2,1)}, 
+                                      {'foo':'x', 'bar':datetime(2000,3,1)} ]}, 
+                            'January 2000:cd,February 2000:ab,March 2000:x,'),
+# The firstof, if, ifequal, and ifnotequal tags need some more work to accept
+# arguments with filters.
+#            'argfilter02': ('{% firstof date|date:"F Y" "text" %}',
+#                            {'date': date(2007, 6, 2)}, 'June 2007'),
+#            # This test fails when TEMPLATE_STRING_IF_INVALID='INVALID'
+#            #'argfilter03': ('{% firstof date|date:"F Y" "text" %}',
+#            #                {}, 'text'),
+#            'argfilter04': ('{% firstof "text" date|date:"F Y" %}',
+#                            {'date': date(2007, 6, 2)}, 'text'),
+#            'argfilter05': ('{% for letter in date|date:"F Y" %}{{ letter }}-{% endfor %}',
+#                            {'date': date(2007, 6, 2)}, 'J-u-n-e- -2-0-0-7-'),
+#            'argfilter06': ('{% ifequal date|date:"F Y" "June 2007" %}equal{% endifequal %}',
+#                            {'date': date(2007, 6, 2)}, 'equal'),
+#            'argfilter07': ('{% ifnotequal date|date:"F Y" "June 2008" %}notequal{% endifnotequal %}',
+#                            {'date': date(2007, 6, 2)}, 'notequal'),
+#            'argfilter08': ('{% if date|date:"F Y" %}true{% endif %}',
+#                            {'date': date(2007, 6, 2)}, 'true'),
+#            'argfilter09': ('{% if date|date:"F Y" %}{% else %}false{% endif %}',
+#                            {}, 'false'),
+            'argfilter10': ('{% for date in data %}{% ifchanged date|date:"F Y" %}changed{% endifchanged %}{% endfor %}',
+                            {'data': [date(2007, 6, 2),
+                                      date(2007, 6, 10),
+                                      date(2007, 12, 30),
+                                      date(2007, 12, 31),
+                                      ]},
+                            'changedchanged'),
+            'argfilter11': ('{% with date|date:"F Y" as formatted_date %}{{ formatted_date }}{% endwith %}',
+                            {'date': date(2007, 6, 2)}, 'June 2007'),
         }
 
 if __name__ == "__main__":
Index: tests/regressiontests/utils/tests.py
===================================================================
--- tests/regressiontests/utils/tests.py	(revision 6980)
+++ tests/regressiontests/utils/tests.py	(working copy)
@@ -4,7 +4,7 @@
 
 from unittest import TestCase
 
-from django.utils import html, checksums
+from django.utils import html, checksums, text
 
 import timesince
 import datastructures
@@ -15,8 +15,9 @@
     'datastructures': datastructures,
 }
 
-class TestUtilsHtml(TestCase):
 
+class UtilsTestCase(TestCase):
+    
     def check_output(self, function, value, output=None):
         """
         Check that function(value) equals output.  If output is None,
@@ -26,6 +27,38 @@
             output = value
         self.assertEqual(function(value), output)
 
+    def check_generator_output(self, function, value, output=None):
+        """
+        Check that list(function(value)) equals output.  If output is None,
+        check that list(function(value)) equals value.
+        """
+        if output is None:
+            output = value
+        self.assertEqual(list(function(value)), output)
+
+class TestUtilsText(UtilsTestCase):
+
+    def test_smart_split(self):
+        f = text.smart_split
+        items = (
+            # Double quotes.
+            ('arg1 arg2|filter:"1" arg3', ['arg1', 'arg2|filter:"1"', 'arg3']),
+            ('arg1 arg2|filter:"1 2" arg3', ['arg1', 'arg2|filter:"1 2"', 'arg3']),
+            ('arg1 arg2|filter:"1  2" arg3', ['arg1', 'arg2|filter:"1  2"', 'arg3']),
+            ('arg1 arg2|filter:"1\t2" arg3', ['arg1', 'arg2|filter:"1\t2"', 'arg3']),
+            #('arg1 arg2|filter:"1\"1" arg3', ['arg1', 'arg2|filter:"1"1', 'arg3']),
+            # Singe quotes.
+            ("arg1 arg2|filter:'1' arg3", ['arg1', "arg2|filter:'1'", 'arg3']),
+            ("arg1 arg2|filter:'1 2' arg3", ['arg1', "arg2|filter:'1 2'", 'arg3']),
+            ("arg1 arg2|filter:'1  2' arg3", ['arg1', "arg2|filter:'1  2'", 'arg3']),
+            ("arg1 arg2|filter:'1\t2' arg3", ['arg1', "arg2|filter:'1\t2'", 'arg3']),
+        )
+        for value, output in items:
+            self.check_generator_output(f, value, output)
+
+
+class TestUtilsHtml(UtilsTestCase):
+
     def test_escape(self):
         f = html.escape
         items = (
@@ -123,17 +156,8 @@
         for value, output in items:
             self.check_output(f, value, output)
 
-class TestUtilsChecksums(TestCase):
+class TestUtilsChecksums(UtilsTestCase):
 
-    def check_output(self, function, value, output=None):
-        """
-        Check that function(value) equals output.  If output is None,
-        check that function(value) equals value.
-        """
-        if output is None:
-            output = value
-        self.assertEqual(function(value), output)
-
     def test_luhn(self):
         f = checksums.luhn
         items = (
