Index: genshi/template/tests/directives.py
===================================================================
--- genshi/template/tests/directives.py	(revision 806)
+++ genshi/template/tests/directives.py	(working copy)
@@ -631,6 +631,32 @@
           </body>
         </html>""", str(tmpl.generate()))
 
+    def test_recursive_match_3(self):
+        tmpl = MarkupTemplate("""<test xmlns:py="http://genshi.edgewall.org/">
+          <py:match path="b[@type='bullet']">
+            <bullet>${select('*|text()')}</bullet>
+          </py:match>
+          <py:match path="group[@type='bullet']">
+            <ul>${select('*')}</ul>
+          </py:match>
+          <py:match path="b">
+            <generic>${select('*|text()')}</generic>
+          </py:match>
+
+          <b>
+            <group type="bullet">
+              <b type="bullet">1</b>
+              <b type="bullet">2</b>
+            </group>
+          </b>
+        </test>
+        """)
+        self.assertEqual("""<test>
+            <generic>
+            <ul><bullet>1</bullet><bullet>2</bullet></ul>
+          </generic>
+        </test>""", str(tmpl.generate()))
+
     def test_not_match_self(self):
         """
         See http://genshi.edgewall.org/ticket/77
Index: genshi/template/markup.py
===================================================================
--- genshi/template/markup.py	(revision 806)
+++ genshi/template/markup.py	(working copy)
@@ -272,9 +272,10 @@
                     # Consume and store all events until an end event
                     # corresponding to this start event is encountered
                     inner = _strip(stream)
-                    if 'match_once' not in hints \
-                            and 'not_recursive' not in hints:
-                        inner = self._match(inner, ctxt, [match_templates[idx]])
+                    pre_match_templates = match_templates[:idx + 1]
+                    if 'match_once' not in hints and 'not_recursive' in hints:
+                        pre_match_templates.pop()
+                    inner = self._match(inner, ctxt, pre_match_templates)
                     content = list(self._include(chain([event], inner, tail),
                                                  ctxt))
 
@@ -290,11 +291,9 @@
                     # Recursively process the output
                     template = _apply_directives(template, ctxt, directives)
                     remaining = match_templates
-                    if 'match_once' not in hints:
-                        remaining = remaining[:idx] + remaining[idx + 1:]
                     for event in self._match(self._exec(
                                     self._eval(self._flatten(template, ctxt),
-                                    ctxt), ctxt), ctxt, remaining):
+                                    ctxt), ctxt), ctxt, match_templates[idx + 1:]):
                         yield event
 
                     ctxt.pop()
