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
 
@@ -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(), \
@@ -384,8 +401,6 @@
         self.plural = []
         self.events = {}
         self.values = {}
-        self.singular_values = {}
-        self.plural_values = {}
         self.depth = 1
         self.order = 1
         self.choose_order = 1
@@ -414,16 +429,14 @@
         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:
@@ -469,7 +482,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')):
