Index: django/contrib/admin/helpers.py
===================================================================
--- django/contrib/admin/helpers.py	(revision 10116)
+++ django/contrib/admin/helpers.py	(working copy)
@@ -41,11 +41,13 @@
     media = property(_media)
 
 class Fieldset(object):
-    def __init__(self, form, name=None, fields=(), classes=(), description=None):
+    is_fieldset = True
+    def __init__(self, form, name=None, fields=(), classes=(), description=None, level=0):
         self.form = form
         self.name, self.fields = name, fields
         self.classes = u' '.join(classes)
         self.description = description
+        self.level = level
 
     def _media(self):
         if 'collapse' in self.classes:
@@ -55,7 +57,18 @@
 
     def __iter__(self):
         for field in self.fields:
-            yield Fieldline(self.form, field)
+            if (len(field)==2 and isinstance(field[1], dict)):
+                # nested fieldset
+                yield Fieldset(self.form,
+                    name=field[0],
+                    fields=field[1].get("fields", ()),
+                    classes=field[1].get("classes", ()),
+                    description=field[1].get("description", ()),
+                    level=self.level + 1,
+                    )
+            else:
+                # field name or a tuple of field names
+                yield Fieldline(self.form, field)
 
 class Fieldline(object):
     def __init__(self, form, field):
@@ -175,7 +188,18 @@
         for field in self.fields:
             if fk and fk.name == field:
                 continue
-            yield Fieldline(self.form, field)
+            if (len(field)==2 and isinstance(field[1], dict)):
+                # nested fieldset
+                yield Fieldset(self.form,
+                    name=field[0],
+                    fields=field[1].get("fields", ()),
+                    classes=field[1].get("classes", ()),
+                    description=field[1].get("description", ()),
+                    level=self.level + 1,
+                    )
+            else:
+                # field name or a tuple of field names
+                yield Fieldline(self.form, field)
             
 class AdminErrorList(forms.util.ErrorList):
     """
Index: django/contrib/admin/media/css/forms.css
===================================================================
--- django/contrib/admin/media/css/forms.css	(revision 10116)
+++ django/contrib/admin/media/css/forms.css	(working copy)
@@ -123,6 +123,12 @@
     width: 450px;
 }
 
+/* NESTED FIELDSETS */
+
+fieldset fieldset {
+    margin: 10px;
+}
+
 /* COLLAPSED FIELDSETS */
 
 fieldset.collapsed * {
Index: django/contrib/admin/templates/admin/includes/fieldset.html
===================================================================
--- django/contrib/admin/templates/admin/includes/fieldset.html	(revision 10116)
+++ django/contrib/admin/templates/admin/includes/fieldset.html	(working copy)
@@ -1,19 +1,23 @@
 <fieldset class="module aligned {{ fieldset.classes }}">
-  {% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
-  {% if fieldset.description %}<div class="description">{{ fieldset.description|safe }}</div>{% endif %}
-  {% for line in fieldset %}
-      <div class="form-row{% if line.errors %} errors{% endif %} {% for field in line %}{{ field.field.name }} {% endfor %} ">
-      {{ line.errors }}
-      {% for field in line %}
-      <div{% if not line.fields|length_is:"1" %} class="field-box"{% endif %}>
-          {% if field.is_checkbox %}
-              {{ field.field }}{{ field.label_tag }}
-          {% else %}
-              {{ field.label_tag }}{{ field.field }}
-          {% endif %}
-          {% if field.field.field.help_text %}<p class="help">{{ field.field.field.help_text|safe }}</p>{% endif %}
-      </div>
-      {% endfor %}
-      </div>
-  {% endfor %}
+    {% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
+    {% if fieldset.description %}<div class="description">{{ fieldset.description|safe }}</div>{% endif %}
+    {% for line in fieldset %}
+        {% if line.is_fieldset %}
+            {% include_parsed "admin/includes/fieldset.html" with line as fieldset %}
+        {% else %}
+            <div class="form-row{% if line.errors %} errors{% endif %} {% for field in line %}{{ field.field.name }} {% endfor %} ">
+            {{ line.errors }}
+            {% for field in line %}
+                <div{% if not line.fields|length_is:"1" %} class="field-box"{% endif %}>
+                  {% if field.is_checkbox %}
+                      {{ field.field }}{{ field.label_tag }}
+                  {% else %}
+                      {{ field.label_tag }}{{ field.field }}
+                  {% endif %}
+                  {% if field.field.field.help_text %}<p class="help">{{ field.field.field.help_text|safe }}</p>{% endif %}
+                </div>
+            {% endfor %}
+            </div>
+        {% endif %}
+    {% endfor %}
 </fieldset>
Index: django/contrib/admin/util.py
===================================================================
--- django/contrib/admin/util.py	(revision 10116)
+++ django/contrib/admin/util.py	(working copy)
@@ -47,10 +47,15 @@
     field_names = []
     for name, opts in fieldsets:
         for field in opts['fields']:
-            # type checking feels dirty, but it seems like the best way here
-            if type(field) == tuple:
-                field_names.extend(field)
+            if isinstance(field, (tuple, list)):
+                if len(field)==2 and isinstance(field[1], dict):
+                    # it's a nested fieldset
+                    field_names.extend(flatten_fieldsets((field,)))
+                else:
+                    # it's a tuple of field names
+                    field_names.extend(field)
             else:
+                # it's a field name
                 field_names.append(field)
     return field_names
 
Index: django/template/defaulttags.py
===================================================================
--- django/template/defaulttags.py	(revision 10116)
+++ django/template/defaulttags.py	(working copy)
@@ -8,6 +8,7 @@
 except NameError:
     from django.utils.itercompat import reversed     # Python 2.3 fallback
 
+from django.template import loader, RequestContext, Template
 from django.template import Node, NodeList, Template, Context, Variable
 from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END
 from django.template import get_library, Library, InvalidTemplateLibrary
@@ -432,6 +433,21 @@
         context.pop()
         return output
 
+class ParsedIncludeNode(Node):
+    def __init__(self, tag_name, template_path, extra):
+        self.tag_name = tag_name
+        self.template_path = template_path
+        self.extra = extra
+    def render(self, context):
+        template_path = self.template_path.resolve(context)
+        context_vars = {}
+        for d in list(context):
+            for var, val in d.items():
+                context_vars[var] = val
+        for var, val in self.extra:
+            context_vars[var] = val.resolve(context)
+        return loader.render_to_string(template_path, context_vars)
+
 #@register.tag
 def autoescape(parser, token):
     """
