text: def piglatin(text):
      """Quick and dirty, regex-based pig latin converter"""
      pl_re="""
      (?ix)       # Verbose processing, ignore case
      (\W|^)      # Start of word or string
      (?! (?: the|\w{0,2})(?:\W|$)) # Don't match 'the' or two-letter words
      (\w*?)([aeiouy]\w*)
      (?= \W|$)   # End of word or string
      """.encode('ascii')
      import re
      def cvt(m):
          pre, head, tail = m.groups()
          return pre+tail+(head or 'w'.encode('ascii'))+'ay'.encode('ascii')
      return re.sub(pl_re, cvt, text)
      
  
  def latinator(app):
      from wsgi_lite import lite, lighten
  
      def middleware(environ):
          status, headers, body = app(environ)
          for name, value in headers:
              if name.lower() == 'content-type' and value == 'text/plain':
                  break
          else:
              # Not text/plain, pass it through unchanged 
              return status, headers, body
                  
          # Strip content-length if present, else it'll be wrong
          headers = [
              (name, value) for name, value in headers
                  if name.lower() != 'content-length'
          ]
          def pliter(body):   # Python 2.3 doesn't do generator expressions
              for data in body: yield piglatin(data)
          return status, headers, pliter(body)
  
      # Make sure that `app` can be invoked via the Lite protocol
      app = lighten(app)  
      return lite(middleware)
  
  def test(app, environ={}, form={}, _debug=True, **kw):
      """Print the output of a WSGI app
  
      Runs `app` as a WSGI application and prints its output.  If an untrapped
      error occurs in `app`, it drops into the ``pdb`` debugger's post-mortem
      debug shell (using ``sys.__stdout__`` if ``sys.stdout`` has been replaced).
  
      Any keyword arguments are added to the environment used to run `app`.  If
      a keyword argument begins with ``wsgi_``, the ``_`` is replaced with a
      ``.``, so that you can set e.g. ``wsgi.multithread`` using a
      ``wsgi_multithread`` keyword argument.
  
      If a non-empty `form` dictionary is provided, it is treated as a collection
      of fields for a form ``POST``. The ``REQUEST_METHOD`` will default to
      ``POST``, and the default ``CONTENT_LENGTH``, ``CONTENT_TYPE``, and
      ``wsgi.input`` values will be appropriately set (but can still be
      overridden by explicit keyword arguments or the `environ` argument).
  
      Any `form` values that are not instances of ``basestring`` are assumed to
      be *sequences* of values, and will result in multiple name/value pairs
      being added to the encoded data sent to the application.
  
      Any WSGI-required variables that are not specified by `environ`, `form`, or
      keyword arguments, are initialized to default values using the
      ``wsgiref.util.setup_testing_defaults()`` function.
      """
      import sys
      from wsgiref.util import setup_testing_defaults
      from wsgiref.handlers import BaseCGIHandler
  
      try:
          from StringIO import StringIO
      except ImportError:
          from io import BytesIO as StringIO
  
      try:
          from urllib import quote_plus
      except ImportError:
          from urllib.parse import quote_plus
  
  
      environ = environ.copy()
      for k, v in kw.items():
          if k.startswith('wsgi_'):
              environ[k.replace('_','.',1)] = v
          else:
              environ[k] = v
      if form:
          encoded = []
          for k, v in form.items():
              if isinstance(v,basestring):
                  v = [v]
              for v in v:
                  encoded.append('%s=%s' % (quote_plus(k), quote_plus(v)))
          encoded = '&'.join(encoded)
          environ.setdefault('wsgi.input', StringIO(encoded))
          environ.setdefault('CONTENT_LENGTH', str(len(encoded)))
          environ.setdefault('CONTENT_TYPE', 'application/x-www-form-urlencoded')
          environ.setdefault('REQUEST_METHOD', 'POST')
  
      setup_testing_defaults(environ)
      stdout = StringIO()
      stderr = environ['wsgi.errors']
      def wrapper(env, start):
          try:
              return app(env, start)
          except:
              if _debug:
                  stdout = sys.stdout
                  try:
                      if stdout is not sys.__stdout__:
                          sys.stdout = sys.__stdout__
                      #import pdb
                      #pdb.post_mortem(sys.exc_info()[2])
                  finally:
                      sys.stdout = stdout
              raise
      def print_output(io):
          b = io.getvalue()
          if type(b) is not str: b = b.decode('latin-1')
          print (b.replace('\r\n', '\n'))
  
      BaseCGIHandler(
          environ['wsgi.input'], stdout, stderr, environ,
          environ['wsgi.multithread'], environ['wsgi.multiprocess']
      ).run(wrapper)
      print_output(stdout)
      if stderr.getvalue():
          print ("--- Log Output ---")
          print_output(stderr)
  
  
  def additional_tests():
      import sys
      tests = ['tests.txt']
      if sys.version>='2.4':
          tests.append('README.rst')
  
      try:
          from greenlet import greenlet
      except ImportError:
          pass
      else:
          tests.append('greenlet-tests.txt')
  
      try:
          from peak.util.proxies import AbstractWrapper
      except ImportError:
          pass
      else:
          tests.append('proxy-tests.txt')
  
      import doctest
      return doctest.DocFileSuite(
          optionflags = doctest.ELLIPSIS
                      | doctest.NORMALIZE_WHITESPACE
                      , #| doctest.REPORT_ONLY_FIRST_FAILURE,
          *tests
      )
  
  
  
  
  