diff --git a/genshi/filters/i18n.py b/genshi/filters/i18n.py
--- a/genshi/filters/i18n.py
+++ b/genshi/filters/i18n.py
@@ -131,14 +131,20 @@
             gettext = self.translator.ugettext
         except AttributeError:
             gettext = self.translator.gettext
+        try:
+            # Unicode aware version first
+            ngettext = self.translator.ungettext
+        except AttributeError:
+            ngettext = self.translator.ngettext
 
         if not self.extract_text:
             search_text = False
         skip = 0
-        i18n_msg = I18N_NAMESPACE['msg']
+        i18n_msg = I18N_NAMESPACE['msg']        
+        i18n_choose = I18N_NAMESPACE['choose']
         ns_prefixes = []
         xml_lang = XML_NAMESPACE['lang']
-
+        
         for kind, data, pos in stream:
 
             # skip chunks that should not be localized
@@ -184,6 +190,10 @@
                     params = attrs.get(i18n_msg)
                     msgbuf = MessageBuffer(params)
                     attrs -= i18n_msg
+                elif i18n_choose in attrs:
+                    params = attrs.get(i18n_choose)
+                    msgbuf = MessageBuffer(params)
+                    attrs -= i18n_choose                    
 
                 yield kind, (tag, attrs), pos
 
@@ -202,8 +212,14 @@
             elif not skip and msgbuf and kind is END:
                 msgbuf.append(kind, data, pos)
                 if not msgbuf.depth:
-                    for event in msgbuf.translate(gettext(msgbuf.format())):
-                        yield event
+                    if msgbuf.singular or msgbuf.plural:
+                        singular, plural, expr = msgbuf.format()
+                        events = ngettext(singular, plural, expr.evaluate(ctxt))
+                        for event in msgbuf.translate(events):
+                            yield event
+                    else:
+                        for event in msgbuf.translate(gettext(msgbuf.format())):
+                            yield event
                     msgbuf = None
                     yield kind, data, pos
 
@@ -298,7 +314,7 @@
                         if name in self.include_attrs:
                             text = value.strip()
                             if text:
-                                yield pos[1], None, text
+                                yield pos[1], None, text, []
                     else:
                         for lineno, funcname, text, comments in self.extract(
                                 _ensure(value), gettext_functions,
@@ -328,7 +344,8 @@
                 msgbuf.append(kind, data, pos)
                 if not msgbuf.depth:
                     if msgbuf.singular or msgbuf.plural:
-                         yield msgbuf.lineno, 'ngettext', msgbuf.format(), \
+                        singular, plural, num = msgbuf.format()
+                        yield msgbuf.lineno, 'ngettext', (singular, plural), \
                                                                 msgbuf.comments
                     else:
                         yield msgbuf.lineno, None, msgbuf.format(), \
@@ -374,6 +391,8 @@
                             self.params.append(param.strip())
                 elif entry[0] == 'EXPR':
                     self.choose_numeral = entry[1]
+        elif isinstance(params, basestring):
+            self.params = [p.strip() for p in params.split(',')]
         else:
             self.params = params
         self.singular_params = self.params[:]
@@ -384,8 +403,6 @@
         self.plural = []
         self.events = {}
         self.values = {}
-        self.singular_values = {}
-        self.plural_values = {}
         self.depth = 1
         self.order = 1
         self.choose_order = 1
@@ -414,25 +431,26 @@
         elif kind is EXPR:
             if self.choose_singular:
                 param = self.singular_params.pop(0)
-                self.singular.append('%%(%s)s' % param)
-                self.singular_values[param] = (kind, data, pos)         
+                self.singular.append('%%(%s)s' % param)      
             elif self.choose_plural:
                 param = self.plural_params.pop(0)
                 self.plural.append('%%(%s)s' % param)
-                self.plural_values[param] = (kind, data, pos)
             else:
                 param = self.params.pop(0)
                 self.string.append('%%(%s)s' % param)
-                self.values[param] = (kind, data, pos)
+            self.values[param] = (kind, data, pos)
             self.events.setdefault(self.stack[-1], []).append(None)
         else:
             if kind is START:
                 if self.choose_singular:
-                    self.ordered_singular = True
                     self.singular.append(u'[%d:' % self.choose_order)
+                    self.events.setdefault(self.choose_order,
+                                           []).append((kind, data, pos))
                 elif self.choose_plural:
-                    self.ordered_plural = True
                     self.plural.append(u'[%d:' % self.choose_order)
+                    self.events.setdefault(self.choose_order,
+                                           []).append((kind, data, pos))
+                    self.stack.append(self.choose_order)
                     self.choose_order += 1
                 elif self.i18n_choose_singular in data[1]:
                     self.choose_singular = True
@@ -442,9 +460,10 @@
                     self.choose_singular = False
                 else:
                     self.string.append(u'[%d:' % self.order)
+                    self.events.setdefault(self.order,
+                                           []).append((kind, data, pos))
+                    self.stack.append(self.order)
                     self.order += 1
-                self.events.setdefault(self.order, []).append((kind, data, pos))
-                self.stack.append(self.order)
                 self.depth += 1
             elif kind is END:
                 self.depth -= 1
@@ -453,7 +472,6 @@
                         self.choose_singular = False
                         if self.choose_order > 1:
                             self.singular.append(u']')
-                            self.ordered_singular = False
                     elif self.choose_plural:
                         self.choose_plural = False
                         if self.choose_order > 1:
@@ -469,7 +487,7 @@
         """
         if self.singular or self.plural:
             return (u''.join(self.singular).strip(),
-                    u''.join(self.plural).strip())
+                    u''.join(self.plural).strip(), self.choose_numeral)
         return u''.join(self.string).strip()
 
     def translate(self, string, regex=re.compile(r'%\((\w+)\)s')):