@@ -1171,3 +1187,40 @@
     parser.delete_first_token()
     return WithNode(var, name, nodelist)
 do_with = register.tag('with', do_with)
+
+#@register.tag
+def do_include_parsed(parser, token):
+    """
+    Parses the defined template with the current context variables and also the ones passed to the template tag. The included template might extend some other template.
+
+    Usage::
+
+        {% include_parsed <template_path> [with <value1> as <variable1>[ and <value2> as <variable2>[ and ...]] %}
+    
+    Examples::
+
+        {% include_parsed "people/item_person.html" %}
+        {% include_parsed path with membership.user.get_profile as person and membership.persongroup as persongroup %}
+
+    """    
+    bits = token.split_contents()
+    tag_name = bits.pop(0)
+    try:
+        template_path = bits.pop(0)
+        extra = [] # a tuple of variables names and values to parse before passing to the template
+        if bits:
+            bits.pop(0) # remove the word "with"
+            while bits:
+                val = bits.pop(0)
+                bits.pop(0) # remove the word "as"
+                var = bits.pop(0)
+                extra.append((var, parser.compile_filter(val)))
+                if bits:
+                    bits.pop(0) # remove the word "and"
+                    
+    except ValueError:
+        raise template.TemplateSyntaxError, "include_parsed tag requires a following syntax: {% include_parsed <template_path> [with <value1> as <variable1>[ and <value2> as <variable2>[ and ...]] %}"
+    return ParsedIncludeNode(parser.compile_filter(tag_name), parser.compile_filter(template_path), extra)
+    
+do_include_parsed = register.tag('include_parsed', do_include_parsed)
+
